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