RISCVInstrInfoZb.td 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. //===-- RISCVInstrInfoZb.td - RISC-V Bitmanip instructions -*- 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 RISC-V instructions from the standard Bitmanip
  10. // extensions, versions:
  11. // Zba - 1.0
  12. // Zbb - 1.0
  13. // Zbc - 1.0
  14. // Zbs - 1.0
  15. //
  16. // The experimental extensions appeared in an earlier draft of the Bitmanip
  17. // extensions. They are not ratified and subject to change.
  18. //
  19. // This file also describes RISC-V instructions from the Zbk* extensions in
  20. // Cryptography Extensions Volume I: Scalar & Entropy Source Instructions,
  21. // versions:
  22. // Zbkb - 1.0
  23. // Zbkc - 1.0
  24. // Zbkx - 1.0
  25. //
  26. //===----------------------------------------------------------------------===//
  27. //===----------------------------------------------------------------------===//
  28. // Operand and SDNode transformation definitions.
  29. //===----------------------------------------------------------------------===//
  30. def riscv_clzw : SDNode<"RISCVISD::CLZW", SDT_RISCVIntUnaryOpW>;
  31. def riscv_ctzw : SDNode<"RISCVISD::CTZW", SDT_RISCVIntUnaryOpW>;
  32. def riscv_rolw : SDNode<"RISCVISD::ROLW", SDT_RISCVIntBinOpW>;
  33. def riscv_rorw : SDNode<"RISCVISD::RORW", SDT_RISCVIntBinOpW>;
  34. def riscv_brev8 : SDNode<"RISCVISD::BREV8", SDTIntUnaryOp>;
  35. def riscv_orc_b : SDNode<"RISCVISD::ORC_B", SDTIntUnaryOp>;
  36. def riscv_zip : SDNode<"RISCVISD::ZIP", SDTIntUnaryOp>;
  37. def riscv_unzip : SDNode<"RISCVISD::UNZIP", SDTIntUnaryOp>;
  38. def riscv_absw : SDNode<"RISCVISD::ABSW", SDTIntUnaryOp>;
  39. def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
  40. let Name = "UImmLog2XLenHalf";
  41. let RenderMethod = "addImmOperands";
  42. let DiagnosticType = "InvalidUImmLog2XLenHalf";
  43. }
  44. def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
  45. if (Subtarget->is64Bit())
  46. return isUInt<5>(Imm);
  47. return isUInt<4>(Imm);
  48. }]> {
  49. let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
  50. let DecoderMethod = "decodeUImmOperand<5>";
  51. let OperandType = "OPERAND_UIMM_SHFL";
  52. let OperandNamespace = "RISCVOp";
  53. let MCOperandPredicate = [{
  54. int64_t Imm;
  55. if (!MCOp.evaluateAsConstantImm(Imm))
  56. return false;
  57. if (STI.getTargetTriple().isArch64Bit())
  58. return isUInt<5>(Imm);
  59. return isUInt<4>(Imm);
  60. }];
  61. }
  62. def BCLRXForm : SDNodeXForm<imm, [{
  63. // Find the lowest 0.
  64. return CurDAG->getTargetConstant(countTrailingOnes(N->getZExtValue()),
  65. SDLoc(N), N->getValueType(0));
  66. }]>;
  67. def SingleBitSetMaskToIndex : SDNodeXForm<imm, [{
  68. // Find the lowest 1.
  69. return CurDAG->getTargetConstant(countTrailingZeros(N->getZExtValue()),
  70. SDLoc(N), N->getValueType(0));
  71. }]>;
  72. // Checks if this mask has a single 0 bit and cannot be used with ANDI.
  73. def BCLRMask : ImmLeaf<XLenVT, [{
  74. if (Subtarget->is64Bit())
  75. return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
  76. return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
  77. }], BCLRXForm>;
  78. // Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
  79. def SingleBitSetMask : ImmLeaf<XLenVT, [{
  80. if (Subtarget->is64Bit())
  81. return !isInt<12>(Imm) && isPowerOf2_64(Imm);
  82. return !isInt<12>(Imm) && isPowerOf2_32(Imm);
  83. }], SingleBitSetMaskToIndex>;
  84. // Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
  85. // in which i = (1 << i0) | (1 << i1).
  86. def BSETINVTwoBitsMask : PatLeaf<(imm), [{
  87. if (!N->hasOneUse())
  88. return false;
  89. // The immediate should not be a simm12.
  90. if (isInt<12>(N->getSExtValue()))
  91. return false;
  92. // The immediate must have exactly two bits set.
  93. return llvm::popcount(N->getZExtValue()) == 2;
  94. }]>;
  95. def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
  96. uint64_t I = N->getZExtValue();
  97. return CurDAG->getTargetConstant(63 - countLeadingZeros(I), SDLoc(N),
  98. N->getValueType(0));
  99. }]>;
  100. // Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
  101. // in which imm = i0 | (1 << i1).
  102. def BSETINVORIMask : PatLeaf<(imm), [{
  103. if (!N->hasOneUse())
  104. return false;
  105. // The immediate should not be a simm12.
  106. if (isInt<12>(N->getSExtValue()))
  107. return false;
  108. // There should be only one set bit from bit 11 to the top.
  109. return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
  110. }]>;
  111. def BSETINVORIMaskLow : SDNodeXForm<imm, [{
  112. return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
  113. SDLoc(N), N->getValueType(0));
  114. }]>;
  115. // Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
  116. // in which i = ~((1<<i0) | (1<<i1)).
  117. def BCLRITwoBitsMask : PatLeaf<(imm), [{
  118. if (!N->hasOneUse())
  119. return false;
  120. // The immediate should not be a simm12.
  121. if (isInt<12>(N->getSExtValue()))
  122. return false;
  123. // The immediate must have exactly two bits clear.
  124. return (unsigned)llvm::popcount(N->getZExtValue()) == Subtarget->getXLen() - 2;
  125. }]>;
  126. def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
  127. return CurDAG->getTargetConstant(countTrailingZeros(~N->getZExtValue()),
  128. SDLoc(N), N->getValueType(0));
  129. }]>;
  130. def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{
  131. uint64_t I = N->getSExtValue();
  132. if (!Subtarget->is64Bit())
  133. I |= 0xffffffffull << 32;
  134. return CurDAG->getTargetConstant(63 - countLeadingZeros(~I), SDLoc(N),
  135. N->getValueType(0));
  136. }]>;
  137. // Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
  138. // in which i = i0 & ~(1<<i1).
  139. def BCLRIANDIMask : PatLeaf<(imm), [{
  140. if (!N->hasOneUse())
  141. return false;
  142. // The immediate should not be a simm12.
  143. if (isInt<12>(N->getSExtValue()))
  144. return false;
  145. // There should be only one clear bit from bit 11 to the top.
  146. uint64_t I = N->getZExtValue() | 0x7ff;
  147. return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);
  148. }]>;
  149. def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
  150. return CurDAG->getTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
  151. SDLoc(N), N->getValueType(0));
  152. }]>;
  153. def C3LeftShift : PatLeaf<(imm), [{
  154. uint64_t C = N->getZExtValue();
  155. return C > 3 && ((C % 3) == 0) && isPowerOf2_64(C / 3);
  156. }]>;
  157. def C5LeftShift : PatLeaf<(imm), [{
  158. uint64_t C = N->getZExtValue();
  159. return C > 5 && ((C % 5) == 0) && isPowerOf2_64(C / 5);
  160. }]>;
  161. def C9LeftShift : PatLeaf<(imm), [{
  162. uint64_t C = N->getZExtValue();
  163. return C > 9 && ((C % 9) == 0) && isPowerOf2_64(C / 9);
  164. }]>;
  165. // Constant of the form (3 << C) where C is less than 32.
  166. def C3LeftShiftUW : PatLeaf<(imm), [{
  167. uint64_t C = N->getZExtValue();
  168. if (C <= 3 || (C % 3) != 0)
  169. return false;
  170. C /= 3;
  171. return isPowerOf2_64(C) && C < (1ULL << 32);
  172. }]>;
  173. // Constant of the form (5 << C) where C is less than 32.
  174. def C5LeftShiftUW : PatLeaf<(imm), [{
  175. uint64_t C = N->getZExtValue();
  176. if (C <= 5 || (C % 5) != 0)
  177. return false;
  178. C /= 5;
  179. return isPowerOf2_64(C) && C < (1ULL << 32);
  180. }]>;
  181. // Constant of the form (9 << C) where C is less than 32.
  182. def C9LeftShiftUW : PatLeaf<(imm), [{
  183. uint64_t C = N->getZExtValue();
  184. if (C <= 9 || (C % 9) != 0)
  185. return false;
  186. C /= 9;
  187. return isPowerOf2_64(C) && C < (1ULL << 32);
  188. }]>;
  189. def CSImm12MulBy4 : PatLeaf<(imm), [{
  190. if (!N->hasOneUse())
  191. return false;
  192. int64_t C = N->getSExtValue();
  193. // Skip if C is simm12, an lui, or can be optimized by the PatLeaf AddiPair.
  194. return !isInt<13>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 2>(C);
  195. }]>;
  196. def CSImm12MulBy8 : PatLeaf<(imm), [{
  197. if (!N->hasOneUse())
  198. return false;
  199. int64_t C = N->getSExtValue();
  200. // Skip if C is simm12, an lui or can be optimized by the PatLeaf AddiPair or
  201. // CSImm12MulBy4.
  202. return !isInt<14>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 3>(C);
  203. }]>;
  204. def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
  205. return CurDAG->getTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
  206. N->getValueType(0));
  207. }]>;
  208. def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
  209. return CurDAG->getTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
  210. N->getValueType(0));
  211. }]>;
  212. // Pattern to exclude simm12 immediates from matching.
  213. def non_imm12 : PatLeaf<(XLenVT GPR:$a), [{
  214. auto *C = dyn_cast<ConstantSDNode>(N);
  215. return !C || !isInt<12>(C->getSExtValue());
  216. }]>;
  217. def Shifted32OnesMask : PatLeaf<(imm), [{
  218. uint64_t Imm = N->getZExtValue();
  219. if (!isShiftedMask_64(Imm))
  220. return false;
  221. unsigned TrailingZeros = countTrailingZeros(Imm);
  222. return TrailingZeros > 0 && TrailingZeros < 32 &&
  223. Imm == UINT64_C(0xFFFFFFFF) << TrailingZeros;
  224. }], TrailingZeros>;
  225. def sh1add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<1>", [], [], 6>;
  226. def sh2add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<2>", [], [], 6>;
  227. def sh3add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<3>", [], [], 6>;
  228. def sh1add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<1>", [], [], 6>;
  229. def sh2add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<2>", [], [], 6>;
  230. def sh3add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<3>", [], [], 6>;
  231. //===----------------------------------------------------------------------===//
  232. // Instruction class templates
  233. //===----------------------------------------------------------------------===//
  234. // Some of these templates should be moved to RISCVInstrFormats.td once the B
  235. // extension has been ratified.
  236. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  237. class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
  238. RISCVOpcode opcode, string opcodestr>
  239. : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
  240. opcodestr, "$rd, $rs1"> {
  241. let rs2 = funct5;
  242. }
  243. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  244. class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
  245. string opcodestr>
  246. : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
  247. (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
  248. "$rd, $rs1, $shamt">;
  249. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  250. class RVBShiftW_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
  251. string opcodestr>
  252. : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
  253. (ins GPR:$rs1, uimm5:$shamt), opcodestr,
  254. "$rd, $rs1, $shamt">;
  255. // Using RVInstIShiftW since it allocates 5 bits instead of 6 to shamt.
  256. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  257. class RVBShfl_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
  258. string opcodestr>
  259. : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
  260. (ins GPR:$rs1, shfl_uimm:$shamt), opcodestr,
  261. "$rd, $rs1, $shamt">;
  262. let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
  263. class RVBTernaryR<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
  264. string opcodestr, string argstr>
  265. : RVInstR4<funct2, funct3, opcode, (outs GPR:$rd),
  266. (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr>;
  267. //===----------------------------------------------------------------------===//
  268. // Instructions
  269. //===----------------------------------------------------------------------===//
  270. let Predicates = [HasStdExtZbbOrZbkb] in {
  271. def ANDN : ALU_rr<0b0100000, 0b111, "andn">,
  272. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  273. def ORN : ALU_rr<0b0100000, 0b110, "orn">,
  274. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  275. def XNOR : ALU_rr<0b0100000, 0b100, "xnor">,
  276. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  277. } // Predicates = [HasStdExtZbbOrZbkb]
  278. let Predicates = [HasStdExtZba] in {
  279. def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
  280. Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
  281. def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
  282. Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
  283. def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
  284. Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
  285. } // Predicates = [HasStdExtZba]
  286. let Predicates = [HasStdExtZba, IsRV64] in {
  287. def SLLI_UW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
  288. Sched<[WriteShiftImm32, ReadShiftImm32]>;
  289. def ADD_UW : ALUW_rr<0b0000100, 0b000, "add.uw">,
  290. Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
  291. def SH1ADD_UW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
  292. Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
  293. def SH2ADD_UW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
  294. Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
  295. def SH3ADD_UW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
  296. Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
  297. } // Predicates = [HasStdExtZba, IsRV64]
  298. let Predicates = [HasStdExtZbbOrZbkb] in {
  299. def ROL : ALU_rr<0b0110000, 0b001, "rol">,
  300. Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
  301. def ROR : ALU_rr<0b0110000, 0b101, "ror">,
  302. Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
  303. def RORI : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
  304. Sched<[WriteRotateImm, ReadRotateImm]>;
  305. } // Predicates = [HasStdExtZbbOrZbkb]
  306. let Predicates = [HasStdExtZbbOrZbkb, IsRV64], IsSignExtendingOpW = 1 in {
  307. def ROLW : ALUW_rr<0b0110000, 0b001, "rolw">,
  308. Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
  309. def RORW : ALUW_rr<0b0110000, 0b101, "rorw">,
  310. Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
  311. def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
  312. Sched<[WriteRotateImm32, ReadRotateImm32]>;
  313. } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
  314. let Predicates = [HasStdExtZbs] in {
  315. def BCLR : ALU_rr<0b0100100, 0b001, "bclr">,
  316. Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
  317. def BSET : ALU_rr<0b0010100, 0b001, "bset">,
  318. Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
  319. def BINV : ALU_rr<0b0110100, 0b001, "binv">,
  320. Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
  321. let IsSignExtendingOpW = 1 in
  322. def BEXT : ALU_rr<0b0100100, 0b101, "bext">,
  323. Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
  324. def BCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "bclri">,
  325. Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
  326. def BSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "bseti">,
  327. Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
  328. def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">,
  329. Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
  330. let IsSignExtendingOpW = 1 in
  331. def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">,
  332. Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
  333. } // Predicates = [HasStdExtZbs]
  334. // These instructions were named xperm.n and xperm.b in the last version of
  335. // the draft bit manipulation specification they were included in. However, we
  336. // use the mnemonics given to them in the ratified Zbkx extension.
  337. let Predicates = [HasStdExtZbkx] in {
  338. def XPERM4 : ALU_rr<0b0010100, 0b010, "xperm4">,
  339. Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;
  340. def XPERM8 : ALU_rr<0b0010100, 0b100, "xperm8">,
  341. Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;
  342. } // Predicates = [HasStdExtZbkx]
  343. let Predicates = [HasStdExtZbb], IsSignExtendingOpW = 1 in {
  344. def CLZ : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM, "clz">,
  345. Sched<[WriteCLZ, ReadCLZ]>;
  346. def CTZ : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM, "ctz">,
  347. Sched<[WriteCTZ, ReadCTZ]>;
  348. def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM, "cpop">,
  349. Sched<[WriteCPOP, ReadCPOP]>;
  350. } // Predicates = [HasStdExtZbb]
  351. let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
  352. def CLZW : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM_32, "clzw">,
  353. Sched<[WriteCLZ32, ReadCLZ32]>;
  354. def CTZW : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM_32, "ctzw">,
  355. Sched<[WriteCTZ32, ReadCTZ32]>;
  356. def CPOPW : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM_32, "cpopw">,
  357. Sched<[WriteCPOP32, ReadCPOP32]>;
  358. } // Predicates = [HasStdExtZbb, IsRV64]
  359. let Predicates = [HasStdExtZbb], IsSignExtendingOpW = 1 in {
  360. def SEXT_B : RVBUnary<0b0110000, 0b00100, 0b001, OPC_OP_IMM, "sext.b">,
  361. Sched<[WriteIALU, ReadIALU]>;
  362. def SEXT_H : RVBUnary<0b0110000, 0b00101, 0b001, OPC_OP_IMM, "sext.h">,
  363. Sched<[WriteIALU, ReadIALU]>;
  364. } // Predicates = [HasStdExtZbb]
  365. let Predicates = [HasStdExtZbc] in {
  366. def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr", /*Commutable*/1>,
  367. Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
  368. } // Predicates = [HasStdExtZbc]
  369. let Predicates = [HasStdExtZbcOrZbkc] in {
  370. def CLMUL : ALU_rr<0b0000101, 0b001, "clmul", /*Commutable*/1>,
  371. Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
  372. def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh", /*Commutable*/1>,
  373. Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
  374. } // Predicates = [HasStdExtZbcOrZbkc]
  375. let Predicates = [HasStdExtZbb] in {
  376. def MIN : ALU_rr<0b0000101, 0b100, "min", /*Commutable*/1>,
  377. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  378. def MINU : ALU_rr<0b0000101, 0b101, "minu", /*Commutable*/1>,
  379. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  380. def MAX : ALU_rr<0b0000101, 0b110, "max", /*Commutable*/1>,
  381. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  382. def MAXU : ALU_rr<0b0000101, 0b111, "maxu", /*Commutable*/1>,
  383. Sched<[WriteIALU, ReadIALU, ReadIALU]>;
  384. } // Predicates = [HasStdExtZbb]
  385. let Predicates = [HasStdExtZbkb] in {
  386. def PACK : ALU_rr<0b0000100, 0b100, "pack">,
  387. Sched<[WritePACK, ReadPACK, ReadPACK]>;
  388. let IsSignExtendingOpW = 1 in
  389. def PACKH : ALU_rr<0b0000100, 0b111, "packh">,
  390. Sched<[WritePACK, ReadPACK, ReadPACK]>;
  391. } // Predicates = [HasStdExtZbkb]
  392. let Predicates = [HasStdExtZbkb, IsRV64], IsSignExtendingOpW = 1 in
  393. def PACKW : ALUW_rr<0b0000100, 0b100, "packw">,
  394. Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
  395. let Predicates = [HasStdExtZbb, IsRV32] in {
  396. def ZEXT_H_RV32 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP, "zext.h">,
  397. Sched<[WriteIALU, ReadIALU]>;
  398. } // Predicates = [HasStdExtZbb, IsRV32]
  399. let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
  400. def ZEXT_H_RV64 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP_32, "zext.h">,
  401. Sched<[WriteIALU, ReadIALU]>;
  402. } // Predicates = [HasStdExtZbb, IsRV64]
  403. let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
  404. def REV8_RV32 : RVBUnary<0b0110100, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
  405. Sched<[WriteREV8, ReadREV8]>;
  406. } // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
  407. let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
  408. def REV8_RV64 : RVBUnary<0b0110101, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
  409. Sched<[WriteREV8, ReadREV8]>;
  410. } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
  411. let Predicates = [HasStdExtZbb] in {
  412. def ORC_B : RVBUnary<0b0010100, 0b00111, 0b101, OPC_OP_IMM, "orc.b">,
  413. Sched<[WriteORCB, ReadORCB]>;
  414. } // Predicates = [HasStdExtZbb]
  415. let Predicates = [HasStdExtZbkb] in
  416. def BREV8 : RVBUnary<0b0110100, 0b00111, 0b101, OPC_OP_IMM, "brev8">,
  417. Sched<[WriteBREV8, ReadBREV8]>;
  418. let Predicates = [HasStdExtZbkb, IsRV32] in {
  419. def ZIP_RV32 : RVBUnary<0b0000100, 0b01111, 0b001, OPC_OP_IMM, "zip">,
  420. Sched<[WriteZIP, ReadZIP]>;
  421. def UNZIP_RV32 : RVBUnary<0b0000100, 0b01111, 0b101, OPC_OP_IMM, "unzip">,
  422. Sched<[WriteZIP, ReadZIP]>;
  423. } // Predicates = [HasStdExtZbkb, IsRV32]
  424. //===----------------------------------------------------------------------===//
  425. // Pseudo Instructions
  426. //===----------------------------------------------------------------------===//
  427. let Predicates = [HasStdExtZba, IsRV64] in {
  428. def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;
  429. } // Predicates = [HasStdExtZba, IsRV64]
  430. let Predicates = [HasStdExtZbb] in {
  431. def : InstAlias<"ror $rd, $rs1, $shamt",
  432. (RORI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
  433. } // Predicates = [HasStdExtZbb]
  434. let Predicates = [HasStdExtZbb, IsRV64] in {
  435. def : InstAlias<"rorw $rd, $rs1, $shamt",
  436. (RORIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
  437. } // Predicates = [HasStdExtZbb, IsRV64]
  438. let Predicates = [HasStdExtZbs] in {
  439. def : InstAlias<"bset $rd, $rs1, $shamt",
  440. (BSETI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
  441. def : InstAlias<"bclr $rd, $rs1, $shamt",
  442. (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
  443. def : InstAlias<"binv $rd, $rs1, $shamt",
  444. (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
  445. def : InstAlias<"bext $rd, $rs1, $shamt",
  446. (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
  447. } // Predicates = [HasStdExtZbs]
  448. //===----------------------------------------------------------------------===//
  449. // Codegen patterns
  450. //===----------------------------------------------------------------------===//
  451. let Predicates = [HasStdExtZbbOrZbkb] in {
  452. def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
  453. def : Pat<(or GPR:$rs1, (not GPR:$rs2)), (ORN GPR:$rs1, GPR:$rs2)>;
  454. def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
  455. } // Predicates = [HasStdExtZbbOrZbkb]
  456. let Predicates = [HasStdExtZbbOrZbkb] in {
  457. def : PatGprGpr<shiftop<rotl>, ROL>;
  458. def : PatGprGpr<shiftop<rotr>, ROR>;
  459. def : PatGprImm<rotr, RORI, uimmlog2xlen>;
  460. // There's no encoding for roli in the the 'B' extension as it can be
  461. // implemented with rori by negating the immediate.
  462. def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
  463. (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
  464. } // Predicates = [HasStdExtZbbOrZbkb]
  465. let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
  466. def : PatGprGpr<shiftopw<riscv_rolw>, ROLW>;
  467. def : PatGprGpr<shiftopw<riscv_rorw>, RORW>;
  468. def : PatGprImm<riscv_rorw, RORIW, uimm5>;
  469. def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
  470. (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
  471. } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
  472. let Predicates = [HasStdExtZbs] in {
  473. def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
  474. (BCLR GPR:$rs1, GPR:$rs2)>;
  475. def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (BCLR GPR:$rs1, GPR:$rs2)>;
  476. def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
  477. (BSET GPR:$rs1, GPR:$rs2)>;
  478. def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
  479. (BINV GPR:$rs1, GPR:$rs2)>;
  480. def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
  481. (BEXT GPR:$rs1, GPR:$rs2)>;
  482. def : Pat<(shiftop<shl> 1, GPR:$rs2),
  483. (BSET X0, GPR:$rs2)>;
  484. def : Pat<(and GPR:$rs1, BCLRMask:$mask),
  485. (BCLRI GPR:$rs1, BCLRMask:$mask)>;
  486. def : Pat<(or GPR:$rs1, SingleBitSetMask:$mask),
  487. (BSETI GPR:$rs1, SingleBitSetMask:$mask)>;
  488. def : Pat<(xor GPR:$rs1, SingleBitSetMask:$mask),
  489. (BINVI GPR:$rs1, SingleBitSetMask:$mask)>;
  490. def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
  491. (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
  492. def : Pat<(seteq (and GPR:$rs1, SingleBitSetMask:$mask), 0),
  493. (BEXTI (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>;
  494. def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
  495. (BSETI (BSETI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i)),
  496. (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
  497. def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
  498. (BINVI (BINVI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i)),
  499. (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
  500. def : Pat<(or GPR:$r, BSETINVORIMask:$i),
  501. (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
  502. (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
  503. def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
  504. (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
  505. (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
  506. def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
  507. (BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
  508. (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
  509. def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
  510. (BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
  511. (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
  512. } // Predicates = [HasStdExtZbs]
  513. let Predicates = [HasStdExtZbb] in {
  514. def : Pat<(riscv_orc_b GPR:$rs1), (ORC_B GPR:$rs1)>;
  515. } // Predicates = [HasStdExtZbb]
  516. let Predicates = [HasStdExtZbkb] in {
  517. def : Pat<(riscv_brev8 GPR:$rs1), (BREV8 GPR:$rs1)>;
  518. } // Predicates = [HasStdExtZbkb]
  519. let Predicates = [HasStdExtZbkb, IsRV32] in {
  520. // We treat zip and unzip as separate instructions, so match it directly.
  521. def : Pat<(i32 (riscv_zip GPR:$rs1)), (ZIP_RV32 GPR:$rs1)>;
  522. def : Pat<(i32 (riscv_unzip GPR:$rs1)), (UNZIP_RV32 GPR:$rs1)>;
  523. } // Predicates = [HasStdExtZbkb, IsRV32]
  524. let Predicates = [HasStdExtZbb] in {
  525. def : PatGpr<ctlz, CLZ>;
  526. def : PatGpr<cttz, CTZ>;
  527. def : PatGpr<ctpop, CPOP>;
  528. } // Predicates = [HasStdExtZbb]
  529. let Predicates = [HasStdExtZbb, IsRV64] in {
  530. def : PatGpr<riscv_clzw, CLZW>;
  531. def : PatGpr<riscv_ctzw, CTZW>;
  532. def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
  533. def : Pat<(i64 (riscv_absw GPR:$rs1)),
  534. (MAX GPR:$rs1, (SUBW X0, GPR:$rs1))>;
  535. } // Predicates = [HasStdExtZbb, IsRV64]
  536. let Predicates = [HasStdExtZbb] in {
  537. def : Pat<(sext_inreg GPR:$rs1, i8), (SEXT_B GPR:$rs1)>;
  538. def : Pat<(sext_inreg GPR:$rs1, i16), (SEXT_H GPR:$rs1)>;
  539. } // Predicates = [HasStdExtZbb]
  540. let Predicates = [HasStdExtZbb] in {
  541. def : PatGprGpr<smin, MIN>;
  542. def : PatGprGpr<smax, MAX>;
  543. def : PatGprGpr<umin, MINU>;
  544. def : PatGprGpr<umax, MAXU>;
  545. } // Predicates = [HasStdExtZbb]
  546. let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
  547. def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
  548. } // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
  549. let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
  550. def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
  551. } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
  552. let Predicates = [HasStdExtZbkb] in {
  553. def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
  554. (zexti8 GPR:$rs1)),
  555. (PACKH GPR:$rs1, GPR:$rs2)>;
  556. def : Pat<(or (shl (zexti8 GPR:$rs2), (XLenVT 8)),
  557. (zexti8 GPR:$rs1)),
  558. (PACKH GPR:$rs1, GPR:$rs2)>;
  559. def : Pat<(and (or (shl GPR:$rs2, (XLenVT 8)),
  560. (zexti8 GPR:$rs1)), 0xFFFF),
  561. (PACKH GPR:$rs1, GPR:$rs2)>;
  562. } // Predicates = [HasStdExtZbkb]
  563. let Predicates = [HasStdExtZbkb, IsRV32] in
  564. def : Pat<(i32 (or (zexti16 GPR:$rs1), (shl GPR:$rs2, (i32 16)))),
  565. (PACK GPR:$rs1, GPR:$rs2)>;
  566. let Predicates = [HasStdExtZbkb, IsRV64] in {
  567. def : Pat<(i64 (or (zexti32 GPR:$rs1), (shl GPR:$rs2, (i64 32)))),
  568. (PACK GPR:$rs1, GPR:$rs2)>;
  569. def : Pat<(binop_allwusers<or> (shl GPR:$rs2, (i64 16)),
  570. (zexti16 GPR:$rs1)),
  571. (PACKW GPR:$rs1, GPR:$rs2)>;
  572. def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
  573. (zexti16 GPR:$rs1))),
  574. (PACKW GPR:$rs1, GPR:$rs2)>;
  575. } // Predicates = [HasStdExtZbkb, IsRV64]
  576. let Predicates = [HasStdExtZbb, IsRV32] in
  577. def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
  578. let Predicates = [HasStdExtZbb, IsRV64] in
  579. def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
  580. let Predicates = [HasStdExtZba] in {
  581. def : Pat<(add (shl GPR:$rs1, (XLenVT 1)), non_imm12:$rs2),
  582. (SH1ADD GPR:$rs1, GPR:$rs2)>;
  583. def : Pat<(add (shl GPR:$rs1, (XLenVT 2)), non_imm12:$rs2),
  584. (SH2ADD GPR:$rs1, GPR:$rs2)>;
  585. def : Pat<(add (shl GPR:$rs1, (XLenVT 3)), non_imm12:$rs2),
  586. (SH3ADD GPR:$rs1, GPR:$rs2)>;
  587. // More complex cases use a ComplexPattern.
  588. def : Pat<(add sh1add_op:$rs1, non_imm12:$rs2),
  589. (SH1ADD sh1add_op:$rs1, GPR:$rs2)>;
  590. def : Pat<(add sh2add_op:$rs1, non_imm12:$rs2),
  591. (SH2ADD sh2add_op:$rs1, GPR:$rs2)>;
  592. def : Pat<(add sh3add_op:$rs1, non_imm12:$rs2),
  593. (SH3ADD sh3add_op:$rs1, GPR:$rs2)>;
  594. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
  595. (SH1ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  596. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
  597. (SH1ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  598. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
  599. (SH1ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  600. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
  601. (SH2ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  602. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
  603. (SH2ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  604. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
  605. (SH2ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  606. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
  607. (SH3ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  608. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
  609. (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  610. def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
  611. (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
  612. def : Pat<(add GPR:$r, CSImm12MulBy4:$i),
  613. (SH2ADD (ADDI X0, (SimmShiftRightBy2XForm CSImm12MulBy4:$i)),
  614. GPR:$r)>;
  615. def : Pat<(add GPR:$r, CSImm12MulBy8:$i),
  616. (SH3ADD (ADDI X0, (SimmShiftRightBy3XForm CSImm12MulBy8:$i)),
  617. GPR:$r)>;
  618. def : Pat<(mul GPR:$r, C3LeftShift:$i),
  619. (SLLI (SH1ADD GPR:$r, GPR:$r),
  620. (TrailingZeros C3LeftShift:$i))>;
  621. def : Pat<(mul GPR:$r, C5LeftShift:$i),
  622. (SLLI (SH2ADD GPR:$r, GPR:$r),
  623. (TrailingZeros C5LeftShift:$i))>;
  624. def : Pat<(mul GPR:$r, C9LeftShift:$i),
  625. (SLLI (SH3ADD GPR:$r, GPR:$r),
  626. (TrailingZeros C9LeftShift:$i))>;
  627. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
  628. (SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
  629. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
  630. (SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
  631. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
  632. (SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
  633. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
  634. (SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
  635. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
  636. (SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
  637. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
  638. (SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
  639. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
  640. (SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
  641. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
  642. (SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
  643. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
  644. (SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
  645. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
  646. (SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
  647. def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
  648. (SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
  649. } // Predicates = [HasStdExtZba]
  650. let Predicates = [HasStdExtZba, IsRV64] in {
  651. def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
  652. (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
  653. // Match a shifted 0xffffffff mask. Use SRLI to clear the LSBs and SLLI_UW to
  654. // mask and shift.
  655. def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),
  656. (SLLI_UW (SRLI GPR:$rs1, Shifted32OnesMask:$mask),
  657. Shifted32OnesMask:$mask)>;
  658. def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFF), non_imm12:$rs2)),
  659. (ADD_UW GPR:$rs1, GPR:$rs2)>;
  660. def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, X0)>;
  661. def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 1)), non_imm12:$rs2)),
  662. (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
  663. def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 2)), non_imm12:$rs2)),
  664. (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
  665. def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 3)), non_imm12:$rs2)),
  666. (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
  667. def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), non_imm12:$rs2)),
  668. (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
  669. def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), non_imm12:$rs2)),
  670. (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
  671. def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2)),
  672. (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
  673. // More complex cases use a ComplexPattern.
  674. def : Pat<(add sh1add_uw_op:$rs1, non_imm12:$rs2),
  675. (SH1ADD_UW sh1add_uw_op:$rs1, GPR:$rs2)>;
  676. def : Pat<(add sh2add_uw_op:$rs1, non_imm12:$rs2),
  677. (SH2ADD_UW sh2add_uw_op:$rs1, GPR:$rs2)>;
  678. def : Pat<(add sh3add_uw_op:$rs1, non_imm12:$rs2),
  679. (SH3ADD_UW sh3add_uw_op:$rs1, GPR:$rs2)>;
  680. def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFE), non_imm12:$rs2)),
  681. (SH1ADD (SRLIW GPR:$rs1, 1), GPR:$rs2)>;
  682. def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFC), non_imm12:$rs2)),
  683. (SH2ADD (SRLIW GPR:$rs1, 2), GPR:$rs2)>;
  684. def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFF8), non_imm12:$rs2)),
  685. (SH3ADD (SRLIW GPR:$rs1, 3), GPR:$rs2)>;
  686. // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
  687. def : Pat<(i64 (add (and GPR:$rs1, 0x1FFFFFFFE), non_imm12:$rs2)),
  688. (SH1ADD_UW (SRLI GPR:$rs1, 1), GPR:$rs2)>;
  689. def : Pat<(i64 (add (and GPR:$rs1, 0x3FFFFFFFC), non_imm12:$rs2)),
  690. (SH2ADD_UW (SRLI GPR:$rs1, 2), GPR:$rs2)>;
  691. def : Pat<(i64 (add (and GPR:$rs1, 0x7FFFFFFF8), non_imm12:$rs2)),
  692. (SH3ADD_UW (SRLI GPR:$rs1, 3), GPR:$rs2)>;
  693. def : Pat<(mul (binop_oneuse<and> GPR:$r, 0xFFFFFFFF), C3LeftShiftUW:$i),
  694. (SH1ADD (SLLI_UW GPR:$r, (TrailingZeros C3LeftShiftUW:$i)),
  695. (SLLI_UW GPR:$r, (TrailingZeros C3LeftShiftUW:$i)))>;
  696. def : Pat<(mul (binop_oneuse<and> GPR:$r, 0xFFFFFFFF), C5LeftShiftUW:$i),
  697. (SH2ADD (SLLI_UW GPR:$r, (TrailingZeros C5LeftShiftUW:$i)),
  698. (SLLI_UW GPR:$r, (TrailingZeros C5LeftShiftUW:$i)))>;
  699. def : Pat<(mul (binop_oneuse<and> GPR:$r, 0xFFFFFFFF), C9LeftShiftUW:$i),
  700. (SH3ADD (SLLI_UW GPR:$r, (TrailingZeros C9LeftShiftUW:$i)),
  701. (SLLI_UW GPR:$r, (TrailingZeros C9LeftShiftUW:$i)))>;
  702. } // Predicates = [HasStdExtZba, IsRV64]
  703. let Predicates = [HasStdExtZbcOrZbkc] in {
  704. def : PatGprGpr<int_riscv_clmul, CLMUL>;
  705. def : PatGprGpr<int_riscv_clmulh, CLMULH>;
  706. } // Predicates = [HasStdExtZbcOrZbkc]
  707. let Predicates = [HasStdExtZbc] in
  708. def : PatGprGpr<int_riscv_clmulr, CLMULR>;
  709. let Predicates = [HasStdExtZbkx] in {
  710. def : PatGprGpr<int_riscv_xperm4, XPERM4>;
  711. def : PatGprGpr<int_riscv_xperm8, XPERM8>;
  712. } // Predicates = [HasStdExtZbkx]