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