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// FIXME: Someone needs to smear multipattern goodness all over this file. 140b57cec5SDimitry Andric 150b57cec5SDimitry Andriclet Defs = [EFLAGS] in { 160b57cec5SDimitry Andric 17*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 180b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCL] in { 190b57cec5SDimitry Andricdef SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1), 200b57cec5SDimitry Andric "shl{b}\t{%cl, $dst|$dst, cl}", 210b57cec5SDimitry Andric [(set GR8:$dst, (shl GR8:$src1, CL))]>; 220b57cec5SDimitry Andricdef SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src1), 230b57cec5SDimitry Andric "shl{w}\t{%cl, $dst|$dst, cl}", 240b57cec5SDimitry Andric [(set GR16:$dst, (shl GR16:$src1, CL))]>, OpSize16; 250b57cec5SDimitry Andricdef SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src1), 260b57cec5SDimitry Andric "shl{l}\t{%cl, $dst|$dst, cl}", 270b57cec5SDimitry Andric [(set GR32:$dst, (shl GR32:$src1, CL))]>, OpSize32; 280b57cec5SDimitry Andricdef SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src1), 290b57cec5SDimitry Andric "shl{q}\t{%cl, $dst|$dst, cl}", 300b57cec5SDimitry Andric [(set GR64:$dst, (shl GR64:$src1, CL))]>; 310b57cec5SDimitry Andric} // Uses = [CL], SchedRW 320b57cec5SDimitry Andric 33*bdd1243dSDimitry Andriclet SchedRW = [WriteShift] in { 340b57cec5SDimitry Andriclet isConvertibleToThreeAddress = 1 in { // Can transform into LEA. 350b57cec5SDimitry Andricdef SHL8ri : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), 360b57cec5SDimitry Andric "shl{b}\t{$src2, $dst|$dst, $src2}", 370b57cec5SDimitry Andric [(set GR8:$dst, (shl GR8:$src1, (i8 imm:$src2)))]>; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andricdef SHL16ri : Ii8<0xC1, MRM4r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2), 400b57cec5SDimitry Andric "shl{w}\t{$src2, $dst|$dst, $src2}", 410b57cec5SDimitry Andric [(set GR16:$dst, (shl GR16:$src1, (i8 imm:$src2)))]>, 420b57cec5SDimitry Andric OpSize16; 430b57cec5SDimitry Andricdef SHL32ri : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2), 440b57cec5SDimitry Andric "shl{l}\t{$src2, $dst|$dst, $src2}", 450b57cec5SDimitry Andric [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))]>, 460b57cec5SDimitry Andric OpSize32; 470b57cec5SDimitry Andricdef SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), 480b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$src2), 490b57cec5SDimitry Andric "shl{q}\t{$src2, $dst|$dst, $src2}", 500b57cec5SDimitry Andric [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>; 510b57cec5SDimitry Andric} // isConvertibleToThreeAddress = 1 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric// NOTE: We don't include patterns for shifts of a register by one, because 540b57cec5SDimitry Andric// 'add reg,reg' is cheaper (and we have a Pat pattern for shift-by-one). 550b57cec5SDimitry Andriclet hasSideEffects = 0 in { 560b57cec5SDimitry Andricdef SHL8r1 : I<0xD0, MRM4r, (outs GR8:$dst), (ins GR8:$src1), 570b57cec5SDimitry Andric "shl{b}\t$dst", []>; 580b57cec5SDimitry Andricdef SHL16r1 : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1), 590b57cec5SDimitry Andric "shl{w}\t$dst", []>, OpSize16; 600b57cec5SDimitry Andricdef SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1), 610b57cec5SDimitry Andric "shl{l}\t$dst", []>, OpSize32; 620b57cec5SDimitry Andricdef SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1), 630b57cec5SDimitry Andric "shl{q}\t$dst", []>; 640b57cec5SDimitry Andric} // hasSideEffects = 0 65*bdd1243dSDimitry Andric} // SchedRW 66*bdd1243dSDimitry Andric} // Constraints = "$src = $dst" 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric// FIXME: Why do we need an explicit "Uses = [CL]" when the instr has a pattern 690b57cec5SDimitry Andric// using CL? 700b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in { 710b57cec5SDimitry Andricdef SHL8mCL : I<0xD2, MRM4m, (outs), (ins i8mem :$dst), 720b57cec5SDimitry Andric "shl{b}\t{%cl, $dst|$dst, cl}", 730b57cec5SDimitry Andric [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>; 740b57cec5SDimitry Andricdef SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst), 750b57cec5SDimitry Andric "shl{w}\t{%cl, $dst|$dst, cl}", 760b57cec5SDimitry Andric [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>, 770b57cec5SDimitry Andric OpSize16; 780b57cec5SDimitry Andricdef SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst), 790b57cec5SDimitry Andric "shl{l}\t{%cl, $dst|$dst, cl}", 800b57cec5SDimitry Andric [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>, 810b57cec5SDimitry Andric OpSize32; 820b57cec5SDimitry Andricdef SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst), 830b57cec5SDimitry Andric "shl{q}\t{%cl, $dst|$dst, cl}", 840b57cec5SDimitry Andric [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>, 850b57cec5SDimitry Andric Requires<[In64BitMode]>; 86*bdd1243dSDimitry Andric} // Uses, SchedRW 870b57cec5SDimitry Andric 880b57cec5SDimitry Andriclet SchedRW = [WriteShiftLd, WriteRMW] in { 890b57cec5SDimitry Andricdef SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, u8imm:$src), 900b57cec5SDimitry Andric "shl{b}\t{$src, $dst|$dst, $src}", 910b57cec5SDimitry Andric [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>; 920b57cec5SDimitry Andricdef SHL16mi : Ii8<0xC1, MRM4m, (outs), (ins i16mem:$dst, u8imm:$src), 930b57cec5SDimitry Andric "shl{w}\t{$src, $dst|$dst, $src}", 940b57cec5SDimitry Andric [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 950b57cec5SDimitry Andric OpSize16; 960b57cec5SDimitry Andricdef SHL32mi : Ii8<0xC1, MRM4m, (outs), (ins i32mem:$dst, u8imm:$src), 970b57cec5SDimitry Andric "shl{l}\t{$src, $dst|$dst, $src}", 980b57cec5SDimitry Andric [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 990b57cec5SDimitry Andric OpSize32; 1000b57cec5SDimitry Andricdef SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, u8imm:$src), 1010b57cec5SDimitry Andric "shl{q}\t{$src, $dst|$dst, $src}", 1020b57cec5SDimitry Andric [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 1030b57cec5SDimitry Andric Requires<[In64BitMode]>; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric// Shift by 1 1060b57cec5SDimitry Andricdef SHL8m1 : I<0xD0, MRM4m, (outs), (ins i8mem :$dst), 1070b57cec5SDimitry Andric "shl{b}\t$dst", 1080b57cec5SDimitry Andric [(store (shl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>; 1090b57cec5SDimitry Andricdef SHL16m1 : I<0xD1, MRM4m, (outs), (ins i16mem:$dst), 1100b57cec5SDimitry Andric "shl{w}\t$dst", 1110b57cec5SDimitry Andric [(store (shl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>, 1120b57cec5SDimitry Andric OpSize16; 1130b57cec5SDimitry Andricdef SHL32m1 : I<0xD1, MRM4m, (outs), (ins i32mem:$dst), 1140b57cec5SDimitry Andric "shl{l}\t$dst", 1150b57cec5SDimitry Andric [(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>, 1160b57cec5SDimitry Andric OpSize32; 1170b57cec5SDimitry Andricdef SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst), 1180b57cec5SDimitry Andric "shl{q}\t$dst", 1190b57cec5SDimitry Andric [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>, 1200b57cec5SDimitry Andric Requires<[In64BitMode]>; 1210b57cec5SDimitry Andric} // SchedRW 1220b57cec5SDimitry Andric 123*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 1240b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCL] in { 1250b57cec5SDimitry Andricdef SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src1), 1260b57cec5SDimitry Andric "shr{b}\t{%cl, $dst|$dst, cl}", 1270b57cec5SDimitry Andric [(set GR8:$dst, (srl GR8:$src1, CL))]>; 1280b57cec5SDimitry Andricdef SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src1), 1290b57cec5SDimitry Andric "shr{w}\t{%cl, $dst|$dst, cl}", 1300b57cec5SDimitry Andric [(set GR16:$dst, (srl GR16:$src1, CL))]>, OpSize16; 1310b57cec5SDimitry Andricdef SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src1), 1320b57cec5SDimitry Andric "shr{l}\t{%cl, $dst|$dst, cl}", 1330b57cec5SDimitry Andric [(set GR32:$dst, (srl GR32:$src1, CL))]>, OpSize32; 1340b57cec5SDimitry Andricdef SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src1), 1350b57cec5SDimitry Andric "shr{q}\t{%cl, $dst|$dst, cl}", 1360b57cec5SDimitry Andric [(set GR64:$dst, (srl GR64:$src1, CL))]>; 137*bdd1243dSDimitry Andric} // Uses, SchedRW 1380b57cec5SDimitry Andric 139*bdd1243dSDimitry Andriclet SchedRW = [WriteShift] in { 1400b57cec5SDimitry Andricdef SHR8ri : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$src2), 1410b57cec5SDimitry Andric "shr{b}\t{$src2, $dst|$dst, $src2}", 1420b57cec5SDimitry Andric [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))]>; 1430b57cec5SDimitry Andricdef SHR16ri : Ii8<0xC1, MRM5r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2), 1440b57cec5SDimitry Andric "shr{w}\t{$src2, $dst|$dst, $src2}", 1450b57cec5SDimitry Andric [(set GR16:$dst, (srl GR16:$src1, (i8 imm:$src2)))]>, 1460b57cec5SDimitry Andric OpSize16; 1470b57cec5SDimitry Andricdef SHR32ri : Ii8<0xC1, MRM5r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2), 1480b57cec5SDimitry Andric "shr{l}\t{$src2, $dst|$dst, $src2}", 1490b57cec5SDimitry Andric [(set GR32:$dst, (srl GR32:$src1, (i8 imm:$src2)))]>, 1500b57cec5SDimitry Andric OpSize32; 1510b57cec5SDimitry Andricdef SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$src2), 1520b57cec5SDimitry Andric "shr{q}\t{$src2, $dst|$dst, $src2}", 1530b57cec5SDimitry Andric [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric// Shift right by 1 1560b57cec5SDimitry Andricdef SHR8r1 : I<0xD0, MRM5r, (outs GR8:$dst), (ins GR8:$src1), 1570b57cec5SDimitry Andric "shr{b}\t$dst", 1580b57cec5SDimitry Andric [(set GR8:$dst, (srl GR8:$src1, (i8 1)))]>; 1590b57cec5SDimitry Andricdef SHR16r1 : I<0xD1, MRM5r, (outs GR16:$dst), (ins GR16:$src1), 1600b57cec5SDimitry Andric "shr{w}\t$dst", 1610b57cec5SDimitry Andric [(set GR16:$dst, (srl GR16:$src1, (i8 1)))]>, OpSize16; 1620b57cec5SDimitry Andricdef SHR32r1 : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1), 1630b57cec5SDimitry Andric "shr{l}\t$dst", 1640b57cec5SDimitry Andric [(set GR32:$dst, (srl GR32:$src1, (i8 1)))]>, OpSize32; 1650b57cec5SDimitry Andricdef SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1), 1660b57cec5SDimitry Andric "shr{q}\t$dst", 1670b57cec5SDimitry Andric [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>; 168*bdd1243dSDimitry Andric} // SchedRW 169*bdd1243dSDimitry Andric} // Constraints = "$src = $dst" 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in { 1730b57cec5SDimitry Andricdef SHR8mCL : I<0xD2, MRM5m, (outs), (ins i8mem :$dst), 1740b57cec5SDimitry Andric "shr{b}\t{%cl, $dst|$dst, cl}", 1750b57cec5SDimitry Andric [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>; 1760b57cec5SDimitry Andricdef SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst), 1770b57cec5SDimitry Andric "shr{w}\t{%cl, $dst|$dst, cl}", 1780b57cec5SDimitry Andric [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>, 1790b57cec5SDimitry Andric OpSize16; 1800b57cec5SDimitry Andricdef SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst), 1810b57cec5SDimitry Andric "shr{l}\t{%cl, $dst|$dst, cl}", 1820b57cec5SDimitry Andric [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>, 1830b57cec5SDimitry Andric OpSize32; 1840b57cec5SDimitry Andricdef SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst), 1850b57cec5SDimitry Andric "shr{q}\t{%cl, $dst|$dst, cl}", 1860b57cec5SDimitry Andric [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>, 1870b57cec5SDimitry Andric Requires<[In64BitMode]>; 188*bdd1243dSDimitry Andric} // Uses, SchedRW 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andriclet SchedRW = [WriteShiftLd, WriteRMW] in { 1910b57cec5SDimitry Andricdef SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, u8imm:$src), 1920b57cec5SDimitry Andric "shr{b}\t{$src, $dst|$dst, $src}", 1930b57cec5SDimitry Andric [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>; 1940b57cec5SDimitry Andricdef SHR16mi : Ii8<0xC1, MRM5m, (outs), (ins i16mem:$dst, u8imm:$src), 1950b57cec5SDimitry Andric "shr{w}\t{$src, $dst|$dst, $src}", 1960b57cec5SDimitry Andric [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 1970b57cec5SDimitry Andric OpSize16; 1980b57cec5SDimitry Andricdef SHR32mi : Ii8<0xC1, MRM5m, (outs), (ins i32mem:$dst, u8imm:$src), 1990b57cec5SDimitry Andric "shr{l}\t{$src, $dst|$dst, $src}", 2000b57cec5SDimitry Andric [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 2010b57cec5SDimitry Andric OpSize32; 2020b57cec5SDimitry Andricdef SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, u8imm:$src), 2030b57cec5SDimitry Andric "shr{q}\t{$src, $dst|$dst, $src}", 2040b57cec5SDimitry Andric [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 2050b57cec5SDimitry Andric Requires<[In64BitMode]>; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric// Shift by 1 2080b57cec5SDimitry Andricdef SHR8m1 : I<0xD0, MRM5m, (outs), (ins i8mem :$dst), 2090b57cec5SDimitry Andric "shr{b}\t$dst", 2100b57cec5SDimitry Andric [(store (srl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>; 2110b57cec5SDimitry Andricdef SHR16m1 : I<0xD1, MRM5m, (outs), (ins i16mem:$dst), 2120b57cec5SDimitry Andric "shr{w}\t$dst", 2130b57cec5SDimitry Andric [(store (srl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>, 2140b57cec5SDimitry Andric OpSize16; 2150b57cec5SDimitry Andricdef SHR32m1 : I<0xD1, MRM5m, (outs), (ins i32mem:$dst), 2160b57cec5SDimitry Andric "shr{l}\t$dst", 2170b57cec5SDimitry Andric [(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>, 2180b57cec5SDimitry Andric OpSize32; 2190b57cec5SDimitry Andricdef SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst), 2200b57cec5SDimitry Andric "shr{q}\t$dst", 2210b57cec5SDimitry Andric [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>, 2220b57cec5SDimitry Andric Requires<[In64BitMode]>; 2230b57cec5SDimitry Andric} // SchedRW 2240b57cec5SDimitry Andric 225*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 2260b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCL] in { 2270b57cec5SDimitry Andricdef SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1), 2280b57cec5SDimitry Andric "sar{b}\t{%cl, $dst|$dst, cl}", 2290b57cec5SDimitry Andric [(set GR8:$dst, (sra GR8:$src1, CL))]>; 2300b57cec5SDimitry Andricdef SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src1), 2310b57cec5SDimitry Andric "sar{w}\t{%cl, $dst|$dst, cl}", 2320b57cec5SDimitry Andric [(set GR16:$dst, (sra GR16:$src1, CL))]>, 2330b57cec5SDimitry Andric OpSize16; 2340b57cec5SDimitry Andricdef SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src1), 2350b57cec5SDimitry Andric "sar{l}\t{%cl, $dst|$dst, cl}", 2360b57cec5SDimitry Andric [(set GR32:$dst, (sra GR32:$src1, CL))]>, 2370b57cec5SDimitry Andric OpSize32; 2380b57cec5SDimitry Andricdef SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src1), 2390b57cec5SDimitry Andric "sar{q}\t{%cl, $dst|$dst, cl}", 2400b57cec5SDimitry Andric [(set GR64:$dst, (sra GR64:$src1, CL))]>; 241*bdd1243dSDimitry Andric} // Uses, SchedRW 2420b57cec5SDimitry Andric 243*bdd1243dSDimitry Andriclet SchedRW = [WriteShift] in { 2440b57cec5SDimitry Andricdef SAR8ri : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), 2450b57cec5SDimitry Andric "sar{b}\t{$src2, $dst|$dst, $src2}", 2460b57cec5SDimitry Andric [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))]>; 2470b57cec5SDimitry Andricdef SAR16ri : Ii8<0xC1, MRM7r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2), 2480b57cec5SDimitry Andric "sar{w}\t{$src2, $dst|$dst, $src2}", 2490b57cec5SDimitry Andric [(set GR16:$dst, (sra GR16:$src1, (i8 imm:$src2)))]>, 2500b57cec5SDimitry Andric OpSize16; 2510b57cec5SDimitry Andricdef SAR32ri : Ii8<0xC1, MRM7r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2), 2520b57cec5SDimitry Andric "sar{l}\t{$src2, $dst|$dst, $src2}", 2530b57cec5SDimitry Andric [(set GR32:$dst, (sra GR32:$src1, (i8 imm:$src2)))]>, 2540b57cec5SDimitry Andric OpSize32; 2550b57cec5SDimitry Andricdef SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), 2560b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$src2), 2570b57cec5SDimitry Andric "sar{q}\t{$src2, $dst|$dst, $src2}", 2580b57cec5SDimitry Andric [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric// Shift by 1 2610b57cec5SDimitry Andricdef SAR8r1 : I<0xD0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1), 2620b57cec5SDimitry Andric "sar{b}\t$dst", 2630b57cec5SDimitry Andric [(set GR8:$dst, (sra GR8:$src1, (i8 1)))]>; 2640b57cec5SDimitry Andricdef SAR16r1 : I<0xD1, MRM7r, (outs GR16:$dst), (ins GR16:$src1), 2650b57cec5SDimitry Andric "sar{w}\t$dst", 2660b57cec5SDimitry Andric [(set GR16:$dst, (sra GR16:$src1, (i8 1)))]>, OpSize16; 2670b57cec5SDimitry Andricdef SAR32r1 : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1), 2680b57cec5SDimitry Andric "sar{l}\t$dst", 2690b57cec5SDimitry Andric [(set GR32:$dst, (sra GR32:$src1, (i8 1)))]>, OpSize32; 2700b57cec5SDimitry Andricdef SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1), 2710b57cec5SDimitry Andric "sar{q}\t$dst", 2720b57cec5SDimitry Andric [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>; 273*bdd1243dSDimitry Andric} // SchedRW 274*bdd1243dSDimitry Andric} // Constraints = "$src = $dst" 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in { 2780b57cec5SDimitry Andricdef SAR8mCL : I<0xD2, MRM7m, (outs), (ins i8mem :$dst), 2790b57cec5SDimitry Andric "sar{b}\t{%cl, $dst|$dst, cl}", 2800b57cec5SDimitry Andric [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>; 2810b57cec5SDimitry Andricdef SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst), 2820b57cec5SDimitry Andric "sar{w}\t{%cl, $dst|$dst, cl}", 2830b57cec5SDimitry Andric [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>, 2840b57cec5SDimitry Andric OpSize16; 2850b57cec5SDimitry Andricdef SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst), 2860b57cec5SDimitry Andric "sar{l}\t{%cl, $dst|$dst, cl}", 2870b57cec5SDimitry Andric [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>, 2880b57cec5SDimitry Andric OpSize32; 2890b57cec5SDimitry Andricdef SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst), 2900b57cec5SDimitry Andric "sar{q}\t{%cl, $dst|$dst, cl}", 2910b57cec5SDimitry Andric [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>, 2920b57cec5SDimitry Andric Requires<[In64BitMode]>; 293*bdd1243dSDimitry Andric} // Uses, SchedRW 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andriclet SchedRW = [WriteShiftLd, WriteRMW] in { 2960b57cec5SDimitry Andricdef SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, u8imm:$src), 2970b57cec5SDimitry Andric "sar{b}\t{$src, $dst|$dst, $src}", 2980b57cec5SDimitry Andric [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>; 2990b57cec5SDimitry Andricdef SAR16mi : Ii8<0xC1, MRM7m, (outs), (ins i16mem:$dst, u8imm:$src), 3000b57cec5SDimitry Andric "sar{w}\t{$src, $dst|$dst, $src}", 3010b57cec5SDimitry Andric [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 3020b57cec5SDimitry Andric OpSize16; 3030b57cec5SDimitry Andricdef SAR32mi : Ii8<0xC1, MRM7m, (outs), (ins i32mem:$dst, u8imm:$src), 3040b57cec5SDimitry Andric "sar{l}\t{$src, $dst|$dst, $src}", 3050b57cec5SDimitry Andric [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 3060b57cec5SDimitry Andric OpSize32; 3070b57cec5SDimitry Andricdef SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, u8imm:$src), 3080b57cec5SDimitry Andric "sar{q}\t{$src, $dst|$dst, $src}", 3090b57cec5SDimitry Andric [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 3100b57cec5SDimitry Andric Requires<[In64BitMode]>; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric// Shift by 1 3130b57cec5SDimitry Andricdef SAR8m1 : I<0xD0, MRM7m, (outs), (ins i8mem :$dst), 3140b57cec5SDimitry Andric "sar{b}\t$dst", 3150b57cec5SDimitry Andric [(store (sra (loadi8 addr:$dst), (i8 1)), addr:$dst)]>; 3160b57cec5SDimitry Andricdef SAR16m1 : I<0xD1, MRM7m, (outs), (ins i16mem:$dst), 3170b57cec5SDimitry Andric "sar{w}\t$dst", 3180b57cec5SDimitry Andric [(store (sra (loadi16 addr:$dst), (i8 1)), addr:$dst)]>, 3190b57cec5SDimitry Andric OpSize16; 3200b57cec5SDimitry Andricdef SAR32m1 : I<0xD1, MRM7m, (outs), (ins i32mem:$dst), 3210b57cec5SDimitry Andric "sar{l}\t$dst", 3220b57cec5SDimitry Andric [(store (sra (loadi32 addr:$dst), (i8 1)), addr:$dst)]>, 3230b57cec5SDimitry Andric OpSize32; 3240b57cec5SDimitry Andricdef SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst), 3250b57cec5SDimitry Andric "sar{q}\t$dst", 3260b57cec5SDimitry Andric [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>, 3270b57cec5SDimitry Andric Requires<[In64BitMode]>; 3280b57cec5SDimitry Andric} // SchedRW 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3310b57cec5SDimitry Andric// Rotate instructions 3320b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andriclet hasSideEffects = 0 in { 335*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andriclet Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in { 3380b57cec5SDimitry Andricdef RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src1), 3390b57cec5SDimitry Andric "rcl{b}\t{%cl, $dst|$dst, cl}", []>; 3400b57cec5SDimitry Andricdef RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src1), 3410b57cec5SDimitry Andric "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16; 3420b57cec5SDimitry Andricdef RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src1), 3430b57cec5SDimitry Andric "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; 3440b57cec5SDimitry Andricdef RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src1), 3450b57cec5SDimitry Andric "rcl{q}\t{%cl, $dst|$dst, cl}", []>; 346*bdd1243dSDimitry Andric} // Uses = [CL, EFLAGS], SchedRW 3470b57cec5SDimitry Andric 348*bdd1243dSDimitry Andriclet Uses = [EFLAGS], SchedRW = [WriteRotate] in { 3490b57cec5SDimitry Andricdef RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src1), 3500b57cec5SDimitry Andric "rcl{b}\t$dst", []>; 3510b57cec5SDimitry Andricdef RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt), 3520b57cec5SDimitry Andric "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>; 3530b57cec5SDimitry Andricdef RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src1), 3540b57cec5SDimitry Andric "rcl{w}\t$dst", []>, OpSize16; 3550b57cec5SDimitry Andricdef RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt), 3560b57cec5SDimitry Andric "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16; 3570b57cec5SDimitry Andricdef RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src1), 3580b57cec5SDimitry Andric "rcl{l}\t$dst", []>, OpSize32; 3590b57cec5SDimitry Andricdef RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt), 3600b57cec5SDimitry Andric "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32; 3610b57cec5SDimitry Andricdef RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src1), 3620b57cec5SDimitry Andric "rcl{q}\t$dst", []>; 3630b57cec5SDimitry Andricdef RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt), 3640b57cec5SDimitry Andric "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>; 365*bdd1243dSDimitry Andric} // Uses = [EFLAGS], SchedRW 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andriclet Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in { 3680b57cec5SDimitry Andricdef RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src1), 3690b57cec5SDimitry Andric "rcr{b}\t{%cl, $dst|$dst, cl}", []>; 3700b57cec5SDimitry Andricdef RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src1), 3710b57cec5SDimitry Andric "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16; 3720b57cec5SDimitry Andricdef RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src1), 3730b57cec5SDimitry Andric "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; 3740b57cec5SDimitry Andricdef RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src1), 3750b57cec5SDimitry Andric "rcr{q}\t{%cl, $dst|$dst, cl}", []>; 376*bdd1243dSDimitry Andric} // Uses = [CL, EFLAGS], SchedRW 3770b57cec5SDimitry Andric 378*bdd1243dSDimitry Andriclet Uses = [EFLAGS], SchedRW = [WriteRotate] in { 3790b57cec5SDimitry Andricdef RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src1), 3800b57cec5SDimitry Andric "rcr{b}\t$dst", []>; 3810b57cec5SDimitry Andricdef RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt), 3820b57cec5SDimitry Andric "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>; 3830b57cec5SDimitry Andricdef RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src1), 3840b57cec5SDimitry Andric "rcr{w}\t$dst", []>, OpSize16; 3850b57cec5SDimitry Andricdef RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt), 3860b57cec5SDimitry Andric "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16; 3870b57cec5SDimitry Andricdef RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src1), 3880b57cec5SDimitry Andric "rcr{l}\t$dst", []>, OpSize32; 3890b57cec5SDimitry Andricdef RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt), 3900b57cec5SDimitry Andric "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32; 3910b57cec5SDimitry Andricdef RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src1), 3920b57cec5SDimitry Andric "rcr{q}\t$dst", []>; 3930b57cec5SDimitry Andricdef RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt), 3940b57cec5SDimitry Andric "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>; 395*bdd1243dSDimitry Andric} // Uses = [EFLAGS], SchedRW 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric} // Constraints = "$src = $dst" 3980b57cec5SDimitry Andric 399*bdd1243dSDimitry Andriclet mayStore = 1 in { 400*bdd1243dSDimitry Andriclet Uses = [EFLAGS], SchedRW = [WriteRotateLd, WriteRMW] in { 4010b57cec5SDimitry Andricdef RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst), 4020b57cec5SDimitry Andric "rcl{b}\t$dst", []>; 4030b57cec5SDimitry Andricdef RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, u8imm:$cnt), 4040b57cec5SDimitry Andric "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>; 4050b57cec5SDimitry Andricdef RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst), 4060b57cec5SDimitry Andric "rcl{w}\t$dst", []>, OpSize16; 4070b57cec5SDimitry Andricdef RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, u8imm:$cnt), 4080b57cec5SDimitry Andric "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16; 4090b57cec5SDimitry Andricdef RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst), 4100b57cec5SDimitry Andric "rcl{l}\t$dst", []>, OpSize32; 4110b57cec5SDimitry Andricdef RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, u8imm:$cnt), 4120b57cec5SDimitry Andric "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32; 4130b57cec5SDimitry Andricdef RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst), 4140b57cec5SDimitry Andric "rcl{q}\t$dst", []>, Requires<[In64BitMode]>; 4150b57cec5SDimitry Andricdef RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, u8imm:$cnt), 4160b57cec5SDimitry Andric "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>, 4170b57cec5SDimitry Andric Requires<[In64BitMode]>; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andricdef RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst), 4200b57cec5SDimitry Andric "rcr{b}\t$dst", []>; 4210b57cec5SDimitry Andricdef RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, u8imm:$cnt), 4220b57cec5SDimitry Andric "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>; 4230b57cec5SDimitry Andricdef RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst), 4240b57cec5SDimitry Andric "rcr{w}\t$dst", []>, OpSize16; 4250b57cec5SDimitry Andricdef RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, u8imm:$cnt), 4260b57cec5SDimitry Andric "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16; 4270b57cec5SDimitry Andricdef RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst), 4280b57cec5SDimitry Andric "rcr{l}\t$dst", []>, OpSize32; 4290b57cec5SDimitry Andricdef RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, u8imm:$cnt), 4300b57cec5SDimitry Andric "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32; 4310b57cec5SDimitry Andricdef RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst), 4320b57cec5SDimitry Andric "rcr{q}\t$dst", []>, Requires<[In64BitMode]>; 4330b57cec5SDimitry Andricdef RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, u8imm:$cnt), 4340b57cec5SDimitry Andric "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>, 4350b57cec5SDimitry Andric Requires<[In64BitMode]>; 436*bdd1243dSDimitry Andric} // Uses = [EFLAGS], SchedRW 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andriclet Uses = [CL, EFLAGS], SchedRW = [WriteRotateCLLd, WriteRMW] in { 4390b57cec5SDimitry Andricdef RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst), 4400b57cec5SDimitry Andric "rcl{b}\t{%cl, $dst|$dst, cl}", []>; 4410b57cec5SDimitry Andricdef RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst), 4420b57cec5SDimitry Andric "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16; 4430b57cec5SDimitry Andricdef RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst), 4440b57cec5SDimitry Andric "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; 4450b57cec5SDimitry Andricdef RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst), 4460b57cec5SDimitry Andric "rcl{q}\t{%cl, $dst|$dst, cl}", []>, 4470b57cec5SDimitry Andric Requires<[In64BitMode]>; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andricdef RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst), 4500b57cec5SDimitry Andric "rcr{b}\t{%cl, $dst|$dst, cl}", []>; 4510b57cec5SDimitry Andricdef RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst), 4520b57cec5SDimitry Andric "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16; 4530b57cec5SDimitry Andricdef RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst), 4540b57cec5SDimitry Andric "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32; 4550b57cec5SDimitry Andricdef RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst), 4560b57cec5SDimitry Andric "rcr{q}\t{%cl, $dst|$dst, cl}", []>, 4570b57cec5SDimitry Andric Requires<[In64BitMode]>; 458*bdd1243dSDimitry Andric} // Uses = [CL, EFLAGS], SchedRW 459*bdd1243dSDimitry Andric} // mayStore 4600b57cec5SDimitry Andric} // hasSideEffects = 0 4610b57cec5SDimitry Andric 462*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 4630b57cec5SDimitry Andric// FIXME: provide shorter instructions when imm8 == 1 4640b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteRotateCL] in { 4650b57cec5SDimitry Andricdef ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1), 4660b57cec5SDimitry Andric "rol{b}\t{%cl, $dst|$dst, cl}", 4670b57cec5SDimitry Andric [(set GR8:$dst, (rotl GR8:$src1, CL))]>; 4680b57cec5SDimitry Andricdef ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src1), 4690b57cec5SDimitry Andric "rol{w}\t{%cl, $dst|$dst, cl}", 4700b57cec5SDimitry Andric [(set GR16:$dst, (rotl GR16:$src1, CL))]>, OpSize16; 4710b57cec5SDimitry Andricdef ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src1), 4720b57cec5SDimitry Andric "rol{l}\t{%cl, $dst|$dst, cl}", 4730b57cec5SDimitry Andric [(set GR32:$dst, (rotl GR32:$src1, CL))]>, OpSize32; 4740b57cec5SDimitry Andricdef ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src1), 4750b57cec5SDimitry Andric "rol{q}\t{%cl, $dst|$dst, cl}", 4760b57cec5SDimitry Andric [(set GR64:$dst, (rotl GR64:$src1, CL))]>; 477*bdd1243dSDimitry Andric} // Uses, SchedRW 4780b57cec5SDimitry Andric 479*bdd1243dSDimitry Andriclet SchedRW = [WriteRotate] in { 4800b57cec5SDimitry Andricdef ROL8ri : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), 4810b57cec5SDimitry Andric "rol{b}\t{$src2, $dst|$dst, $src2}", 4825ffd83dbSDimitry Andric [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))]>; 4830b57cec5SDimitry Andricdef ROL16ri : Ii8<0xC1, MRM0r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2), 4840b57cec5SDimitry Andric "rol{w}\t{$src2, $dst|$dst, $src2}", 4855ffd83dbSDimitry Andric [(set GR16:$dst, (rotl GR16:$src1, (i8 imm:$src2)))]>, 4860b57cec5SDimitry Andric OpSize16; 4870b57cec5SDimitry Andricdef ROL32ri : Ii8<0xC1, MRM0r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2), 4880b57cec5SDimitry Andric "rol{l}\t{$src2, $dst|$dst, $src2}", 4895ffd83dbSDimitry Andric [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$src2)))]>, 4900b57cec5SDimitry Andric OpSize32; 4910b57cec5SDimitry Andricdef ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), 4920b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$src2), 4930b57cec5SDimitry Andric "rol{q}\t{$src2, $dst|$dst, $src2}", 4945ffd83dbSDimitry Andric [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric// Rotate by 1 4970b57cec5SDimitry Andricdef ROL8r1 : I<0xD0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1), 4980b57cec5SDimitry Andric "rol{b}\t$dst", 4990b57cec5SDimitry Andric [(set GR8:$dst, (rotl GR8:$src1, (i8 1)))]>; 5000b57cec5SDimitry Andricdef ROL16r1 : I<0xD1, MRM0r, (outs GR16:$dst), (ins GR16:$src1), 5010b57cec5SDimitry Andric "rol{w}\t$dst", 5020b57cec5SDimitry Andric [(set GR16:$dst, (rotl GR16:$src1, (i8 1)))]>, OpSize16; 5030b57cec5SDimitry Andricdef ROL32r1 : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1), 5040b57cec5SDimitry Andric "rol{l}\t$dst", 5050b57cec5SDimitry Andric [(set GR32:$dst, (rotl GR32:$src1, (i8 1)))]>, OpSize32; 5060b57cec5SDimitry Andricdef ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1), 5070b57cec5SDimitry Andric "rol{q}\t$dst", 5080b57cec5SDimitry Andric [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>; 509*bdd1243dSDimitry Andric} // SchedRW 510*bdd1243dSDimitry Andric} // Constraints = "$src = $dst" 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in { 5130b57cec5SDimitry Andricdef ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst), 5140b57cec5SDimitry Andric "rol{b}\t{%cl, $dst|$dst, cl}", 5150b57cec5SDimitry Andric [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>; 5160b57cec5SDimitry Andricdef ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst), 5170b57cec5SDimitry Andric "rol{w}\t{%cl, $dst|$dst, cl}", 5180b57cec5SDimitry Andric [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16; 5190b57cec5SDimitry Andricdef ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst), 5200b57cec5SDimitry Andric "rol{l}\t{%cl, $dst|$dst, cl}", 5210b57cec5SDimitry Andric [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32; 5220b57cec5SDimitry Andricdef ROL64mCL : RI<0xD3, MRM0m, (outs), (ins i64mem:$dst), 5230b57cec5SDimitry Andric "rol{q}\t{%cl, $dst|$dst, cl}", 5240b57cec5SDimitry Andric [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>, 5250b57cec5SDimitry Andric Requires<[In64BitMode]>; 526*bdd1243dSDimitry Andric} // Uses, SchedRW 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andriclet SchedRW = [WriteRotateLd, WriteRMW] in { 5290b57cec5SDimitry Andricdef ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, u8imm:$src1), 5300b57cec5SDimitry Andric "rol{b}\t{$src1, $dst|$dst, $src1}", 5310b57cec5SDimitry Andric [(store (rotl (loadi8 addr:$dst), (i8 imm:$src1)), addr:$dst)]>; 5320b57cec5SDimitry Andricdef ROL16mi : Ii8<0xC1, MRM0m, (outs), (ins i16mem:$dst, u8imm:$src1), 5330b57cec5SDimitry Andric "rol{w}\t{$src1, $dst|$dst, $src1}", 5340b57cec5SDimitry Andric [(store (rotl (loadi16 addr:$dst), (i8 imm:$src1)), addr:$dst)]>, 5350b57cec5SDimitry Andric OpSize16; 5360b57cec5SDimitry Andricdef ROL32mi : Ii8<0xC1, MRM0m, (outs), (ins i32mem:$dst, u8imm:$src1), 5370b57cec5SDimitry Andric "rol{l}\t{$src1, $dst|$dst, $src1}", 5380b57cec5SDimitry Andric [(store (rotl (loadi32 addr:$dst), (i8 imm:$src1)), addr:$dst)]>, 5390b57cec5SDimitry Andric OpSize32; 5400b57cec5SDimitry Andricdef ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, u8imm:$src1), 5410b57cec5SDimitry Andric "rol{q}\t{$src1, $dst|$dst, $src1}", 5420b57cec5SDimitry Andric [(store (rotl (loadi64 addr:$dst), (i8 imm:$src1)), addr:$dst)]>, 5430b57cec5SDimitry Andric Requires<[In64BitMode]>; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric// Rotate by 1 5460b57cec5SDimitry Andricdef ROL8m1 : I<0xD0, MRM0m, (outs), (ins i8mem :$dst), 5470b57cec5SDimitry Andric "rol{b}\t$dst", 5480b57cec5SDimitry Andric [(store (rotl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>; 5490b57cec5SDimitry Andricdef ROL16m1 : I<0xD1, MRM0m, (outs), (ins i16mem:$dst), 5500b57cec5SDimitry Andric "rol{w}\t$dst", 5510b57cec5SDimitry Andric [(store (rotl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>, 5520b57cec5SDimitry Andric OpSize16; 5530b57cec5SDimitry Andricdef ROL32m1 : I<0xD1, MRM0m, (outs), (ins i32mem:$dst), 5540b57cec5SDimitry Andric "rol{l}\t$dst", 5550b57cec5SDimitry Andric [(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>, 5560b57cec5SDimitry Andric OpSize32; 5570b57cec5SDimitry Andricdef ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst), 5580b57cec5SDimitry Andric "rol{q}\t$dst", 5590b57cec5SDimitry Andric [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>, 5600b57cec5SDimitry Andric Requires<[In64BitMode]>; 5610b57cec5SDimitry Andric} // SchedRW 5620b57cec5SDimitry Andric 563*bdd1243dSDimitry Andriclet Constraints = "$src1 = $dst" in { 5640b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteRotateCL] in { 5650b57cec5SDimitry Andricdef ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1), 5660b57cec5SDimitry Andric "ror{b}\t{%cl, $dst|$dst, cl}", 5670b57cec5SDimitry Andric [(set GR8:$dst, (rotr GR8:$src1, CL))]>; 5680b57cec5SDimitry Andricdef ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src1), 5690b57cec5SDimitry Andric "ror{w}\t{%cl, $dst|$dst, cl}", 5700b57cec5SDimitry Andric [(set GR16:$dst, (rotr GR16:$src1, CL))]>, OpSize16; 5710b57cec5SDimitry Andricdef ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src1), 5720b57cec5SDimitry Andric "ror{l}\t{%cl, $dst|$dst, cl}", 5730b57cec5SDimitry Andric [(set GR32:$dst, (rotr GR32:$src1, CL))]>, OpSize32; 5740b57cec5SDimitry Andricdef ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src1), 5750b57cec5SDimitry Andric "ror{q}\t{%cl, $dst|$dst, cl}", 5760b57cec5SDimitry Andric [(set GR64:$dst, (rotr GR64:$src1, CL))]>; 5770b57cec5SDimitry Andric} 5780b57cec5SDimitry Andric 579*bdd1243dSDimitry Andriclet SchedRW = [WriteRotate] in { 5800b57cec5SDimitry Andricdef ROR8ri : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2), 5810b57cec5SDimitry Andric "ror{b}\t{$src2, $dst|$dst, $src2}", 5825ffd83dbSDimitry Andric [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))]>; 5830b57cec5SDimitry Andricdef ROR16ri : Ii8<0xC1, MRM1r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2), 5840b57cec5SDimitry Andric "ror{w}\t{$src2, $dst|$dst, $src2}", 5855ffd83dbSDimitry Andric [(set GR16:$dst, (rotr GR16:$src1, (i8 imm:$src2)))]>, 5860b57cec5SDimitry Andric OpSize16; 5870b57cec5SDimitry Andricdef ROR32ri : Ii8<0xC1, MRM1r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2), 5880b57cec5SDimitry Andric "ror{l}\t{$src2, $dst|$dst, $src2}", 5895ffd83dbSDimitry Andric [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$src2)))]>, 5900b57cec5SDimitry Andric OpSize32; 5910b57cec5SDimitry Andricdef ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), 5920b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$src2), 5930b57cec5SDimitry Andric "ror{q}\t{$src2, $dst|$dst, $src2}", 5945ffd83dbSDimitry Andric [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric// Rotate by 1 5970b57cec5SDimitry Andricdef ROR8r1 : I<0xD0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1), 5980b57cec5SDimitry Andric "ror{b}\t$dst", 5990b57cec5SDimitry Andric [(set GR8:$dst, (rotr GR8:$src1, (i8 1)))]>; 6000b57cec5SDimitry Andricdef ROR16r1 : I<0xD1, MRM1r, (outs GR16:$dst), (ins GR16:$src1), 6010b57cec5SDimitry Andric "ror{w}\t$dst", 6020b57cec5SDimitry Andric [(set GR16:$dst, (rotr GR16:$src1, (i8 1)))]>, OpSize16; 6030b57cec5SDimitry Andricdef ROR32r1 : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1), 6040b57cec5SDimitry Andric "ror{l}\t$dst", 6050b57cec5SDimitry Andric [(set GR32:$dst, (rotr GR32:$src1, (i8 1)))]>, OpSize32; 6060b57cec5SDimitry Andricdef ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1), 6070b57cec5SDimitry Andric "ror{q}\t$dst", 6080b57cec5SDimitry Andric [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>; 609*bdd1243dSDimitry Andric} // SchedRW 6100b57cec5SDimitry Andric} // Constraints = "$src = $dst", SchedRW 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in { 6130b57cec5SDimitry Andricdef ROR8mCL : I<0xD2, MRM1m, (outs), (ins i8mem :$dst), 6140b57cec5SDimitry Andric "ror{b}\t{%cl, $dst|$dst, cl}", 6150b57cec5SDimitry Andric [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>; 6160b57cec5SDimitry Andricdef ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst), 6170b57cec5SDimitry Andric "ror{w}\t{%cl, $dst|$dst, cl}", 6180b57cec5SDimitry Andric [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16; 6190b57cec5SDimitry Andricdef ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst), 6200b57cec5SDimitry Andric "ror{l}\t{%cl, $dst|$dst, cl}", 6210b57cec5SDimitry Andric [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32; 6220b57cec5SDimitry Andricdef ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), 6230b57cec5SDimitry Andric "ror{q}\t{%cl, $dst|$dst, cl}", 6240b57cec5SDimitry Andric [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>, 6250b57cec5SDimitry Andric Requires<[In64BitMode]>; 626*bdd1243dSDimitry Andric} // Uses, SchedRW 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andriclet SchedRW = [WriteRotateLd, WriteRMW] in { 6290b57cec5SDimitry Andricdef ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, u8imm:$src), 6300b57cec5SDimitry Andric "ror{b}\t{$src, $dst|$dst, $src}", 6310b57cec5SDimitry Andric [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>; 6320b57cec5SDimitry Andricdef ROR16mi : Ii8<0xC1, MRM1m, (outs), (ins i16mem:$dst, u8imm:$src), 6330b57cec5SDimitry Andric "ror{w}\t{$src, $dst|$dst, $src}", 6340b57cec5SDimitry Andric [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 6350b57cec5SDimitry Andric OpSize16; 6360b57cec5SDimitry Andricdef ROR32mi : Ii8<0xC1, MRM1m, (outs), (ins i32mem:$dst, u8imm:$src), 6370b57cec5SDimitry Andric "ror{l}\t{$src, $dst|$dst, $src}", 6380b57cec5SDimitry Andric [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 6390b57cec5SDimitry Andric OpSize32; 6400b57cec5SDimitry Andricdef ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, u8imm:$src), 6410b57cec5SDimitry Andric "ror{q}\t{$src, $dst|$dst, $src}", 6420b57cec5SDimitry Andric [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>, 6430b57cec5SDimitry Andric Requires<[In64BitMode]>; 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric// Rotate by 1 6460b57cec5SDimitry Andricdef ROR8m1 : I<0xD0, MRM1m, (outs), (ins i8mem :$dst), 6470b57cec5SDimitry Andric "ror{b}\t$dst", 6480b57cec5SDimitry Andric [(store (rotr (loadi8 addr:$dst), (i8 1)), addr:$dst)]>; 6490b57cec5SDimitry Andricdef ROR16m1 : I<0xD1, MRM1m, (outs), (ins i16mem:$dst), 6500b57cec5SDimitry Andric "ror{w}\t$dst", 6510b57cec5SDimitry Andric [(store (rotr (loadi16 addr:$dst), (i8 1)), addr:$dst)]>, 6520b57cec5SDimitry Andric OpSize16; 6530b57cec5SDimitry Andricdef ROR32m1 : I<0xD1, MRM1m, (outs), (ins i32mem:$dst), 6540b57cec5SDimitry Andric "ror{l}\t$dst", 6550b57cec5SDimitry Andric [(store (rotr (loadi32 addr:$dst), (i8 1)), addr:$dst)]>, 6560b57cec5SDimitry Andric OpSize32; 6570b57cec5SDimitry Andricdef ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst), 6580b57cec5SDimitry Andric "ror{q}\t$dst", 6590b57cec5SDimitry Andric [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>, 6600b57cec5SDimitry Andric Requires<[In64BitMode]>; 6610b57cec5SDimitry Andric} // SchedRW 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 6650b57cec5SDimitry Andric// Double shift instructions (generalizations of rotate) 6660b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andriclet Constraints = "$src1 = $dst" in { 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteSHDrrcl] in { 6710b57cec5SDimitry Andricdef SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst), 6720b57cec5SDimitry Andric (ins GR16:$src1, GR16:$src2), 6730b57cec5SDimitry Andric "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6745ffd83dbSDimitry Andric [(set GR16:$dst, (X86fshl GR16:$src1, GR16:$src2, CL))]>, 6750b57cec5SDimitry Andric TB, OpSize16; 6760b57cec5SDimitry Andricdef SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst), 6770b57cec5SDimitry Andric (ins GR16:$src1, GR16:$src2), 6780b57cec5SDimitry Andric "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6795ffd83dbSDimitry Andric [(set GR16:$dst, (X86fshr GR16:$src2, GR16:$src1, CL))]>, 6800b57cec5SDimitry Andric TB, OpSize16; 6810b57cec5SDimitry Andricdef SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst), 6820b57cec5SDimitry Andric (ins GR32:$src1, GR32:$src2), 6830b57cec5SDimitry Andric "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6845ffd83dbSDimitry Andric [(set GR32:$dst, (fshl GR32:$src1, GR32:$src2, CL))]>, 6850b57cec5SDimitry Andric TB, OpSize32; 6860b57cec5SDimitry Andricdef SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst), 6870b57cec5SDimitry Andric (ins GR32:$src1, GR32:$src2), 6880b57cec5SDimitry Andric "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6895ffd83dbSDimitry Andric [(set GR32:$dst, (fshr GR32:$src2, GR32:$src1, CL))]>, 6900b57cec5SDimitry Andric TB, OpSize32; 6910b57cec5SDimitry Andricdef SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), 6920b57cec5SDimitry Andric (ins GR64:$src1, GR64:$src2), 6930b57cec5SDimitry Andric "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6945ffd83dbSDimitry Andric [(set GR64:$dst, (fshl GR64:$src1, GR64:$src2, CL))]>, 6950b57cec5SDimitry Andric TB; 6960b57cec5SDimitry Andricdef SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), 6970b57cec5SDimitry Andric (ins GR64:$src1, GR64:$src2), 6980b57cec5SDimitry Andric "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", 6995ffd83dbSDimitry Andric [(set GR64:$dst, (fshr GR64:$src2, GR64:$src1, CL))]>, 7000b57cec5SDimitry Andric TB; 701*bdd1243dSDimitry Andric} // Uses, SchedRW 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andriclet isCommutable = 1, SchedRW = [WriteSHDrri] in { // These instructions commute to each other. 7040b57cec5SDimitry Andricdef SHLD16rri8 : Ii8<0xA4, MRMDestReg, 7050b57cec5SDimitry Andric (outs GR16:$dst), 7060b57cec5SDimitry Andric (ins GR16:$src1, GR16:$src2, u8imm:$src3), 7070b57cec5SDimitry Andric "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7085ffd83dbSDimitry Andric [(set GR16:$dst, (X86fshl GR16:$src1, GR16:$src2, 7090b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7100b57cec5SDimitry Andric TB, OpSize16; 7110b57cec5SDimitry Andricdef SHRD16rri8 : Ii8<0xAC, MRMDestReg, 7120b57cec5SDimitry Andric (outs GR16:$dst), 7130b57cec5SDimitry Andric (ins GR16:$src1, GR16:$src2, u8imm:$src3), 7140b57cec5SDimitry Andric "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7155ffd83dbSDimitry Andric [(set GR16:$dst, (X86fshr GR16:$src2, GR16:$src1, 7160b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7170b57cec5SDimitry Andric TB, OpSize16; 7180b57cec5SDimitry Andricdef SHLD32rri8 : Ii8<0xA4, MRMDestReg, 7190b57cec5SDimitry Andric (outs GR32:$dst), 7200b57cec5SDimitry Andric (ins GR32:$src1, GR32:$src2, u8imm:$src3), 7210b57cec5SDimitry Andric "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7225ffd83dbSDimitry Andric [(set GR32:$dst, (fshl GR32:$src1, GR32:$src2, 7230b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7240b57cec5SDimitry Andric TB, OpSize32; 7250b57cec5SDimitry Andricdef SHRD32rri8 : Ii8<0xAC, MRMDestReg, 7260b57cec5SDimitry Andric (outs GR32:$dst), 7270b57cec5SDimitry Andric (ins GR32:$src1, GR32:$src2, u8imm:$src3), 7280b57cec5SDimitry Andric "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7295ffd83dbSDimitry Andric [(set GR32:$dst, (fshr GR32:$src2, GR32:$src1, 7300b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7310b57cec5SDimitry Andric TB, OpSize32; 7320b57cec5SDimitry Andricdef SHLD64rri8 : RIi8<0xA4, MRMDestReg, 7330b57cec5SDimitry Andric (outs GR64:$dst), 7340b57cec5SDimitry Andric (ins GR64:$src1, GR64:$src2, u8imm:$src3), 7350b57cec5SDimitry Andric "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7365ffd83dbSDimitry Andric [(set GR64:$dst, (fshl GR64:$src1, GR64:$src2, 7370b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7380b57cec5SDimitry Andric TB; 7390b57cec5SDimitry Andricdef SHRD64rri8 : RIi8<0xAC, MRMDestReg, 7400b57cec5SDimitry Andric (outs GR64:$dst), 7410b57cec5SDimitry Andric (ins GR64:$src1, GR64:$src2, u8imm:$src3), 7420b57cec5SDimitry Andric "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7435ffd83dbSDimitry Andric [(set GR64:$dst, (fshr GR64:$src2, GR64:$src1, 7440b57cec5SDimitry Andric (i8 imm:$src3)))]>, 7450b57cec5SDimitry Andric TB; 7460b57cec5SDimitry Andric} // SchedRW 7470b57cec5SDimitry Andric} // Constraints = "$src = $dst" 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andriclet Uses = [CL], SchedRW = [WriteSHDmrcl] in { 7500b57cec5SDimitry Andricdef SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), 7510b57cec5SDimitry Andric "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7525ffd83dbSDimitry Andric [(store (X86fshl (loadi16 addr:$dst), GR16:$src2, CL), 7530b57cec5SDimitry Andric addr:$dst)]>, TB, OpSize16; 7540b57cec5SDimitry Andricdef SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), 7550b57cec5SDimitry Andric "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7565ffd83dbSDimitry Andric [(store (X86fshr GR16:$src2, (loadi16 addr:$dst), CL), 7570b57cec5SDimitry Andric addr:$dst)]>, TB, OpSize16; 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andricdef SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), 7600b57cec5SDimitry Andric "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7615ffd83dbSDimitry Andric [(store (fshl (loadi32 addr:$dst), GR32:$src2, CL), 7620b57cec5SDimitry Andric addr:$dst)]>, TB, OpSize32; 7630b57cec5SDimitry Andricdef SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), 7640b57cec5SDimitry Andric "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7655ffd83dbSDimitry Andric [(store (fshr GR32:$src2, (loadi32 addr:$dst), CL), 7660b57cec5SDimitry Andric addr:$dst)]>, TB, OpSize32; 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andricdef SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), 7690b57cec5SDimitry Andric "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7705ffd83dbSDimitry Andric [(store (fshl (loadi64 addr:$dst), GR64:$src2, CL), 7710b57cec5SDimitry Andric addr:$dst)]>, TB; 7720b57cec5SDimitry Andricdef SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), 7730b57cec5SDimitry Andric "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}", 7745ffd83dbSDimitry Andric [(store (fshr GR64:$src2, (loadi64 addr:$dst), CL), 7750b57cec5SDimitry Andric addr:$dst)]>, TB; 776*bdd1243dSDimitry Andric} // Uses, SchedRW 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andriclet SchedRW = [WriteSHDmri] in { 7790b57cec5SDimitry Andricdef SHLD16mri8 : Ii8<0xA4, MRMDestMem, 7800b57cec5SDimitry Andric (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3), 7810b57cec5SDimitry Andric "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7825ffd83dbSDimitry Andric [(store (X86fshl (loadi16 addr:$dst), GR16:$src2, 7830b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 7840b57cec5SDimitry Andric TB, OpSize16; 7850b57cec5SDimitry Andricdef SHRD16mri8 : Ii8<0xAC, MRMDestMem, 7860b57cec5SDimitry Andric (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3), 7870b57cec5SDimitry Andric "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7885ffd83dbSDimitry Andric [(store (X86fshr GR16:$src2, (loadi16 addr:$dst), 7890b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 7900b57cec5SDimitry Andric TB, OpSize16; 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andricdef SHLD32mri8 : Ii8<0xA4, MRMDestMem, 7930b57cec5SDimitry Andric (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3), 7940b57cec5SDimitry Andric "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 7955ffd83dbSDimitry Andric [(store (fshl (loadi32 addr:$dst), GR32:$src2, 7960b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 7970b57cec5SDimitry Andric TB, OpSize32; 7980b57cec5SDimitry Andricdef SHRD32mri8 : Ii8<0xAC, MRMDestMem, 7990b57cec5SDimitry Andric (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3), 8000b57cec5SDimitry Andric "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 8015ffd83dbSDimitry Andric [(store (fshr GR32:$src2, (loadi32 addr:$dst), 8020b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 8030b57cec5SDimitry Andric TB, OpSize32; 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andricdef SHLD64mri8 : RIi8<0xA4, MRMDestMem, 8060b57cec5SDimitry Andric (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3), 8070b57cec5SDimitry Andric "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 8085ffd83dbSDimitry Andric [(store (fshl (loadi64 addr:$dst), GR64:$src2, 8090b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 8100b57cec5SDimitry Andric TB; 8110b57cec5SDimitry Andricdef SHRD64mri8 : RIi8<0xAC, MRMDestMem, 8120b57cec5SDimitry Andric (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3), 8130b57cec5SDimitry Andric "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", 8145ffd83dbSDimitry Andric [(store (fshr GR64:$src2, (loadi64 addr:$dst), 8150b57cec5SDimitry Andric (i8 imm:$src3)), addr:$dst)]>, 8160b57cec5SDimitry Andric TB; 8170b57cec5SDimitry Andric} // SchedRW 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric} // Defs = [EFLAGS] 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric// Use the opposite rotate if allows us to use the rotate by 1 instruction. 8220b57cec5SDimitry Andricdef : Pat<(rotl GR8:$src1, (i8 7)), (ROR8r1 GR8:$src1)>; 8230b57cec5SDimitry Andricdef : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1 GR16:$src1)>; 8240b57cec5SDimitry Andricdef : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1 GR32:$src1)>; 8250b57cec5SDimitry Andricdef : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1 GR64:$src1)>; 8260b57cec5SDimitry Andricdef : Pat<(rotr GR8:$src1, (i8 7)), (ROL8r1 GR8:$src1)>; 8270b57cec5SDimitry Andricdef : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1 GR16:$src1)>; 8280b57cec5SDimitry Andricdef : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1 GR32:$src1)>; 8290b57cec5SDimitry Andricdef : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1 GR64:$src1)>; 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi8 addr:$dst), (i8 7)), addr:$dst), 8320b57cec5SDimitry Andric (ROR8m1 addr:$dst)>; 8330b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi16 addr:$dst), (i8 15)), addr:$dst), 8340b57cec5SDimitry Andric (ROR16m1 addr:$dst)>; 8350b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi32 addr:$dst), (i8 31)), addr:$dst), 8360b57cec5SDimitry Andric (ROR32m1 addr:$dst)>; 8370b57cec5SDimitry Andricdef : Pat<(store (rotl (loadi64 addr:$dst), (i8 63)), addr:$dst), 8380b57cec5SDimitry Andric (ROR64m1 addr:$dst)>, Requires<[In64BitMode]>; 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi8 addr:$dst), (i8 7)), addr:$dst), 8410b57cec5SDimitry Andric (ROL8m1 addr:$dst)>; 8420b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi16 addr:$dst), (i8 15)), addr:$dst), 8430b57cec5SDimitry Andric (ROL16m1 addr:$dst)>; 8440b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi32 addr:$dst), (i8 31)), addr:$dst), 8450b57cec5SDimitry Andric (ROL32m1 addr:$dst)>; 8460b57cec5SDimitry Andricdef : Pat<(store (rotr (loadi64 addr:$dst), (i8 63)), addr:$dst), 8470b57cec5SDimitry Andric (ROL64m1 addr:$dst)>, Requires<[In64BitMode]>; 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric// Sandy Bridge and newer Intel processors support faster rotates using 8500b57cec5SDimitry Andric// SHLD to avoid a partial flag update on the normal rotate instructions. 8510b57cec5SDimitry Andric// Use a pseudo so that TwoInstructionPass and register allocation will see 8520b57cec5SDimitry Andric// this as unary instruction. 8530b57cec5SDimitry Andriclet Predicates = [HasFastSHLDRotate], AddedComplexity = 5, 8540b57cec5SDimitry Andric Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteSHDrri], 8550b57cec5SDimitry Andric Constraints = "$src1 = $dst" in { 8560b57cec5SDimitry Andric def SHLDROT32ri : I<0, Pseudo, (outs GR32:$dst), 8570b57cec5SDimitry Andric (ins GR32:$src1, u8imm:$shamt), "", 8580b57cec5SDimitry Andric [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$shamt)))]>; 8590b57cec5SDimitry Andric def SHLDROT64ri : I<0, Pseudo, (outs GR64:$dst), 8600b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$shamt), "", 8610b57cec5SDimitry Andric [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$shamt)))]>; 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric def SHRDROT32ri : I<0, Pseudo, (outs GR32:$dst), 8640b57cec5SDimitry Andric (ins GR32:$src1, u8imm:$shamt), "", 8650b57cec5SDimitry Andric [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$shamt)))]>; 8660b57cec5SDimitry Andric def SHRDROT64ri : I<0, Pseudo, (outs GR64:$dst), 8670b57cec5SDimitry Andric (ins GR64:$src1, u8imm:$shamt), "", 8680b57cec5SDimitry Andric [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$shamt)))]>; 8690b57cec5SDimitry Andric} 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andricdef ROT32L2R_imm8 : SDNodeXForm<imm, [{ 8720b57cec5SDimitry Andric // Convert a ROTL shamt to a ROTR shamt on 32-bit integer. 8730b57cec5SDimitry Andric return getI8Imm(32 - N->getZExtValue(), SDLoc(N)); 8740b57cec5SDimitry Andric}]>; 8750b57cec5SDimitry Andric 8760b57cec5SDimitry Andricdef ROT64L2R_imm8 : SDNodeXForm<imm, [{ 8770b57cec5SDimitry Andric // Convert a ROTL shamt to a ROTR shamt on 64-bit integer. 8780b57cec5SDimitry Andric return getI8Imm(64 - N->getZExtValue(), SDLoc(N)); 8790b57cec5SDimitry Andric}]>; 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric// NOTE: We use WriteShift for these rotates as they avoid the stalls 8820b57cec5SDimitry Andric// of many of the older x86 rotate instructions. 8830b57cec5SDimitry Andricmulticlass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop> { 8840b57cec5SDimitry Andriclet hasSideEffects = 0 in { 8850b57cec5SDimitry Andric def ri : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, u8imm:$src2), 8860b57cec5SDimitry Andric !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 8870b57cec5SDimitry Andric []>, TAXD, VEX, Sched<[WriteShift]>; 8880b57cec5SDimitry Andric let mayLoad = 1 in 8890b57cec5SDimitry Andric def mi : Ii8<0xF0, MRMSrcMem, (outs RC:$dst), 8900b57cec5SDimitry Andric (ins x86memop:$src1, u8imm:$src2), 8910b57cec5SDimitry Andric !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 8920b57cec5SDimitry Andric []>, TAXD, VEX, Sched<[WriteShiftLd]>; 8930b57cec5SDimitry Andric} 8940b57cec5SDimitry Andric} 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andricmulticlass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop> { 8970b57cec5SDimitry Andriclet hasSideEffects = 0 in { 8980b57cec5SDimitry Andric def rr : I<0xF7, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2), 8990b57cec5SDimitry Andric !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, 9000b57cec5SDimitry Andric VEX, Sched<[WriteShift]>; 9010b57cec5SDimitry Andric let mayLoad = 1 in 9020b57cec5SDimitry Andric def rm : I<0xF7, MRMSrcMem4VOp3, 9030b57cec5SDimitry Andric (outs RC:$dst), (ins x86memop:$src1, RC:$src2), 9040b57cec5SDimitry Andric !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, 9050b57cec5SDimitry Andric VEX, Sched<[WriteShift.Folded, 9060b57cec5SDimitry Andric // x86memop:$src1 9070b57cec5SDimitry Andric ReadDefault, ReadDefault, ReadDefault, ReadDefault, 9080b57cec5SDimitry Andric ReadDefault, 9090b57cec5SDimitry Andric // RC:$src2 9100b57cec5SDimitry Andric WriteShift.ReadAfterFold]>; 9110b57cec5SDimitry Andric} 9120b57cec5SDimitry Andric} 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andriclet Predicates = [HasBMI2] in { 9150b57cec5SDimitry Andric defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>; 9160b57cec5SDimitry Andric defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, VEX_W; 9170b57cec5SDimitry Andric defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8XS; 9180b57cec5SDimitry Andric defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8XS, VEX_W; 9190b57cec5SDimitry Andric defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8XD; 9200b57cec5SDimitry Andric defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8XD, VEX_W; 9210b57cec5SDimitry Andric defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8PD; 9220b57cec5SDimitry Andric defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8PD, VEX_W; 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric // Prefer RORX which is non-destructive and doesn't update EFLAGS. 9250b57cec5SDimitry Andric let AddedComplexity = 10 in { 9260b57cec5SDimitry Andric def : Pat<(rotr GR32:$src, (i8 imm:$shamt)), 9270b57cec5SDimitry Andric (RORX32ri GR32:$src, imm:$shamt)>; 9280b57cec5SDimitry Andric def : Pat<(rotr GR64:$src, (i8 imm:$shamt)), 9290b57cec5SDimitry Andric (RORX64ri GR64:$src, imm:$shamt)>; 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric def : Pat<(rotl GR32:$src, (i8 imm:$shamt)), 9320b57cec5SDimitry Andric (RORX32ri GR32:$src, (ROT32L2R_imm8 imm:$shamt))>; 9330b57cec5SDimitry Andric def : Pat<(rotl GR64:$src, (i8 imm:$shamt)), 9340b57cec5SDimitry Andric (RORX64ri GR64:$src, (ROT64L2R_imm8 imm:$shamt))>; 9350b57cec5SDimitry Andric } 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric def : Pat<(rotr (loadi32 addr:$src), (i8 imm:$shamt)), 9380b57cec5SDimitry Andric (RORX32mi addr:$src, imm:$shamt)>; 9390b57cec5SDimitry Andric def : Pat<(rotr (loadi64 addr:$src), (i8 imm:$shamt)), 9400b57cec5SDimitry Andric (RORX64mi addr:$src, imm:$shamt)>; 9410b57cec5SDimitry Andric 9420b57cec5SDimitry Andric def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)), 9430b57cec5SDimitry Andric (RORX32mi addr:$src, (ROT32L2R_imm8 imm:$shamt))>; 9440b57cec5SDimitry Andric def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)), 9450b57cec5SDimitry Andric (RORX64mi addr:$src, (ROT64L2R_imm8 imm:$shamt))>; 9460b57cec5SDimitry Andric 9470b57cec5SDimitry Andric // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not 9480b57cec5SDimitry Andric // immediate shift, i.e. the following code is considered better 9490b57cec5SDimitry Andric // 9500b57cec5SDimitry Andric // mov %edi, %esi 9510b57cec5SDimitry Andric // shl $imm, %esi 9520b57cec5SDimitry Andric // ... %edi, ... 9530b57cec5SDimitry Andric // 9540b57cec5SDimitry Andric // than 9550b57cec5SDimitry Andric // 9560b57cec5SDimitry Andric // movb $imm, %sil 9570b57cec5SDimitry Andric // shlx %sil, %edi, %esi 9580b57cec5SDimitry Andric // ... %edi, ... 9590b57cec5SDimitry Andric // 9600b57cec5SDimitry Andric let AddedComplexity = 1 in { 9610b57cec5SDimitry Andric def : Pat<(sra GR32:$src1, GR8:$src2), 9620b57cec5SDimitry Andric (SARX32rr GR32:$src1, 9630b57cec5SDimitry Andric (INSERT_SUBREG 9640b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9650b57cec5SDimitry Andric def : Pat<(sra GR64:$src1, GR8:$src2), 9660b57cec5SDimitry Andric (SARX64rr GR64:$src1, 9670b57cec5SDimitry Andric (INSERT_SUBREG 9680b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric def : Pat<(srl GR32:$src1, GR8:$src2), 9710b57cec5SDimitry Andric (SHRX32rr GR32:$src1, 9720b57cec5SDimitry Andric (INSERT_SUBREG 9730b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9740b57cec5SDimitry Andric def : Pat<(srl GR64:$src1, GR8:$src2), 9750b57cec5SDimitry Andric (SHRX64rr GR64:$src1, 9760b57cec5SDimitry Andric (INSERT_SUBREG 9770b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric def : Pat<(shl GR32:$src1, GR8:$src2), 9800b57cec5SDimitry Andric (SHLX32rr GR32:$src1, 9810b57cec5SDimitry Andric (INSERT_SUBREG 9820b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9830b57cec5SDimitry Andric def : Pat<(shl GR64:$src1, GR8:$src2), 9840b57cec5SDimitry Andric (SHLX64rr GR64:$src1, 9850b57cec5SDimitry Andric (INSERT_SUBREG 9860b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric // We prefer to use 9900b57cec5SDimitry Andric // mov (%ecx), %esi 9910b57cec5SDimitry Andric // shl $imm, $esi 9920b57cec5SDimitry Andric // 9930b57cec5SDimitry Andric // over 9940b57cec5SDimitry Andric // 9950b57cec5SDimitry Andric // movb $imm, %al 9960b57cec5SDimitry Andric // shlx %al, (%ecx), %esi 9970b57cec5SDimitry Andric // 9980b57cec5SDimitry Andric // This priority is enforced by IsProfitableToFoldLoad. 9990b57cec5SDimitry Andric def : Pat<(sra (loadi32 addr:$src1), GR8:$src2), 10000b57cec5SDimitry Andric (SARX32rm addr:$src1, 10010b57cec5SDimitry Andric (INSERT_SUBREG 10020b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10030b57cec5SDimitry Andric def : Pat<(sra (loadi64 addr:$src1), GR8:$src2), 10040b57cec5SDimitry Andric (SARX64rm addr:$src1, 10050b57cec5SDimitry Andric (INSERT_SUBREG 10060b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric def : Pat<(srl (loadi32 addr:$src1), GR8:$src2), 10090b57cec5SDimitry Andric (SHRX32rm addr:$src1, 10100b57cec5SDimitry Andric (INSERT_SUBREG 10110b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10120b57cec5SDimitry Andric def : Pat<(srl (loadi64 addr:$src1), GR8:$src2), 10130b57cec5SDimitry Andric (SHRX64rm addr:$src1, 10140b57cec5SDimitry Andric (INSERT_SUBREG 10150b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric def : Pat<(shl (loadi32 addr:$src1), GR8:$src2), 10180b57cec5SDimitry Andric (SHLX32rm addr:$src1, 10190b57cec5SDimitry Andric (INSERT_SUBREG 10200b57cec5SDimitry Andric (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10210b57cec5SDimitry Andric def : Pat<(shl (loadi64 addr:$src1), GR8:$src2), 10220b57cec5SDimitry Andric (SHLX64rm addr:$src1, 10230b57cec5SDimitry Andric (INSERT_SUBREG 10240b57cec5SDimitry Andric (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; 10250b57cec5SDimitry Andric} 10265ffd83dbSDimitry Andric 10275ffd83dbSDimitry Andricdef : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)), 10285ffd83dbSDimitry Andric (ROL8ri GR8:$src1, relocImm:$src2)>; 10295ffd83dbSDimitry Andricdef : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)), 10305ffd83dbSDimitry Andric (ROL16ri GR16:$src1, relocImm:$src2)>; 10315ffd83dbSDimitry Andricdef : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)), 10325ffd83dbSDimitry Andric (ROL32ri GR32:$src1, relocImm:$src2)>; 10335ffd83dbSDimitry Andricdef : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)), 10345ffd83dbSDimitry Andric (ROL64ri GR64:$src1, relocImm:$src2)>; 10355ffd83dbSDimitry Andric 10365ffd83dbSDimitry Andricdef : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)), 10375ffd83dbSDimitry Andric (ROR8ri GR8:$src1, relocImm:$src2)>; 10385ffd83dbSDimitry Andricdef : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)), 10395ffd83dbSDimitry Andric (ROR16ri GR16:$src1, relocImm:$src2)>; 10405ffd83dbSDimitry Andricdef : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)), 10415ffd83dbSDimitry Andric (ROR32ri GR32:$src1, relocImm:$src2)>; 10425ffd83dbSDimitry Andricdef : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)), 10435ffd83dbSDimitry Andric (ROR64ri GR64:$src1, relocImm:$src2)>; 1044