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