xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td (revision 5e801ac66d24704442eba426ed13c3effb8a34e7)
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//   Zbe - 0.93
16//   Zbf - 0.93
17//   Zbm - 0.93
18//   Zbp - 0.93
19//   Zbr - 0.93
20//   Zbt - 0.93
21// This version is still experimental as the Bitmanip extensions haven't been
22// ratified yet.
23//
24//===----------------------------------------------------------------------===//
25
26//===----------------------------------------------------------------------===//
27// Operand and SDNode transformation definitions.
28//===----------------------------------------------------------------------===//
29
30def riscv_clzw   : SDNode<"RISCVISD::CLZW",   SDT_RISCVIntUnaryOpW>;
31def riscv_ctzw   : SDNode<"RISCVISD::CTZW",   SDT_RISCVIntUnaryOpW>;
32def riscv_rolw   : SDNode<"RISCVISD::ROLW",   SDT_RISCVIntBinOpW>;
33def riscv_rorw   : SDNode<"RISCVISD::RORW",   SDT_RISCVIntBinOpW>;
34def riscv_fslw   : SDNode<"RISCVISD::FSLW",   SDT_RISCVIntShiftDOpW>;
35def riscv_fsrw   : SDNode<"RISCVISD::FSRW",   SDT_RISCVIntShiftDOpW>;
36def riscv_fsl    : SDNode<"RISCVISD::FSL",    SDTIntShiftDOp>;
37def riscv_fsr    : SDNode<"RISCVISD::FSR",    SDTIntShiftDOp>;
38def riscv_grev   : SDNode<"RISCVISD::GREV",   SDTIntBinOp>;
39def riscv_grevw  : SDNode<"RISCVISD::GREVW",  SDT_RISCVIntBinOpW>;
40def riscv_gorc   : SDNode<"RISCVISD::GORC",   SDTIntBinOp>;
41def riscv_gorcw  : SDNode<"RISCVISD::GORCW",  SDT_RISCVIntBinOpW>;
42def riscv_shfl   : SDNode<"RISCVISD::SHFL",   SDTIntBinOp>;
43def riscv_shflw  : SDNode<"RISCVISD::SHFLW",  SDT_RISCVIntBinOpW>;
44def riscv_unshfl : SDNode<"RISCVISD::UNSHFL", SDTIntBinOp>;
45def riscv_unshflw: SDNode<"RISCVISD::UNSHFLW",SDT_RISCVIntBinOpW>;
46def riscv_bcompress    : SDNode<"RISCVISD::BCOMPRESS",   SDTIntBinOp>;
47def riscv_bcompressw   : SDNode<"RISCVISD::BCOMPRESSW",  SDT_RISCVIntBinOpW>;
48def riscv_bdecompress  : SDNode<"RISCVISD::BDECOMPRESS", SDTIntBinOp>;
49def riscv_bdecompressw : SDNode<"RISCVISD::BDECOMPRESSW",SDT_RISCVIntBinOpW>;
50
51def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
52  let Name = "UImmLog2XLenHalf";
53  let RenderMethod = "addImmOperands";
54  let DiagnosticType = "InvalidUImmLog2XLenHalf";
55}
56
57def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
58  if (Subtarget->is64Bit())
59    return isUInt<5>(Imm);
60  return isUInt<4>(Imm);
61}]> {
62  let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
63  let DecoderMethod = "decodeUImmOperand<5>";
64  let MCOperandPredicate = [{
65    int64_t Imm;
66    if (!MCOp.evaluateAsConstantImm(Imm))
67      return false;
68    if (STI.getTargetTriple().isArch64Bit())
69      return  isUInt<5>(Imm);
70    return isUInt<4>(Imm);
71  }];
72}
73
74def BCLRXForm : SDNodeXForm<imm, [{
75  // Find the lowest 0.
76  return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
77                                   SDLoc(N), N->getValueType(0));
78}]>;
79
80def BSETINVXForm : SDNodeXForm<imm, [{
81  // Find the lowest 1.
82  return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
83                                   SDLoc(N), N->getValueType(0));
84}]>;
85
86// Checks if this mask has a single 0 bit and cannot be used with ANDI.
87def BCLRMask : ImmLeaf<XLenVT, [{
88  if (Subtarget->is64Bit())
89    return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
90  return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
91}], BCLRXForm>;
92
93// Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
94def BSETINVMask : ImmLeaf<XLenVT, [{
95  if (Subtarget->is64Bit())
96    return !isInt<12>(Imm) && isPowerOf2_64(Imm);
97  return !isInt<12>(Imm) && isPowerOf2_32(Imm);
98}], BSETINVXForm>;
99
100// Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
101// in which i = (1 << i0) | (1 << i1).
102def BSETINVTwoBitsMask : PatLeaf<(imm), [{
103  if (!N->hasOneUse())
104    return false;
105  // The immediate should not be a simm12.
106  if (isInt<12>(N->getSExtValue()))
107    return false;
108  // The immediate must have exactly two bits set.
109  return countPopulation(N->getZExtValue()) == 2;
110}]>;
111
112def TrailingZerosXForm : SDNodeXForm<imm, [{
113  uint64_t I = N->getZExtValue();
114  return CurDAG->getTargetConstant(countTrailingZeros(I), SDLoc(N),
115                                   N->getValueType(0));
116}]>;
117
118def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
119  uint64_t I = N->getZExtValue();
120  return CurDAG->getTargetConstant(63 - countLeadingZeros(I), SDLoc(N),
121                                   N->getValueType(0));
122}]>;
123
124// Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
125// in which imm = i0 | (1 << i1).
126def BSETINVORIMask : PatLeaf<(imm), [{
127  if (!N->hasOneUse())
128    return false;
129  // The immediate should not be a simm12.
130  if (isInt<12>(N->getSExtValue()))
131    return false;
132  // There should be only one set bit from bit 11 to the top.
133  return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
134}]>;
135
136def BSETINVORIMaskLow : SDNodeXForm<imm, [{
137  return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
138                                   SDLoc(N), N->getValueType(0));
139}]>;
140
141// Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
142// in which i = ~((1<<i0) | (1<<i1)).
143def BCLRITwoBitsMask : PatLeaf<(imm), [{
144  if (!N->hasOneUse())
145    return false;
146  // The immediate should not be a simm12.
147  if (isInt<12>(N->getSExtValue()))
148    return false;
149  // The immediate must have exactly two bits clear.
150  return countPopulation(N->getZExtValue()) == Subtarget->getXLen() - 2;
151}]>;
152
153def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
154  return CurDAG->getTargetConstant(countTrailingZeros(~N->getZExtValue()),
155                                   SDLoc(N), N->getValueType(0));
156}]>;
157
158def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{
159  uint64_t I = N->getSExtValue();
160  if (!Subtarget->is64Bit())
161    I |= 0xffffffffull << 32;
162  return CurDAG->getTargetConstant(63 - countLeadingZeros(~I), SDLoc(N),
163                                   N->getValueType(0));
164}]>;
165
166// Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
167// in which i = i0 & ~(1<<i1).
168def BCLRIANDIMask : PatLeaf<(imm), [{
169  if (!N->hasOneUse())
170    return false;
171  // The immediate should not be a simm12.
172  if (isInt<12>(N->getSExtValue()))
173    return false;
174  // There should be only one clear bit from bit 11 to the top.
175  uint64_t I = N->getZExtValue() | 0x7ff;
176  return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);
177}]>;
178
179def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
180  return CurDAG->getTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
181                                   SDLoc(N), N->getValueType(0));
182}]>;
183
184def C3LeftShift : PatLeaf<(imm), [{
185  uint64_t C = N->getZExtValue();
186  return C > 3 && ((C % 3) == 0) && isPowerOf2_64(C / 3);
187}]>;
188
189def C5LeftShift : PatLeaf<(imm), [{
190  uint64_t C = N->getZExtValue();
191  return C > 5 && ((C % 5) == 0) && isPowerOf2_64(C / 5);
192}]>;
193
194def C9LeftShift : PatLeaf<(imm), [{
195  uint64_t C = N->getZExtValue();
196  return C > 9 && ((C % 9) == 0) && isPowerOf2_64(C / 9);
197}]>;
198
199def CSImm12MulBy4 : PatLeaf<(imm), [{
200  if (!N->hasOneUse())
201    return false;
202  int64_t C = N->getSExtValue();
203  // Skip if C is simm12 or can be optimized by the PatLeaf AddiPair.
204  return !isInt<13>(C) && isInt<14>(C) && (C & 3) == 0;
205}]>;
206
207def CSImm12MulBy8 : PatLeaf<(imm), [{
208  if (!N->hasOneUse())
209    return false;
210  int64_t C = N->getSExtValue();
211  // Skip if C is simm12 or can be optimized by the PatLeaf AddiPair.
212  return !isInt<13>(C) && isInt<15>(C) && (C & 7) == 0;
213}]>;
214
215def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
216  return CurDAG->getTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
217                                   N->getValueType(0));
218}]>;
219
220def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
221  return CurDAG->getTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
222                                   N->getValueType(0));
223}]>;
224
225//===----------------------------------------------------------------------===//
226// Instruction class templates
227//===----------------------------------------------------------------------===//
228
229// Some of these templates should be moved to RISCVInstrFormats.td once the B
230// extension has been ratified.
231
232let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
233class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
234               RISCVOpcode opcode, string opcodestr>
235    : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
236              opcodestr, "$rd, $rs1"> {
237  let rs2 = funct5;
238}
239
240let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
241class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
242                  string opcodestr>
243    : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
244                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
245                   "$rd, $rs1, $shamt">;
246
247let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
248class RVBShiftW_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
249                   string opcodestr>
250    : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
251                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,
252                    "$rd, $rs1, $shamt">;
253
254// Using RVInstIShiftW since it allocates 5 bits instead of 6 to shamt.
255let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
256class RVBShfl_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
257                 string opcodestr>
258    : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
259                    (ins GPR:$rs1, shfl_uimm:$shamt), opcodestr,
260                    "$rd, $rs1, $shamt">;
261
262let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
263class RVBTernaryR<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
264                  string opcodestr, string argstr>
265    : RVInstR4<funct2, funct3, opcode, (outs GPR:$rd),
266               (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr>;
267
268// Currently used by FSRI only
269let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
270class RVBTernaryImm6<bits<3> funct3, RISCVOpcode opcode,
271                     string opcodestr, string argstr>
272    : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
273             opcodestr, argstr, [], InstFormatR4> {
274  bits<5> rs3;
275  bits<6> shamt;
276  bits<5> rs1;
277  bits<5> rd;
278
279  let Inst{31-27} = rs3;
280  let Inst{26} = 1;
281  let Inst{25-20} = shamt;
282  let Inst{19-15} = rs1;
283  let Inst{14-12} = funct3;
284  let Inst{11-7} = rd;
285  let Opcode = opcode.Value;
286}
287
288// Currently used by FSRIW only
289let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
290class RVBTernaryImm5<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
291                     string opcodestr, string argstr>
292    : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt),
293             opcodestr, argstr, [], InstFormatR4> {
294  bits<5> rs3;
295  bits<5> shamt;
296  bits<5> rs1;
297  bits<5> rd;
298
299  let Inst{31-27} = rs3;
300  let Inst{26-25} = funct2;
301  let Inst{24-20} = shamt;
302  let Inst{19-15} = rs1;
303  let Inst{14-12} = funct3;
304  let Inst{11-7} = rd;
305  let Opcode = opcode.Value;
306}
307
308//===----------------------------------------------------------------------===//
309// Instructions
310//===----------------------------------------------------------------------===//
311
312let Predicates = [HasStdExtZbbOrZbp] in {
313def ANDN  : ALU_rr<0b0100000, 0b111, "andn">,
314            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
315def ORN   : ALU_rr<0b0100000, 0b110, "orn">,
316            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
317def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">,
318            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
319} // Predicates = [HasStdExtZbbOrZbp]
320
321let Predicates = [HasStdExtZba] in {
322def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
323             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
324def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
325             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
326def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
327             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
328} // Predicates = [HasStdExtZba]
329
330let Predicates = [HasStdExtZbbOrZbp] in {
331def ROL   : ALU_rr<0b0110000, 0b001, "rol">,
332            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
333def ROR   : ALU_rr<0b0110000, 0b101, "ror">,
334            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
335} // Predicates = [HasStdExtZbbOrZbp]
336
337let Predicates = [HasStdExtZbs] in {
338def BCLR : ALU_rr<0b0100100, 0b001, "bclr">, Sched<[]>;
339def BSET : ALU_rr<0b0010100, 0b001, "bset">, Sched<[]>;
340def BINV : ALU_rr<0b0110100, 0b001, "binv">, Sched<[]>;
341def BEXT : ALU_rr<0b0100100, 0b101, "bext">, Sched<[]>;
342} // Predicates = [HasStdExtZbs]
343
344let Predicates = [HasStdExtZbp] in {
345def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
346def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
347} // Predicates = [HasStdExtZbp]
348
349let Predicates = [HasStdExtZbp] in {
350def XPERMN : ALU_rr<0b0010100, 0b010, "xperm.n">, Sched<[]>;
351def XPERMB : ALU_rr<0b0010100, 0b100, "xperm.b">, Sched<[]>;
352def XPERMH : ALU_rr<0b0010100, 0b110, "xperm.h">, Sched<[]>;
353} // Predicates = [HasStdExtZbp]
354
355let Predicates = [HasStdExtZbbOrZbp] in
356def RORI  : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
357            Sched<[WriteRotateImm, ReadRotateImm]>;
358
359let Predicates = [HasStdExtZbs] in {
360def BCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "bclri">, Sched<[]>;
361def BSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "bseti">, Sched<[]>;
362def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">, Sched<[]>;
363def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">, Sched<[]>;
364} // Predicates = [HasStdExtZbs]
365
366let Predicates = [HasStdExtZbp] in {
367def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
368def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
369} // Predicates = [HasStdExtZbp]
370
371let Predicates = [HasStdExtZbt] in {
372def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
373           Sched<[]>;
374def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
375           Sched<[]>;
376def FSL  : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
377           Sched<[]>;
378def FSR  : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
379           Sched<[]>;
380def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
381                          "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
382} // Predicates = [HasStdExtZbt]
383
384let Predicates = [HasStdExtZbb] in {
385def CLZ  : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">,
386           Sched<[WriteCLZ, ReadCLZ]>;
387def CTZ  : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0010011>, "ctz">,
388           Sched<[WriteCTZ, ReadCTZ]>;
389def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "cpop">,
390           Sched<[WriteCPOP, ReadCPOP]>;
391} // Predicates = [HasStdExtZbb]
392
393let Predicates = [HasStdExtZbm, IsRV64] in
394def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>,
395                        "bmatflip">, Sched<[]>;
396
397let Predicates = [HasStdExtZbb] in {
398def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>,
399                     "sext.b">, Sched<[WriteIALU, ReadIALU]>;
400def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>,
401                     "sext.h">, Sched<[WriteIALU, ReadIALU]>;
402} // Predicates = [HasStdExtZbb]
403
404let Predicates = [HasStdExtZbr] in {
405def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>,
406                      "crc32.b">, Sched<[]>;
407def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>,
408                      "crc32.h">, Sched<[]>;
409def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>,
410                      "crc32.w">, Sched<[]>;
411} // Predicates = [HasStdExtZbr]
412
413let Predicates = [HasStdExtZbr, IsRV64] in
414def CRC32D  : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>,
415                       "crc32.d">, Sched<[]>;
416
417let Predicates = [HasStdExtZbr] in {
418def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>,
419                       "crc32c.b">, Sched<[]>;
420def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>,
421                       "crc32c.h">, Sched<[]>;
422def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>,
423                       "crc32c.w">, Sched<[]>;
424} // Predicates = [HasStdExtZbr]
425
426let Predicates = [HasStdExtZbr, IsRV64] in
427def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>,
428                       "crc32c.d">, Sched<[]>;
429
430let Predicates = [HasStdExtZbc] in {
431def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>;
432def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>;
433def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[]>;
434} // Predicates = [HasStdExtZbc]
435
436let Predicates = [HasStdExtZbb] in {
437def MIN  : ALU_rr<0b0000101, 0b100, "min">,
438           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
439def MINU : ALU_rr<0b0000101, 0b101, "minu">,
440           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
441def MAX  : ALU_rr<0b0000101, 0b110, "max">,
442           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
443def MAXU : ALU_rr<0b0000101, 0b111, "maxu">,
444           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
445} // Predicates = [HasStdExtZbb]
446
447let Predicates = [HasStdExtZbp] in {
448def SHFL   : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
449def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
450} // Predicates = [HasStdExtZbp]
451
452let Predicates = [HasStdExtZbe] in {
453// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
454// bext in the 0.93 spec.
455def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">, Sched<[]>;
456def BCOMPRESS   : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>;
457} // Predicates = [HasStdExtZbe]
458
459let Predicates = [HasStdExtZbp] in {
460def PACK  : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
461def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
462def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
463} // Predicates = [HasStdExtZbp]
464
465let Predicates = [HasStdExtZbm, IsRV64] in {
466def BMATOR   : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
467def BMATXOR  : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
468} // Predicates = [HasStdExtZbm, IsRV64]
469
470let Predicates = [HasStdExtZbf] in
471def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
472
473let Predicates = [HasStdExtZbp] in {
474def SHFLI   : RVBShfl_ri<0b0000100, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
475def UNSHFLI : RVBShfl_ri<0b0000100, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
476} // Predicates = [HasStdExtZbp]
477
478let Predicates = [HasStdExtZba, IsRV64] in {
479def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
480             Sched<[WriteShiftImm32, ReadShiftImm32]>;
481def ADDUW : ALUW_rr<0b0000100, 0b000, "add.uw">,
482            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
483def SH1ADDUW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
484               Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
485def SH2ADDUW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
486               Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
487def SH3ADDUW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
488               Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
489} // Predicates = [HasStdExtZbb, IsRV64]
490
491let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
492def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">,
493            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
494def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">,
495            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
496} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
497
498let Predicates = [HasStdExtZbp, IsRV64] in {
499def GORCW  : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
500def GREVW  : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
501} // Predicates = [HasStdExtZbp, IsRV64]
502
503let Predicates = [HasStdExtZbp, IsRV64] in {
504def XPERMW : ALU_rr<0b0010100, 0b000, "xperm.w">, Sched<[]>;
505} // Predicates = [HasStdExtZbp, IsRV64]
506
507let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
508def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
509            Sched<[WriteRotateImm32, ReadRotateImm32]>;
510
511let Predicates = [HasStdExtZbp, IsRV64] in {
512def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
513def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
514} // Predicates = [HasStdExtZbp, IsRV64]
515
516let Predicates = [HasStdExtZbt, IsRV64] in {
517def FSLW  : RVBTernaryR<0b10, 0b001, OPC_OP_32,
518                        "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
519def FSRW  : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
520                        "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
521def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
522                           "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
523} // Predicates = [HasStdExtZbt, IsRV64]
524
525let Predicates = [HasStdExtZbb, IsRV64] in {
526def CLZW   : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>,
527                      "clzw">, Sched<[WriteCLZ32, ReadCLZ32]>;
528def CTZW   : RVBUnary<0b0110000, 0b00001, 0b001, RISCVOpcode<0b0011011>,
529                      "ctzw">, Sched<[WriteCTZ32, ReadCTZ32]>;
530def CPOPW  : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>,
531                      "cpopw">, Sched<[WriteCPOP32, ReadCPOP32]>;
532} // Predicates = [HasStdExtZbb, IsRV64]
533
534let Predicates = [HasStdExtZbp, IsRV64] in {
535def SHFLW   : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
536def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
537} // Predicates = [HasStdExtZbp, IsRV64]
538
539let Predicates = [HasStdExtZbe, IsRV64] in {
540// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
541// bextw in the 0.93 spec.
542def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">, Sched<[]>;
543def BCOMPRESSW   : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>;
544} // Predicates = [HasStdExtZbe, IsRV64]
545
546let Predicates = [HasStdExtZbp, IsRV64] in {
547def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
548def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
549} // Predicates = [HasStdExtZbp, IsRV64]
550
551let Predicates = [HasStdExtZbf, IsRV64] in
552def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
553
554let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
555let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
556def ZEXTH_RV32 : RVInstR<0b0000100, 0b100, OPC_OP, (outs GPR:$rd),
557                         (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
558                 Sched<[WriteIALU, ReadIALU]> {
559  let rs2 = 0b00000;
560}
561} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
562
563let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
564let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
565def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd),
566                         (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
567                 Sched<[WriteIALU, ReadIALU]> {
568  let rs2 = 0b00000;
569}
570} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
571
572// We treat rev8 and orc.b as standalone instructions even though they use a
573// portion of the encodings for grevi and gorci. This allows us to support only
574// those encodings when only Zbb is enabled. We do this even when grevi and
575// gorci are available with Zbp. Trying to use 'HasStdExtZbb, NotHasStdExtZbp'
576// causes diagnostics to suggest that Zbp rather than Zbb is required for rev8
577// or gorci. Since Zbb is closer to being finalized than Zbp this will be
578// misleading to users.
579let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
580let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
581def REV8_RV32 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
582                        "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
583  let imm12 = { 0b01101, 0b0011000 };
584}
585} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
586
587let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
588let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
589def REV8_RV64 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
590                        "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
591  let imm12 = { 0b01101, 0b0111000 };
592}
593} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
594
595let Predicates = [HasStdExtZbbOrZbp] in {
596let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
597def ORCB : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
598                   "orc.b", "$rd, $rs1">, Sched<[WriteORCB, ReadORCB]> {
599  let imm12 = { 0b00101, 0b0000111 };
600}
601} // Predicates = [HasStdExtZbbOrZbp]
602
603//===----------------------------------------------------------------------===//
604// Pseudo Instructions
605//===----------------------------------------------------------------------===//
606
607let Predicates = [HasStdExtZba, IsRV64] in {
608def : InstAlias<"zext.w $rd, $rs", (ADDUW GPR:$rd, GPR:$rs, X0)>;
609}
610
611let Predicates = [HasStdExtZbp] in {
612def : InstAlias<"rev.p $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
613def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
614def : InstAlias<"rev.n $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
615def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
616def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
617def : InstAlias<"rev.b $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00111)>;
618def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
619def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
620def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
621def : InstAlias<"rev.h $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
622
623def : InstAlias<"zip.n $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0001)>;
624def : InstAlias<"unzip.n $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
625def : InstAlias<"zip2.b $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0010)>;
626def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
627def : InstAlias<"zip.b $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0011)>;
628def : InstAlias<"unzip.b $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
629def : InstAlias<"zip4.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0100)>;
630def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
631def : InstAlias<"zip2.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0110)>;
632def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
633def : InstAlias<"zip.h $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0111)>;
634def : InstAlias<"unzip.h $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
635
636def : InstAlias<"orc.p $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
637def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
638def : InstAlias<"orc.n $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
639def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
640def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
641// orc.b is considered an instruction rather than an alias.
642def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
643def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
644def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
645def : InstAlias<"orc.h $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
646} // Predicates = [HasStdExtZbp]
647
648let Predicates = [HasStdExtZbp, IsRV32] in {
649def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
650// rev8 is considered an instruction rather than an alias.
651def : InstAlias<"rev4 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
652def : InstAlias<"rev2 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
653def : InstAlias<"rev $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
654
655def : InstAlias<"zip8 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1000)>;
656def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
657def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>;
658def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
659def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>;
660def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
661def : InstAlias<"zip $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b1111)>;
662def : InstAlias<"unzip $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>;
663
664def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
665def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
666def : InstAlias<"orc4 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
667def : InstAlias<"orc2 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
668def : InstAlias<"orc $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
669} // Predicates = [HasStdExtZbp, IsRV32]
670
671let Predicates = [HasStdExtZbp, IsRV64] in {
672def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
673def : InstAlias<"rev8.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
674def : InstAlias<"rev4.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
675def : InstAlias<"rev2.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
676def : InstAlias<"rev.w $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
677def : InstAlias<"rev32 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
678def : InstAlias<"rev16 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
679// rev8 is considered an instruction rather than an alias.
680def : InstAlias<"rev4 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
681def : InstAlias<"rev2 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
682def : InstAlias<"rev $rd, $rs",     (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
683
684def : InstAlias<"zip8.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01000)>;
685def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
686def : InstAlias<"zip4.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01100)>;
687def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
688def : InstAlias<"zip2.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01110)>;
689def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
690def : InstAlias<"zip.w $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b01111)>;
691def : InstAlias<"unzip.w $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
692def : InstAlias<"zip16 $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b10000)>;
693def : InstAlias<"unzip16 $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
694def : InstAlias<"zip8 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11000)>;
695def : InstAlias<"unzip8 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
696def : InstAlias<"zip4 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11100)>;
697def : InstAlias<"unzip4 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
698def : InstAlias<"zip2 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11110)>;
699def : InstAlias<"unzip2 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
700def : InstAlias<"zip $rd, $rs",      (SHFLI   GPR:$rd, GPR:$rs, 0b11111)>;
701def : InstAlias<"unzip $rd, $rs",    (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
702
703def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
704def : InstAlias<"orc8.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
705def : InstAlias<"orc4.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
706def : InstAlias<"orc2.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
707def : InstAlias<"orc.w $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
708def : InstAlias<"orc32 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
709def : InstAlias<"orc16 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
710def : InstAlias<"orc8 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
711def : InstAlias<"orc4 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
712def : InstAlias<"orc2 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
713def : InstAlias<"orc $rd, $rs",     (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
714} // Predicates = [HasStdExtZbp, IsRV64]
715
716let Predicates = [HasStdExtZbbOrZbp] in {
717def : InstAlias<"ror $rd, $rs1, $shamt",
718                (RORI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
719} // Predicates = [HasStdExtZbbOrZbp]
720
721let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
722def : InstAlias<"rorw $rd, $rs1, $shamt",
723                (RORIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
724} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
725
726let Predicates = [HasStdExtZbp] in {
727def : InstAlias<"grev $rd, $rs1, $shamt",
728                (GREVI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
729def : InstAlias<"gorc $rd, $rs1, $shamt",
730                (GORCI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
731def : InstAlias<"shfl $rd, $rs1, $shamt",
732                (SHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
733def : InstAlias<"unshfl $rd, $rs1, $shamt",
734                (UNSHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
735} // Predicates = [HasStdExtZbp]
736
737let Predicates = [HasStdExtZbp, IsRV64] in {
738def : InstAlias<"grevw $rd, $rs1, $shamt",
739                (GREVIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
740def : InstAlias<"gorcw $rd, $rs1, $shamt",
741                (GORCIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
742} // Predicates = [HasStdExtZbp, IsRV64]
743
744let Predicates = [HasStdExtZbs] in {
745def : InstAlias<"bset $rd, $rs1, $shamt",
746                (BSETI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
747def : InstAlias<"bclr $rd, $rs1, $shamt",
748                (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
749def : InstAlias<"binv $rd, $rs1, $shamt",
750                (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
751def : InstAlias<"bext $rd, $rs1, $shamt",
752                (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
753} // Predicates = [HasStdExtZbs]
754
755//===----------------------------------------------------------------------===//
756// Codegen patterns
757//===----------------------------------------------------------------------===//
758
759let Predicates = [HasStdExtZbbOrZbp] in {
760def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
761def : Pat<(or  GPR:$rs1, (not GPR:$rs2)), (ORN  GPR:$rs1, GPR:$rs2)>;
762def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
763} // Predicates = [HasStdExtZbbOrZbp]
764
765let Predicates = [HasStdExtZbbOrZbp] in {
766def : PatGprGpr<rotl, ROL>;
767def : PatGprGpr<rotr, ROR>;
768} // Predicates = [HasStdExtZbbOrZbp]
769
770let Predicates = [HasStdExtZbs] in {
771def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
772          (BCLR GPR:$rs1, GPR:$rs2)>;
773def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (BCLR GPR:$rs1, GPR:$rs2)>;
774def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
775          (BSET GPR:$rs1, GPR:$rs2)>;
776def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
777          (BINV GPR:$rs1, GPR:$rs2)>;
778def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
779          (BEXT GPR:$rs1, GPR:$rs2)>;
780
781def : Pat<(shiftop<shl> 1, GPR:$rs2),
782          (BSET X0, GPR:$rs2)>;
783
784def : Pat<(and GPR:$rs1, BCLRMask:$mask),
785          (BCLRI GPR:$rs1, BCLRMask:$mask)>;
786def : Pat<(or GPR:$rs1, BSETINVMask:$mask),
787          (BSETI GPR:$rs1, BSETINVMask:$mask)>;
788def : Pat<(xor GPR:$rs1, BSETINVMask:$mask),
789          (BINVI GPR:$rs1, BSETINVMask:$mask)>;
790
791def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
792          (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
793
794def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
795          (BSETI (BSETI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
796                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
797def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
798          (BINVI (BINVI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
799                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
800def : Pat<(or GPR:$r, BSETINVORIMask:$i),
801          (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
802                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
803def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
804          (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
805                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
806def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
807          (BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
808                 (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
809def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
810          (BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
811                 (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
812}
813
814// There's no encoding for roli in the the 'B' extension as it can be
815// implemented with rori by negating the immediate.
816let Predicates = [HasStdExtZbbOrZbp] in {
817def : PatGprImm<rotr, RORI, uimmlog2xlen>;
818def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
819          (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
820
821// We treat orc.b as a separate instruction, so match it directly. We also
822// lower the Zbb orc.b intrinsic to this.
823def : Pat<(riscv_gorc GPR:$rs1, 7), (ORCB GPR:$rs1)>;
824}
825
826let Predicates = [HasStdExtZbp] in {
827def : PatGprGpr<riscv_grev, GREV>;
828def : PatGprGpr<riscv_gorc, GORC>;
829def : PatGprGpr<riscv_shfl, SHFL>;
830def : PatGprGpr<riscv_unshfl, UNSHFL>;
831def : PatGprGpr<int_riscv_xperm_n, XPERMN>;
832def : PatGprGpr<int_riscv_xperm_b, XPERMB>;
833def : PatGprGpr<int_riscv_xperm_h, XPERMH>;
834def : PatGprGpr<int_riscv_xperm_w, XPERMW>;
835def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
836def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
837def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
838def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
839} // Predicates = [HasStdExtZbp]
840
841let Predicates = [HasStdExtZbp, IsRV32] in {
842def : Pat<(i32 (rotr (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
843def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
844
845// We treat rev8 as a separate instruction, so match it directly.
846def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
847} // Predicates = [HasStdExtZbp, IsRV32]
848
849let Predicates = [HasStdExtZbp, IsRV64] in {
850// We treat rev8 as a separate instruction, so match it directly.
851def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
852} // Predicates = [HasStdExtZbp, IsRV64]
853
854let Predicates = [HasStdExtZbt] in {
855def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
856          (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
857
858def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
859          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
860def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
861          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
862def : Pat<(select (XLenVT (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, GPR:$rs3),
863          (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
864def : Pat<(select (XLenVT (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs3, GPR:$rs1),
865          (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
866def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3),
867          (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
868def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
869          (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
870def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
871          (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
872def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
873          (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
874def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
875          (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
876def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
877          (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
878def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
879          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
880} // Predicates = [HasStdExtZbt]
881
882// fshl and fshr concatenate their operands in the same order. fsr and fsl
883// instruction use different orders. fshl will return its first operand for
884// shift of zero, fshr will return its second operand. fsl and fsr both return
885// $rs1 so the patterns need to have different operand orders.
886let Predicates = [HasStdExtZbt] in {
887def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
888          (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
889def : Pat<(riscv_fsr GPR:$rs3, GPR:$rs1, GPR:$rs2),
890          (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
891
892def : Pat<(fshr GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
893          (FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
894// We can use FSRI for fshl by immediate if we subtract the immediate from
895// XLen and swap the operands.
896def : Pat<(fshl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
897          (FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
898} // Predicates = [HasStdExtZbt]
899
900let Predicates = [HasStdExtZbb] in {
901def : PatGpr<ctlz, CLZ>;
902def : PatGpr<cttz, CTZ>;
903def : PatGpr<ctpop, CPOP>;
904} // Predicates = [HasStdExtZbb]
905
906let Predicates = [HasStdExtZbb] in {
907def : Pat<(sext_inreg GPR:$rs1, i8), (SEXTB GPR:$rs1)>;
908def : Pat<(sext_inreg GPR:$rs1, i16), (SEXTH GPR:$rs1)>;
909}
910
911let Predicates = [HasStdExtZbb] in {
912def : PatGprGpr<smin, MIN>;
913def : PatGprGpr<smax, MAX>;
914def : PatGprGpr<umin, MINU>;
915def : PatGprGpr<umax, MAXU>;
916} // Predicates = [HasStdExtZbb]
917
918let Predicates = [HasStdExtZbb, IsRV32] in {
919def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
920} // Predicates = [HasStdExtZbb, IsRV32]
921
922let Predicates = [HasStdExtZbb, IsRV64] in {
923def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
924} // Predicates = [HasStdExtZbb, IsRV64]
925
926let Predicates = [HasStdExtZbp, IsRV32] in {
927def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
928          (PACK GPR:$rs1, GPR:$rs2)>;
929def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
930          (PACKU GPR:$rs1, GPR:$rs2)>;
931
932}
933let Predicates = [HasStdExtZbp, IsRV64] in {
934def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
935          (PACK GPR:$rs1, GPR:$rs2)>;
936def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
937          (PACKU GPR:$rs1, GPR:$rs2)>;
938}
939let Predicates = [HasStdExtZbp] in
940def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
941              (and GPR:$rs1, 0x00FF)),
942          (PACKH GPR:$rs1, GPR:$rs2)>;
943
944let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
945def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>;
946let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
947def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV64 GPR:$rs)>;
948
949// Pattern to exclude simm12 immediates from matching.
950def non_imm12 : PatLeaf<(XLenVT GPR:$a), [{
951  auto *C = dyn_cast<ConstantSDNode>(N);
952  return !C || !isInt<12>(C->getSExtValue());
953}]>;
954
955let Predicates = [HasStdExtZba] in {
956def : Pat<(add (shl GPR:$rs1, (XLenVT 1)), non_imm12:$rs2),
957          (SH1ADD GPR:$rs1, GPR:$rs2)>;
958def : Pat<(add (shl GPR:$rs1, (XLenVT 2)), non_imm12:$rs2),
959          (SH2ADD GPR:$rs1, GPR:$rs2)>;
960def : Pat<(add (shl GPR:$rs1, (XLenVT 3)), non_imm12:$rs2),
961          (SH3ADD GPR:$rs1, GPR:$rs2)>;
962
963def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
964          (SH1ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
965def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
966          (SH1ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
967def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
968          (SH1ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
969def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
970          (SH2ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
971def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
972          (SH2ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
973def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
974          (SH2ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
975def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
976          (SH3ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
977def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
978          (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
979def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
980          (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
981
982def : Pat<(add GPR:$r, CSImm12MulBy4:$i),
983          (SH2ADD (ADDI X0, (SimmShiftRightBy2XForm CSImm12MulBy4:$i)),
984                  GPR:$r)>;
985def : Pat<(add GPR:$r, CSImm12MulBy8:$i),
986          (SH3ADD (ADDI X0, (SimmShiftRightBy3XForm CSImm12MulBy8:$i)),
987                  GPR:$r)>;
988
989def : Pat<(mul GPR:$r, C3LeftShift:$i),
990          (SLLI (SH1ADD GPR:$r, GPR:$r),
991                (TrailingZerosXForm C3LeftShift:$i))>;
992def : Pat<(mul GPR:$r, C5LeftShift:$i),
993          (SLLI (SH2ADD GPR:$r, GPR:$r),
994                (TrailingZerosXForm C5LeftShift:$i))>;
995def : Pat<(mul GPR:$r, C9LeftShift:$i),
996          (SLLI (SH3ADD GPR:$r, GPR:$r),
997                (TrailingZerosXForm C9LeftShift:$i))>;
998
999def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
1000          (SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1001def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
1002          (SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1003def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
1004          (SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1005def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
1006          (SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1007def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
1008          (SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1009def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
1010          (SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1011def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
1012          (SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1013def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
1014          (SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1015def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
1016          (SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1017def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
1018          (SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1019def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
1020          (SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1021} // Predicates = [HasStdExtZba]
1022
1023let Predicates = [HasStdExtZba, IsRV64] in {
1024def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
1025          (SLLIUW GPR:$rs1, uimm5:$shamt)>;
1026def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFF), non_imm12:$rs2)),
1027          (ADDUW GPR:$rs1, GPR:$rs2)>;
1028def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADDUW GPR:$rs, X0)>;
1029
1030def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 1)), non_imm12:$rs2)),
1031          (SH1ADDUW GPR:$rs1, GPR:$rs2)>;
1032def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 2)), non_imm12:$rs2)),
1033          (SH2ADDUW GPR:$rs1, GPR:$rs2)>;
1034def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 3)), non_imm12:$rs2)),
1035          (SH3ADDUW GPR:$rs1, GPR:$rs2)>;
1036
1037def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), non_imm12:$rs2)),
1038          (SH1ADDUW GPR:$rs1, GPR:$rs2)>;
1039def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), non_imm12:$rs2)),
1040          (SH2ADDUW GPR:$rs1, GPR:$rs2)>;
1041def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2)),
1042          (SH3ADDUW GPR:$rs1, GPR:$rs2)>;
1043} // Predicates = [HasStdExtZba, IsRV64]
1044
1045let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
1046def : PatGprGpr<riscv_rolw, ROLW>;
1047def : PatGprGpr<riscv_rorw, RORW>;
1048def : PatGprImm<riscv_rorw, RORIW, uimm5>;
1049def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
1050          (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
1051} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
1052
1053let Predicates = [HasStdExtZbp, IsRV64] in {
1054def : Pat<(riscv_rorw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
1055def : Pat<(riscv_rolw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
1056def : PatGprGpr<riscv_grevw, GREVW>;
1057def : PatGprGpr<riscv_gorcw, GORCW>;
1058def : PatGprGpr<riscv_shflw, SHFLW>;
1059def : PatGprGpr<riscv_unshflw, UNSHFLW>;
1060def : PatGprImm<riscv_grevw, GREVIW, uimm5>;
1061def : PatGprImm<riscv_gorcw, GORCIW, uimm5>;
1062} // Predicates = [HasStdExtZbp, IsRV64]
1063
1064let Predicates = [HasStdExtZbt, IsRV64] in {
1065def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
1066          (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1067def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, GPR:$rs2),
1068          (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1069def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
1070          (FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
1071def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
1072          (FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
1073} // Predicates = [HasStdExtZbt, IsRV64]
1074
1075let Predicates = [HasStdExtZbb, IsRV64] in {
1076def : PatGpr<riscv_clzw, CLZW>;
1077def : PatGpr<riscv_ctzw, CTZW>;
1078def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
1079} // Predicates = [HasStdExtZbb, IsRV64]
1080
1081let Predicates = [HasStdExtZbp, IsRV64] in {
1082def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
1083                               (and GPR:$rs1, 0x000000000000FFFF)),
1084                           i32)),
1085          (PACKW GPR:$rs1, GPR:$rs2)>;
1086def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
1087                   (and GPR:$rs1, 0x000000000000FFFF))),
1088          (PACKW GPR:$rs1, GPR:$rs2)>;
1089def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
1090                   (srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
1091          (PACKUW GPR:$rs1, GPR:$rs2)>;
1092} // Predicates = [HasStdExtZbp, IsRV64]
1093
1094let Predicates = [HasStdExtZbc] in {
1095def : PatGprGpr<int_riscv_clmul, CLMUL>;
1096def : PatGprGpr<int_riscv_clmulh, CLMULH>;
1097def : PatGprGpr<int_riscv_clmulr, CLMULR>;
1098} // Predicates = [HasStdExtZbc]
1099
1100let Predicates = [HasStdExtZbe] in {
1101def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
1102def : PatGprGpr<riscv_bdecompress, BDECOMPRESS>;
1103} // Predicates = [HasStdExtZbe]
1104
1105let Predicates = [HasStdExtZbe, IsRV64] in {
1106def : PatGprGpr<riscv_bcompressw, BCOMPRESSW>;
1107def : PatGprGpr<riscv_bdecompressw, BDECOMPRESSW>;
1108} // Predicates = [HasStdExtZbe, IsRV64]
1109
1110let Predicates = [HasStdExtZbr] in {
1111def : PatGpr<int_riscv_crc32_b, CRC32B>;
1112def : PatGpr<int_riscv_crc32_h, CRC32H>;
1113def : PatGpr<int_riscv_crc32_w, CRC32W>;
1114def : PatGpr<int_riscv_crc32c_b, CRC32CB>;
1115def : PatGpr<int_riscv_crc32c_h, CRC32CH>;
1116def : PatGpr<int_riscv_crc32c_w, CRC32CW>;
1117} // Predicates = [HasStdExtZbr]
1118
1119let Predicates = [HasStdExtZbr, IsRV64] in {
1120def : PatGpr<int_riscv_crc32_d, CRC32D>;
1121def : PatGpr<int_riscv_crc32c_d, CRC32CD>;
1122} // Predicates = [HasStdExtZbr, IsRV64]
1123