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