X86InstrShiftRotate.td 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. //===-- X86InstrShiftRotate.td - Shift and Rotate Instrs ---*- tablegen -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file describes the shift and rotate instructions.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. // FIXME: Someone needs to smear multipattern goodness all over this file.
  13. let Defs = [EFLAGS] in {
  14. let Constraints = "$src1 = $dst" in {
  15. let Uses = [CL], SchedRW = [WriteShiftCL] in {
  16. def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1),
  17. "shl{b}\t{%cl, $dst|$dst, cl}",
  18. [(set GR8:$dst, (shl GR8:$src1, CL))]>;
  19. def SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
  20. "shl{w}\t{%cl, $dst|$dst, cl}",
  21. [(set GR16:$dst, (shl GR16:$src1, CL))]>, OpSize16;
  22. def SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
  23. "shl{l}\t{%cl, $dst|$dst, cl}",
  24. [(set GR32:$dst, (shl GR32:$src1, CL))]>, OpSize32;
  25. def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
  26. "shl{q}\t{%cl, $dst|$dst, cl}",
  27. [(set GR64:$dst, (shl GR64:$src1, CL))]>;
  28. } // Uses = [CL], SchedRW
  29. let SchedRW = [WriteShift] in {
  30. let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
  31. def SHL8ri : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
  32. "shl{b}\t{$src2, $dst|$dst, $src2}",
  33. [(set GR8:$dst, (shl GR8:$src1, (i8 imm:$src2)))]>;
  34. def SHL16ri : Ii8<0xC1, MRM4r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
  35. "shl{w}\t{$src2, $dst|$dst, $src2}",
  36. [(set GR16:$dst, (shl GR16:$src1, (i8 imm:$src2)))]>,
  37. OpSize16;
  38. def SHL32ri : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
  39. "shl{l}\t{$src2, $dst|$dst, $src2}",
  40. [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))]>,
  41. OpSize32;
  42. def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst),
  43. (ins GR64:$src1, u8imm:$src2),
  44. "shl{q}\t{$src2, $dst|$dst, $src2}",
  45. [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
  46. } // isConvertibleToThreeAddress = 1
  47. // NOTE: We don't include patterns for shifts of a register by one, because
  48. // 'add reg,reg' is cheaper (and we have a Pat pattern for shift-by-one).
  49. let hasSideEffects = 0 in {
  50. def SHL8r1 : I<0xD0, MRM4r, (outs GR8:$dst), (ins GR8:$src1),
  51. "shl{b}\t$dst", []>;
  52. def SHL16r1 : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
  53. "shl{w}\t$dst", []>, OpSize16;
  54. def SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
  55. "shl{l}\t$dst", []>, OpSize32;
  56. def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
  57. "shl{q}\t$dst", []>;
  58. } // hasSideEffects = 0
  59. } // SchedRW
  60. } // Constraints = "$src = $dst"
  61. // FIXME: Why do we need an explicit "Uses = [CL]" when the instr has a pattern
  62. // using CL?
  63. let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
  64. def SHL8mCL : I<0xD2, MRM4m, (outs), (ins i8mem :$dst),
  65. "shl{b}\t{%cl, $dst|$dst, cl}",
  66. [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>;
  67. def SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst),
  68. "shl{w}\t{%cl, $dst|$dst, cl}",
  69. [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
  70. OpSize16;
  71. def SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst),
  72. "shl{l}\t{%cl, $dst|$dst, cl}",
  73. [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
  74. OpSize32;
  75. def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
  76. "shl{q}\t{%cl, $dst|$dst, cl}",
  77. [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>,
  78. Requires<[In64BitMode]>;
  79. } // Uses, SchedRW
  80. let SchedRW = [WriteShiftLd, WriteRMW] in {
  81. def SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, u8imm:$src),
  82. "shl{b}\t{$src, $dst|$dst, $src}",
  83. [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  84. def SHL16mi : Ii8<0xC1, MRM4m, (outs), (ins i16mem:$dst, u8imm:$src),
  85. "shl{w}\t{$src, $dst|$dst, $src}",
  86. [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  87. OpSize16;
  88. def SHL32mi : Ii8<0xC1, MRM4m, (outs), (ins i32mem:$dst, u8imm:$src),
  89. "shl{l}\t{$src, $dst|$dst, $src}",
  90. [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  91. OpSize32;
  92. def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, u8imm:$src),
  93. "shl{q}\t{$src, $dst|$dst, $src}",
  94. [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  95. Requires<[In64BitMode]>;
  96. // Shift by 1
  97. def SHL8m1 : I<0xD0, MRM4m, (outs), (ins i8mem :$dst),
  98. "shl{b}\t$dst",
  99. [(store (shl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
  100. def SHL16m1 : I<0xD1, MRM4m, (outs), (ins i16mem:$dst),
  101. "shl{w}\t$dst",
  102. [(store (shl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
  103. OpSize16;
  104. def SHL32m1 : I<0xD1, MRM4m, (outs), (ins i32mem:$dst),
  105. "shl{l}\t$dst",
  106. [(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
  107. OpSize32;
  108. def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
  109. "shl{q}\t$dst",
  110. [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
  111. Requires<[In64BitMode]>;
  112. } // SchedRW
  113. let Constraints = "$src1 = $dst" in {
  114. let Uses = [CL], SchedRW = [WriteShiftCL] in {
  115. def SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src1),
  116. "shr{b}\t{%cl, $dst|$dst, cl}",
  117. [(set GR8:$dst, (srl GR8:$src1, CL))]>;
  118. def SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
  119. "shr{w}\t{%cl, $dst|$dst, cl}",
  120. [(set GR16:$dst, (srl GR16:$src1, CL))]>, OpSize16;
  121. def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
  122. "shr{l}\t{%cl, $dst|$dst, cl}",
  123. [(set GR32:$dst, (srl GR32:$src1, CL))]>, OpSize32;
  124. def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
  125. "shr{q}\t{%cl, $dst|$dst, cl}",
  126. [(set GR64:$dst, (srl GR64:$src1, CL))]>;
  127. } // Uses, SchedRW
  128. let SchedRW = [WriteShift] in {
  129. def SHR8ri : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$src2),
  130. "shr{b}\t{$src2, $dst|$dst, $src2}",
  131. [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))]>;
  132. def SHR16ri : Ii8<0xC1, MRM5r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
  133. "shr{w}\t{$src2, $dst|$dst, $src2}",
  134. [(set GR16:$dst, (srl GR16:$src1, (i8 imm:$src2)))]>,
  135. OpSize16;
  136. def SHR32ri : Ii8<0xC1, MRM5r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
  137. "shr{l}\t{$src2, $dst|$dst, $src2}",
  138. [(set GR32:$dst, (srl GR32:$src1, (i8 imm:$src2)))]>,
  139. OpSize32;
  140. def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$src2),
  141. "shr{q}\t{$src2, $dst|$dst, $src2}",
  142. [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
  143. // Shift right by 1
  144. def SHR8r1 : I<0xD0, MRM5r, (outs GR8:$dst), (ins GR8:$src1),
  145. "shr{b}\t$dst",
  146. [(set GR8:$dst, (srl GR8:$src1, (i8 1)))]>;
  147. def SHR16r1 : I<0xD1, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
  148. "shr{w}\t$dst",
  149. [(set GR16:$dst, (srl GR16:$src1, (i8 1)))]>, OpSize16;
  150. def SHR32r1 : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
  151. "shr{l}\t$dst",
  152. [(set GR32:$dst, (srl GR32:$src1, (i8 1)))]>, OpSize32;
  153. def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
  154. "shr{q}\t$dst",
  155. [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
  156. } // SchedRW
  157. } // Constraints = "$src = $dst"
  158. let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
  159. def SHR8mCL : I<0xD2, MRM5m, (outs), (ins i8mem :$dst),
  160. "shr{b}\t{%cl, $dst|$dst, cl}",
  161. [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>;
  162. def SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst),
  163. "shr{w}\t{%cl, $dst|$dst, cl}",
  164. [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
  165. OpSize16;
  166. def SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst),
  167. "shr{l}\t{%cl, $dst|$dst, cl}",
  168. [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
  169. OpSize32;
  170. def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
  171. "shr{q}\t{%cl, $dst|$dst, cl}",
  172. [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>,
  173. Requires<[In64BitMode]>;
  174. } // Uses, SchedRW
  175. let SchedRW = [WriteShiftLd, WriteRMW] in {
  176. def SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, u8imm:$src),
  177. "shr{b}\t{$src, $dst|$dst, $src}",
  178. [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  179. def SHR16mi : Ii8<0xC1, MRM5m, (outs), (ins i16mem:$dst, u8imm:$src),
  180. "shr{w}\t{$src, $dst|$dst, $src}",
  181. [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  182. OpSize16;
  183. def SHR32mi : Ii8<0xC1, MRM5m, (outs), (ins i32mem:$dst, u8imm:$src),
  184. "shr{l}\t{$src, $dst|$dst, $src}",
  185. [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  186. OpSize32;
  187. def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, u8imm:$src),
  188. "shr{q}\t{$src, $dst|$dst, $src}",
  189. [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  190. Requires<[In64BitMode]>;
  191. // Shift by 1
  192. def SHR8m1 : I<0xD0, MRM5m, (outs), (ins i8mem :$dst),
  193. "shr{b}\t$dst",
  194. [(store (srl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
  195. def SHR16m1 : I<0xD1, MRM5m, (outs), (ins i16mem:$dst),
  196. "shr{w}\t$dst",
  197. [(store (srl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
  198. OpSize16;
  199. def SHR32m1 : I<0xD1, MRM5m, (outs), (ins i32mem:$dst),
  200. "shr{l}\t$dst",
  201. [(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
  202. OpSize32;
  203. def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
  204. "shr{q}\t$dst",
  205. [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
  206. Requires<[In64BitMode]>;
  207. } // SchedRW
  208. let Constraints = "$src1 = $dst" in {
  209. let Uses = [CL], SchedRW = [WriteShiftCL] in {
  210. def SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
  211. "sar{b}\t{%cl, $dst|$dst, cl}",
  212. [(set GR8:$dst, (sra GR8:$src1, CL))]>;
  213. def SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
  214. "sar{w}\t{%cl, $dst|$dst, cl}",
  215. [(set GR16:$dst, (sra GR16:$src1, CL))]>,
  216. OpSize16;
  217. def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
  218. "sar{l}\t{%cl, $dst|$dst, cl}",
  219. [(set GR32:$dst, (sra GR32:$src1, CL))]>,
  220. OpSize32;
  221. def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
  222. "sar{q}\t{%cl, $dst|$dst, cl}",
  223. [(set GR64:$dst, (sra GR64:$src1, CL))]>;
  224. } // Uses, SchedRW
  225. let SchedRW = [WriteShift] in {
  226. def SAR8ri : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
  227. "sar{b}\t{$src2, $dst|$dst, $src2}",
  228. [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))]>;
  229. def SAR16ri : Ii8<0xC1, MRM7r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
  230. "sar{w}\t{$src2, $dst|$dst, $src2}",
  231. [(set GR16:$dst, (sra GR16:$src1, (i8 imm:$src2)))]>,
  232. OpSize16;
  233. def SAR32ri : Ii8<0xC1, MRM7r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
  234. "sar{l}\t{$src2, $dst|$dst, $src2}",
  235. [(set GR32:$dst, (sra GR32:$src1, (i8 imm:$src2)))]>,
  236. OpSize32;
  237. def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst),
  238. (ins GR64:$src1, u8imm:$src2),
  239. "sar{q}\t{$src2, $dst|$dst, $src2}",
  240. [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
  241. // Shift by 1
  242. def SAR8r1 : I<0xD0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
  243. "sar{b}\t$dst",
  244. [(set GR8:$dst, (sra GR8:$src1, (i8 1)))]>;
  245. def SAR16r1 : I<0xD1, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
  246. "sar{w}\t$dst",
  247. [(set GR16:$dst, (sra GR16:$src1, (i8 1)))]>, OpSize16;
  248. def SAR32r1 : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
  249. "sar{l}\t$dst",
  250. [(set GR32:$dst, (sra GR32:$src1, (i8 1)))]>, OpSize32;
  251. def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
  252. "sar{q}\t$dst",
  253. [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
  254. } // SchedRW
  255. } // Constraints = "$src = $dst"
  256. let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
  257. def SAR8mCL : I<0xD2, MRM7m, (outs), (ins i8mem :$dst),
  258. "sar{b}\t{%cl, $dst|$dst, cl}",
  259. [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>;
  260. def SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst),
  261. "sar{w}\t{%cl, $dst|$dst, cl}",
  262. [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
  263. OpSize16;
  264. def SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst),
  265. "sar{l}\t{%cl, $dst|$dst, cl}",
  266. [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
  267. OpSize32;
  268. def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
  269. "sar{q}\t{%cl, $dst|$dst, cl}",
  270. [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>,
  271. Requires<[In64BitMode]>;
  272. } // Uses, SchedRW
  273. let SchedRW = [WriteShiftLd, WriteRMW] in {
  274. def SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, u8imm:$src),
  275. "sar{b}\t{$src, $dst|$dst, $src}",
  276. [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  277. def SAR16mi : Ii8<0xC1, MRM7m, (outs), (ins i16mem:$dst, u8imm:$src),
  278. "sar{w}\t{$src, $dst|$dst, $src}",
  279. [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  280. OpSize16;
  281. def SAR32mi : Ii8<0xC1, MRM7m, (outs), (ins i32mem:$dst, u8imm:$src),
  282. "sar{l}\t{$src, $dst|$dst, $src}",
  283. [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  284. OpSize32;
  285. def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, u8imm:$src),
  286. "sar{q}\t{$src, $dst|$dst, $src}",
  287. [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  288. Requires<[In64BitMode]>;
  289. // Shift by 1
  290. def SAR8m1 : I<0xD0, MRM7m, (outs), (ins i8mem :$dst),
  291. "sar{b}\t$dst",
  292. [(store (sra (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
  293. def SAR16m1 : I<0xD1, MRM7m, (outs), (ins i16mem:$dst),
  294. "sar{w}\t$dst",
  295. [(store (sra (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
  296. OpSize16;
  297. def SAR32m1 : I<0xD1, MRM7m, (outs), (ins i32mem:$dst),
  298. "sar{l}\t$dst",
  299. [(store (sra (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
  300. OpSize32;
  301. def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
  302. "sar{q}\t$dst",
  303. [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
  304. Requires<[In64BitMode]>;
  305. } // SchedRW
  306. //===----------------------------------------------------------------------===//
  307. // Rotate instructions
  308. //===----------------------------------------------------------------------===//
  309. let hasSideEffects = 0 in {
  310. let Constraints = "$src1 = $dst" in {
  311. let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in {
  312. def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
  313. "rcl{b}\t{%cl, $dst|$dst, cl}", []>;
  314. def RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
  315. "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
  316. def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
  317. "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
  318. def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
  319. "rcl{q}\t{%cl, $dst|$dst, cl}", []>;
  320. } // Uses = [CL, EFLAGS], SchedRW
  321. let Uses = [EFLAGS], SchedRW = [WriteRotate] in {
  322. def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
  323. "rcl{b}\t$dst", []>;
  324. def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt),
  325. "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
  326. def RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
  327. "rcl{w}\t$dst", []>, OpSize16;
  328. def RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt),
  329. "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
  330. def RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
  331. "rcl{l}\t$dst", []>, OpSize32;
  332. def RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt),
  333. "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
  334. def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
  335. "rcl{q}\t$dst", []>;
  336. def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt),
  337. "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
  338. } // Uses = [EFLAGS], SchedRW
  339. let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in {
  340. def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
  341. "rcr{b}\t{%cl, $dst|$dst, cl}", []>;
  342. def RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
  343. "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
  344. def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
  345. "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
  346. def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
  347. "rcr{q}\t{%cl, $dst|$dst, cl}", []>;
  348. } // Uses = [CL, EFLAGS], SchedRW
  349. let Uses = [EFLAGS], SchedRW = [WriteRotate] in {
  350. def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
  351. "rcr{b}\t$dst", []>;
  352. def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt),
  353. "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
  354. def RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
  355. "rcr{w}\t$dst", []>, OpSize16;
  356. def RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt),
  357. "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
  358. def RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
  359. "rcr{l}\t$dst", []>, OpSize32;
  360. def RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt),
  361. "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
  362. def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
  363. "rcr{q}\t$dst", []>;
  364. def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt),
  365. "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
  366. } // Uses = [EFLAGS], SchedRW
  367. } // Constraints = "$src = $dst"
  368. let mayStore = 1 in {
  369. let Uses = [EFLAGS], SchedRW = [WriteRotateLd, WriteRMW] in {
  370. def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst),
  371. "rcl{b}\t$dst", []>;
  372. def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, u8imm:$cnt),
  373. "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
  374. def RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst),
  375. "rcl{w}\t$dst", []>, OpSize16;
  376. def RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, u8imm:$cnt),
  377. "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
  378. def RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst),
  379. "rcl{l}\t$dst", []>, OpSize32;
  380. def RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, u8imm:$cnt),
  381. "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
  382. def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
  383. "rcl{q}\t$dst", []>, Requires<[In64BitMode]>;
  384. def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, u8imm:$cnt),
  385. "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>,
  386. Requires<[In64BitMode]>;
  387. def RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst),
  388. "rcr{b}\t$dst", []>;
  389. def RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, u8imm:$cnt),
  390. "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
  391. def RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst),
  392. "rcr{w}\t$dst", []>, OpSize16;
  393. def RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, u8imm:$cnt),
  394. "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
  395. def RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst),
  396. "rcr{l}\t$dst", []>, OpSize32;
  397. def RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, u8imm:$cnt),
  398. "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
  399. def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
  400. "rcr{q}\t$dst", []>, Requires<[In64BitMode]>;
  401. def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, u8imm:$cnt),
  402. "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>,
  403. Requires<[In64BitMode]>;
  404. } // Uses = [EFLAGS], SchedRW
  405. let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCLLd, WriteRMW] in {
  406. def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst),
  407. "rcl{b}\t{%cl, $dst|$dst, cl}", []>;
  408. def RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst),
  409. "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
  410. def RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst),
  411. "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
  412. def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
  413. "rcl{q}\t{%cl, $dst|$dst, cl}", []>,
  414. Requires<[In64BitMode]>;
  415. def RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst),
  416. "rcr{b}\t{%cl, $dst|$dst, cl}", []>;
  417. def RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst),
  418. "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
  419. def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst),
  420. "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
  421. def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
  422. "rcr{q}\t{%cl, $dst|$dst, cl}", []>,
  423. Requires<[In64BitMode]>;
  424. } // Uses = [CL, EFLAGS], SchedRW
  425. } // mayStore
  426. } // hasSideEffects = 0
  427. let Constraints = "$src1 = $dst" in {
  428. // FIXME: provide shorter instructions when imm8 == 1
  429. let Uses = [CL], SchedRW = [WriteRotateCL] in {
  430. def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
  431. "rol{b}\t{%cl, $dst|$dst, cl}",
  432. [(set GR8:$dst, (rotl GR8:$src1, CL))]>;
  433. def ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
  434. "rol{w}\t{%cl, $dst|$dst, cl}",
  435. [(set GR16:$dst, (rotl GR16:$src1, CL))]>, OpSize16;
  436. def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
  437. "rol{l}\t{%cl, $dst|$dst, cl}",
  438. [(set GR32:$dst, (rotl GR32:$src1, CL))]>, OpSize32;
  439. def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
  440. "rol{q}\t{%cl, $dst|$dst, cl}",
  441. [(set GR64:$dst, (rotl GR64:$src1, CL))]>;
  442. } // Uses, SchedRW
  443. let SchedRW = [WriteRotate] in {
  444. def ROL8ri : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
  445. "rol{b}\t{$src2, $dst|$dst, $src2}",
  446. [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))]>;
  447. def ROL16ri : Ii8<0xC1, MRM0r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
  448. "rol{w}\t{$src2, $dst|$dst, $src2}",
  449. [(set GR16:$dst, (rotl GR16:$src1, (i8 imm:$src2)))]>,
  450. OpSize16;
  451. def ROL32ri : Ii8<0xC1, MRM0r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
  452. "rol{l}\t{$src2, $dst|$dst, $src2}",
  453. [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$src2)))]>,
  454. OpSize32;
  455. def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst),
  456. (ins GR64:$src1, u8imm:$src2),
  457. "rol{q}\t{$src2, $dst|$dst, $src2}",
  458. [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
  459. // Rotate by 1
  460. def ROL8r1 : I<0xD0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
  461. "rol{b}\t$dst",
  462. [(set GR8:$dst, (rotl GR8:$src1, (i8 1)))]>;
  463. def ROL16r1 : I<0xD1, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
  464. "rol{w}\t$dst",
  465. [(set GR16:$dst, (rotl GR16:$src1, (i8 1)))]>, OpSize16;
  466. def ROL32r1 : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
  467. "rol{l}\t$dst",
  468. [(set GR32:$dst, (rotl GR32:$src1, (i8 1)))]>, OpSize32;
  469. def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
  470. "rol{q}\t$dst",
  471. [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
  472. } // SchedRW
  473. } // Constraints = "$src = $dst"
  474. let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in {
  475. def ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst),
  476. "rol{b}\t{%cl, $dst|$dst, cl}",
  477. [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>;
  478. def ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst),
  479. "rol{w}\t{%cl, $dst|$dst, cl}",
  480. [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16;
  481. def ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst),
  482. "rol{l}\t{%cl, $dst|$dst, cl}",
  483. [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32;
  484. def ROL64mCL : RI<0xD3, MRM0m, (outs), (ins i64mem:$dst),
  485. "rol{q}\t{%cl, $dst|$dst, cl}",
  486. [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>,
  487. Requires<[In64BitMode]>;
  488. } // Uses, SchedRW
  489. let SchedRW = [WriteRotateLd, WriteRMW] in {
  490. def ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, u8imm:$src1),
  491. "rol{b}\t{$src1, $dst|$dst, $src1}",
  492. [(store (rotl (loadi8 addr:$dst), (i8 imm:$src1)), addr:$dst)]>;
  493. def ROL16mi : Ii8<0xC1, MRM0m, (outs), (ins i16mem:$dst, u8imm:$src1),
  494. "rol{w}\t{$src1, $dst|$dst, $src1}",
  495. [(store (rotl (loadi16 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
  496. OpSize16;
  497. def ROL32mi : Ii8<0xC1, MRM0m, (outs), (ins i32mem:$dst, u8imm:$src1),
  498. "rol{l}\t{$src1, $dst|$dst, $src1}",
  499. [(store (rotl (loadi32 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
  500. OpSize32;
  501. def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, u8imm:$src1),
  502. "rol{q}\t{$src1, $dst|$dst, $src1}",
  503. [(store (rotl (loadi64 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
  504. Requires<[In64BitMode]>;
  505. // Rotate by 1
  506. def ROL8m1 : I<0xD0, MRM0m, (outs), (ins i8mem :$dst),
  507. "rol{b}\t$dst",
  508. [(store (rotl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
  509. def ROL16m1 : I<0xD1, MRM0m, (outs), (ins i16mem:$dst),
  510. "rol{w}\t$dst",
  511. [(store (rotl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
  512. OpSize16;
  513. def ROL32m1 : I<0xD1, MRM0m, (outs), (ins i32mem:$dst),
  514. "rol{l}\t$dst",
  515. [(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
  516. OpSize32;
  517. def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
  518. "rol{q}\t$dst",
  519. [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
  520. Requires<[In64BitMode]>;
  521. } // SchedRW
  522. let Constraints = "$src1 = $dst" in {
  523. let Uses = [CL], SchedRW = [WriteRotateCL] in {
  524. def ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
  525. "ror{b}\t{%cl, $dst|$dst, cl}",
  526. [(set GR8:$dst, (rotr GR8:$src1, CL))]>;
  527. def ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
  528. "ror{w}\t{%cl, $dst|$dst, cl}",
  529. [(set GR16:$dst, (rotr GR16:$src1, CL))]>, OpSize16;
  530. def ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
  531. "ror{l}\t{%cl, $dst|$dst, cl}",
  532. [(set GR32:$dst, (rotr GR32:$src1, CL))]>, OpSize32;
  533. def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
  534. "ror{q}\t{%cl, $dst|$dst, cl}",
  535. [(set GR64:$dst, (rotr GR64:$src1, CL))]>;
  536. }
  537. let SchedRW = [WriteRotate] in {
  538. def ROR8ri : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
  539. "ror{b}\t{$src2, $dst|$dst, $src2}",
  540. [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))]>;
  541. def ROR16ri : Ii8<0xC1, MRM1r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
  542. "ror{w}\t{$src2, $dst|$dst, $src2}",
  543. [(set GR16:$dst, (rotr GR16:$src1, (i8 imm:$src2)))]>,
  544. OpSize16;
  545. def ROR32ri : Ii8<0xC1, MRM1r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
  546. "ror{l}\t{$src2, $dst|$dst, $src2}",
  547. [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$src2)))]>,
  548. OpSize32;
  549. def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst),
  550. (ins GR64:$src1, u8imm:$src2),
  551. "ror{q}\t{$src2, $dst|$dst, $src2}",
  552. [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
  553. // Rotate by 1
  554. def ROR8r1 : I<0xD0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
  555. "ror{b}\t$dst",
  556. [(set GR8:$dst, (rotr GR8:$src1, (i8 1)))]>;
  557. def ROR16r1 : I<0xD1, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
  558. "ror{w}\t$dst",
  559. [(set GR16:$dst, (rotr GR16:$src1, (i8 1)))]>, OpSize16;
  560. def ROR32r1 : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
  561. "ror{l}\t$dst",
  562. [(set GR32:$dst, (rotr GR32:$src1, (i8 1)))]>, OpSize32;
  563. def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
  564. "ror{q}\t$dst",
  565. [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
  566. } // SchedRW
  567. } // Constraints = "$src = $dst", SchedRW
  568. let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in {
  569. def ROR8mCL : I<0xD2, MRM1m, (outs), (ins i8mem :$dst),
  570. "ror{b}\t{%cl, $dst|$dst, cl}",
  571. [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>;
  572. def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst),
  573. "ror{w}\t{%cl, $dst|$dst, cl}",
  574. [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16;
  575. def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst),
  576. "ror{l}\t{%cl, $dst|$dst, cl}",
  577. [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32;
  578. def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
  579. "ror{q}\t{%cl, $dst|$dst, cl}",
  580. [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>,
  581. Requires<[In64BitMode]>;
  582. } // Uses, SchedRW
  583. let SchedRW = [WriteRotateLd, WriteRMW] in {
  584. def ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, u8imm:$src),
  585. "ror{b}\t{$src, $dst|$dst, $src}",
  586. [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
  587. def ROR16mi : Ii8<0xC1, MRM1m, (outs), (ins i16mem:$dst, u8imm:$src),
  588. "ror{w}\t{$src, $dst|$dst, $src}",
  589. [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  590. OpSize16;
  591. def ROR32mi : Ii8<0xC1, MRM1m, (outs), (ins i32mem:$dst, u8imm:$src),
  592. "ror{l}\t{$src, $dst|$dst, $src}",
  593. [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  594. OpSize32;
  595. def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, u8imm:$src),
  596. "ror{q}\t{$src, $dst|$dst, $src}",
  597. [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
  598. Requires<[In64BitMode]>;
  599. // Rotate by 1
  600. def ROR8m1 : I<0xD0, MRM1m, (outs), (ins i8mem :$dst),
  601. "ror{b}\t$dst",
  602. [(store (rotr (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
  603. def ROR16m1 : I<0xD1, MRM1m, (outs), (ins i16mem:$dst),
  604. "ror{w}\t$dst",
  605. [(store (rotr (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
  606. OpSize16;
  607. def ROR32m1 : I<0xD1, MRM1m, (outs), (ins i32mem:$dst),
  608. "ror{l}\t$dst",
  609. [(store (rotr (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
  610. OpSize32;
  611. def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
  612. "ror{q}\t$dst",
  613. [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
  614. Requires<[In64BitMode]>;
  615. } // SchedRW
  616. //===----------------------------------------------------------------------===//
  617. // Double shift instructions (generalizations of rotate)
  618. //===----------------------------------------------------------------------===//
  619. let Constraints = "$src1 = $dst" in {
  620. let Uses = [CL], SchedRW = [WriteSHDrrcl] in {
  621. def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst),
  622. (ins GR16:$src1, GR16:$src2),
  623. "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  624. [(set GR16:$dst, (X86fshl GR16:$src1, GR16:$src2, CL))]>,
  625. TB, OpSize16;
  626. def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst),
  627. (ins GR16:$src1, GR16:$src2),
  628. "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  629. [(set GR16:$dst, (X86fshr GR16:$src2, GR16:$src1, CL))]>,
  630. TB, OpSize16;
  631. def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst),
  632. (ins GR32:$src1, GR32:$src2),
  633. "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  634. [(set GR32:$dst, (fshl GR32:$src1, GR32:$src2, CL))]>,
  635. TB, OpSize32;
  636. def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst),
  637. (ins GR32:$src1, GR32:$src2),
  638. "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  639. [(set GR32:$dst, (fshr GR32:$src2, GR32:$src1, CL))]>,
  640. TB, OpSize32;
  641. def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst),
  642. (ins GR64:$src1, GR64:$src2),
  643. "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  644. [(set GR64:$dst, (fshl GR64:$src1, GR64:$src2, CL))]>,
  645. TB;
  646. def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst),
  647. (ins GR64:$src1, GR64:$src2),
  648. "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  649. [(set GR64:$dst, (fshr GR64:$src2, GR64:$src1, CL))]>,
  650. TB;
  651. } // Uses, SchedRW
  652. let isCommutable = 1, SchedRW = [WriteSHDrri] in { // These instructions commute to each other.
  653. def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
  654. (outs GR16:$dst),
  655. (ins GR16:$src1, GR16:$src2, u8imm:$src3),
  656. "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  657. [(set GR16:$dst, (X86fshl GR16:$src1, GR16:$src2,
  658. (i8 imm:$src3)))]>,
  659. TB, OpSize16;
  660. def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
  661. (outs GR16:$dst),
  662. (ins GR16:$src1, GR16:$src2, u8imm:$src3),
  663. "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  664. [(set GR16:$dst, (X86fshr GR16:$src2, GR16:$src1,
  665. (i8 imm:$src3)))]>,
  666. TB, OpSize16;
  667. def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
  668. (outs GR32:$dst),
  669. (ins GR32:$src1, GR32:$src2, u8imm:$src3),
  670. "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  671. [(set GR32:$dst, (fshl GR32:$src1, GR32:$src2,
  672. (i8 imm:$src3)))]>,
  673. TB, OpSize32;
  674. def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
  675. (outs GR32:$dst),
  676. (ins GR32:$src1, GR32:$src2, u8imm:$src3),
  677. "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  678. [(set GR32:$dst, (fshr GR32:$src2, GR32:$src1,
  679. (i8 imm:$src3)))]>,
  680. TB, OpSize32;
  681. def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
  682. (outs GR64:$dst),
  683. (ins GR64:$src1, GR64:$src2, u8imm:$src3),
  684. "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  685. [(set GR64:$dst, (fshl GR64:$src1, GR64:$src2,
  686. (i8 imm:$src3)))]>,
  687. TB;
  688. def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
  689. (outs GR64:$dst),
  690. (ins GR64:$src1, GR64:$src2, u8imm:$src3),
  691. "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  692. [(set GR64:$dst, (fshr GR64:$src2, GR64:$src1,
  693. (i8 imm:$src3)))]>,
  694. TB;
  695. } // SchedRW
  696. } // Constraints = "$src = $dst"
  697. let Uses = [CL], SchedRW = [WriteSHDmrcl] in {
  698. def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
  699. "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  700. [(store (X86fshl (loadi16 addr:$dst), GR16:$src2, CL),
  701. addr:$dst)]>, TB, OpSize16;
  702. def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
  703. "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  704. [(store (X86fshr GR16:$src2, (loadi16 addr:$dst), CL),
  705. addr:$dst)]>, TB, OpSize16;
  706. def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
  707. "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  708. [(store (fshl (loadi32 addr:$dst), GR32:$src2, CL),
  709. addr:$dst)]>, TB, OpSize32;
  710. def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
  711. "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  712. [(store (fshr GR32:$src2, (loadi32 addr:$dst), CL),
  713. addr:$dst)]>, TB, OpSize32;
  714. def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
  715. "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  716. [(store (fshl (loadi64 addr:$dst), GR64:$src2, CL),
  717. addr:$dst)]>, TB;
  718. def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
  719. "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
  720. [(store (fshr GR64:$src2, (loadi64 addr:$dst), CL),
  721. addr:$dst)]>, TB;
  722. } // Uses, SchedRW
  723. let SchedRW = [WriteSHDmri] in {
  724. def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
  725. (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3),
  726. "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  727. [(store (X86fshl (loadi16 addr:$dst), GR16:$src2,
  728. (i8 imm:$src3)), addr:$dst)]>,
  729. TB, OpSize16;
  730. def SHRD16mri8 : Ii8<0xAC, MRMDestMem,
  731. (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3),
  732. "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  733. [(store (X86fshr GR16:$src2, (loadi16 addr:$dst),
  734. (i8 imm:$src3)), addr:$dst)]>,
  735. TB, OpSize16;
  736. def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
  737. (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3),
  738. "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  739. [(store (fshl (loadi32 addr:$dst), GR32:$src2,
  740. (i8 imm:$src3)), addr:$dst)]>,
  741. TB, OpSize32;
  742. def SHRD32mri8 : Ii8<0xAC, MRMDestMem,
  743. (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3),
  744. "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  745. [(store (fshr GR32:$src2, (loadi32 addr:$dst),
  746. (i8 imm:$src3)), addr:$dst)]>,
  747. TB, OpSize32;
  748. def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
  749. (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3),
  750. "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  751. [(store (fshl (loadi64 addr:$dst), GR64:$src2,
  752. (i8 imm:$src3)), addr:$dst)]>,
  753. TB;
  754. def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
  755. (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3),
  756. "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
  757. [(store (fshr GR64:$src2, (loadi64 addr:$dst),
  758. (i8 imm:$src3)), addr:$dst)]>,
  759. TB;
  760. } // SchedRW
  761. } // Defs = [EFLAGS]
  762. // Use the opposite rotate if allows us to use the rotate by 1 instruction.
  763. def : Pat<(rotl GR8:$src1, (i8 7)), (ROR8r1 GR8:$src1)>;
  764. def : Pat<(rotl GR16:$src1, (i8 15)), (ROR16r1 GR16:$src1)>;
  765. def : Pat<(rotl GR32:$src1, (i8 31)), (ROR32r1 GR32:$src1)>;
  766. def : Pat<(rotl GR64:$src1, (i8 63)), (ROR64r1 GR64:$src1)>;
  767. def : Pat<(rotr GR8:$src1, (i8 7)), (ROL8r1 GR8:$src1)>;
  768. def : Pat<(rotr GR16:$src1, (i8 15)), (ROL16r1 GR16:$src1)>;
  769. def : Pat<(rotr GR32:$src1, (i8 31)), (ROL32r1 GR32:$src1)>;
  770. def : Pat<(rotr GR64:$src1, (i8 63)), (ROL64r1 GR64:$src1)>;
  771. def : Pat<(store (rotl (loadi8 addr:$dst), (i8 7)), addr:$dst),
  772. (ROR8m1 addr:$dst)>;
  773. def : Pat<(store (rotl (loadi16 addr:$dst), (i8 15)), addr:$dst),
  774. (ROR16m1 addr:$dst)>;
  775. def : Pat<(store (rotl (loadi32 addr:$dst), (i8 31)), addr:$dst),
  776. (ROR32m1 addr:$dst)>;
  777. def : Pat<(store (rotl (loadi64 addr:$dst), (i8 63)), addr:$dst),
  778. (ROR64m1 addr:$dst)>, Requires<[In64BitMode]>;
  779. def : Pat<(store (rotr (loadi8 addr:$dst), (i8 7)), addr:$dst),
  780. (ROL8m1 addr:$dst)>;
  781. def : Pat<(store (rotr (loadi16 addr:$dst), (i8 15)), addr:$dst),
  782. (ROL16m1 addr:$dst)>;
  783. def : Pat<(store (rotr (loadi32 addr:$dst), (i8 31)), addr:$dst),
  784. (ROL32m1 addr:$dst)>;
  785. def : Pat<(store (rotr (loadi64 addr:$dst), (i8 63)), addr:$dst),
  786. (ROL64m1 addr:$dst)>, Requires<[In64BitMode]>;
  787. // Sandy Bridge and newer Intel processors support faster rotates using
  788. // SHLD to avoid a partial flag update on the normal rotate instructions.
  789. // Use a pseudo so that TwoInstructionPass and register allocation will see
  790. // this as unary instruction.
  791. let Predicates = [HasFastSHLDRotate], AddedComplexity = 5,
  792. Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteSHDrri],
  793. Constraints = "$src1 = $dst" in {
  794. def SHLDROT32ri : I<0, Pseudo, (outs GR32:$dst),
  795. (ins GR32:$src1, u8imm:$shamt), "",
  796. [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$shamt)))]>;
  797. def SHLDROT64ri : I<0, Pseudo, (outs GR64:$dst),
  798. (ins GR64:$src1, u8imm:$shamt), "",
  799. [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$shamt)))]>;
  800. def SHRDROT32ri : I<0, Pseudo, (outs GR32:$dst),
  801. (ins GR32:$src1, u8imm:$shamt), "",
  802. [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$shamt)))]>;
  803. def SHRDROT64ri : I<0, Pseudo, (outs GR64:$dst),
  804. (ins GR64:$src1, u8imm:$shamt), "",
  805. [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$shamt)))]>;
  806. }
  807. def ROT32L2R_imm8 : SDNodeXForm<imm, [{
  808. // Convert a ROTL shamt to a ROTR shamt on 32-bit integer.
  809. return getI8Imm(32 - N->getZExtValue(), SDLoc(N));
  810. }]>;
  811. def ROT64L2R_imm8 : SDNodeXForm<imm, [{
  812. // Convert a ROTL shamt to a ROTR shamt on 64-bit integer.
  813. return getI8Imm(64 - N->getZExtValue(), SDLoc(N));
  814. }]>;
  815. // NOTE: We use WriteShift for these rotates as they avoid the stalls
  816. // of many of the older x86 rotate instructions.
  817. multiclass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop> {
  818. let hasSideEffects = 0 in {
  819. def ri : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, u8imm:$src2),
  820. !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
  821. []>, TAXD, VEX, Sched<[WriteShift]>;
  822. let mayLoad = 1 in
  823. def mi : Ii8<0xF0, MRMSrcMem, (outs RC:$dst),
  824. (ins x86memop:$src1, u8imm:$src2),
  825. !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
  826. []>, TAXD, VEX, Sched<[WriteShiftLd]>;
  827. }
  828. }
  829. multiclass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop> {
  830. let hasSideEffects = 0 in {
  831. def rr : I<0xF7, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
  832. !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
  833. VEX, Sched<[WriteShift]>;
  834. let mayLoad = 1 in
  835. def rm : I<0xF7, MRMSrcMem4VOp3,
  836. (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
  837. !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
  838. VEX, Sched<[WriteShift.Folded,
  839. // x86memop:$src1
  840. ReadDefault, ReadDefault, ReadDefault, ReadDefault,
  841. ReadDefault,
  842. // RC:$src2
  843. WriteShift.ReadAfterFold]>;
  844. }
  845. }
  846. let Predicates = [HasBMI2] in {
  847. defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>;
  848. defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, VEX_W;
  849. defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8XS;
  850. defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8XS, VEX_W;
  851. defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8XD;
  852. defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8XD, VEX_W;
  853. defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8PD;
  854. defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8PD, VEX_W;
  855. // Prefer RORX which is non-destructive and doesn't update EFLAGS.
  856. let AddedComplexity = 10 in {
  857. def : Pat<(rotr GR32:$src, (i8 imm:$shamt)),
  858. (RORX32ri GR32:$src, imm:$shamt)>;
  859. def : Pat<(rotr GR64:$src, (i8 imm:$shamt)),
  860. (RORX64ri GR64:$src, imm:$shamt)>;
  861. def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),
  862. (RORX32ri GR32:$src, (ROT32L2R_imm8 imm:$shamt))>;
  863. def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),
  864. (RORX64ri GR64:$src, (ROT64L2R_imm8 imm:$shamt))>;
  865. }
  866. def : Pat<(rotr (loadi32 addr:$src), (i8 imm:$shamt)),
  867. (RORX32mi addr:$src, imm:$shamt)>;
  868. def : Pat<(rotr (loadi64 addr:$src), (i8 imm:$shamt)),
  869. (RORX64mi addr:$src, imm:$shamt)>;
  870. def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)),
  871. (RORX32mi addr:$src, (ROT32L2R_imm8 imm:$shamt))>;
  872. def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)),
  873. (RORX64mi addr:$src, (ROT64L2R_imm8 imm:$shamt))>;
  874. // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not
  875. // immediate shift, i.e. the following code is considered better
  876. //
  877. // mov %edi, %esi
  878. // shl $imm, %esi
  879. // ... %edi, ...
  880. //
  881. // than
  882. //
  883. // movb $imm, %sil
  884. // shlx %sil, %edi, %esi
  885. // ... %edi, ...
  886. //
  887. let AddedComplexity = 1 in {
  888. def : Pat<(sra GR32:$src1, GR8:$src2),
  889. (SARX32rr GR32:$src1,
  890. (INSERT_SUBREG
  891. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  892. def : Pat<(sra GR64:$src1, GR8:$src2),
  893. (SARX64rr GR64:$src1,
  894. (INSERT_SUBREG
  895. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  896. def : Pat<(srl GR32:$src1, GR8:$src2),
  897. (SHRX32rr GR32:$src1,
  898. (INSERT_SUBREG
  899. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  900. def : Pat<(srl GR64:$src1, GR8:$src2),
  901. (SHRX64rr GR64:$src1,
  902. (INSERT_SUBREG
  903. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  904. def : Pat<(shl GR32:$src1, GR8:$src2),
  905. (SHLX32rr GR32:$src1,
  906. (INSERT_SUBREG
  907. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  908. def : Pat<(shl GR64:$src1, GR8:$src2),
  909. (SHLX64rr GR64:$src1,
  910. (INSERT_SUBREG
  911. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  912. }
  913. // We prefer to use
  914. // mov (%ecx), %esi
  915. // shl $imm, $esi
  916. //
  917. // over
  918. //
  919. // movb $imm, %al
  920. // shlx %al, (%ecx), %esi
  921. //
  922. // This priority is enforced by IsProfitableToFoldLoad.
  923. def : Pat<(sra (loadi32 addr:$src1), GR8:$src2),
  924. (SARX32rm addr:$src1,
  925. (INSERT_SUBREG
  926. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  927. def : Pat<(sra (loadi64 addr:$src1), GR8:$src2),
  928. (SARX64rm addr:$src1,
  929. (INSERT_SUBREG
  930. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  931. def : Pat<(srl (loadi32 addr:$src1), GR8:$src2),
  932. (SHRX32rm addr:$src1,
  933. (INSERT_SUBREG
  934. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  935. def : Pat<(srl (loadi64 addr:$src1), GR8:$src2),
  936. (SHRX64rm addr:$src1,
  937. (INSERT_SUBREG
  938. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  939. def : Pat<(shl (loadi32 addr:$src1), GR8:$src2),
  940. (SHLX32rm addr:$src1,
  941. (INSERT_SUBREG
  942. (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  943. def : Pat<(shl (loadi64 addr:$src1), GR8:$src2),
  944. (SHLX64rm addr:$src1,
  945. (INSERT_SUBREG
  946. (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
  947. }
  948. def : Pat<(rotl GR8:$src1, (i8 relocImm:$src2)),
  949. (ROL8ri GR8:$src1, relocImm:$src2)>;
  950. def : Pat<(rotl GR16:$src1, (i8 relocImm:$src2)),
  951. (ROL16ri GR16:$src1, relocImm:$src2)>;
  952. def : Pat<(rotl GR32:$src1, (i8 relocImm:$src2)),
  953. (ROL32ri GR32:$src1, relocImm:$src2)>;
  954. def : Pat<(rotl GR64:$src1, (i8 relocImm:$src2)),
  955. (ROL64ri GR64:$src1, relocImm:$src2)>;
  956. def : Pat<(rotr GR8:$src1, (i8 relocImm:$src2)),
  957. (ROR8ri GR8:$src1, relocImm:$src2)>;
  958. def : Pat<(rotr GR16:$src1, (i8 relocImm:$src2)),
  959. (ROR16ri GR16:$src1, relocImm:$src2)>;
  960. def : Pat<(rotr GR32:$src1, (i8 relocImm:$src2)),
  961. (ROR32ri GR32:$src1, relocImm:$src2)>;
  962. def : Pat<(rotr GR64:$src1, (i8 relocImm:$src2)),
  963. (ROR64ri GR64:$src1, relocImm:$src2)>;