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(countTrailingOnes(N->getZExtValue()),
87                                   SDLoc(N), N->getValueType(0));
88}]>;
89
90def BSETINVXForm : SDNodeXForm<imm, [{
91  // Find the lowest 1.
92  return CurDAG->getTargetConstant(countTrailingZeros(N->getZExtValue()),
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) && isShiftedInt<12, 2>(C);
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 or
222  // CSImm12MulBy4.
223  return !isInt<14>(C) && isShiftedInt<12, 3>(C);
224}]>;
225
226def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
227  return CurDAG->getTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
228                                   N->getValueType(0));
229}]>;
230
231def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
232  return CurDAG->getTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
233                                   N->getValueType(0));
234}]>;
235
236// Pattern to exclude simm12 immediates from matching.
237def non_imm12 : PatLeaf<(XLenVT GPR:$a), [{
238  auto *C = dyn_cast<ConstantSDNode>(N);
239  return !C || !isInt<12>(C->getSExtValue());
240}]>;
241
242def sh1add_op : ComplexPattern<XLenVT, 1, "selectSH1ADDOp", [], [], 6>;
243def sh2add_op : ComplexPattern<XLenVT, 1, "selectSH2ADDOp", [], [], 6>;
244def sh3add_op : ComplexPattern<XLenVT, 1, "selectSH3ADDOp", [], [], 6>;
245
246//===----------------------------------------------------------------------===//
247// Instruction class templates
248//===----------------------------------------------------------------------===//
249
250// Some of these templates should be moved to RISCVInstrFormats.td once the B
251// extension has been ratified.
252
253let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
254class RVBUnary<bits<7> funct7, bits<5> funct5, bits<3> funct3,
255               RISCVOpcode opcode, string opcodestr>
256    : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
257              opcodestr, "$rd, $rs1"> {
258  let rs2 = funct5;
259}
260
261let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
262class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
263                  string opcodestr>
264    : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
265                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
266                   "$rd, $rs1, $shamt">;
267
268let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
269class RVBShiftW_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
270                   string opcodestr>
271    : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
272                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,
273                    "$rd, $rs1, $shamt">;
274
275// Using RVInstIShiftW since it allocates 5 bits instead of 6 to shamt.
276let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
277class RVBShfl_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
278                 string opcodestr>
279    : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
280                    (ins GPR:$rs1, shfl_uimm:$shamt), opcodestr,
281                    "$rd, $rs1, $shamt">;
282
283let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
284class RVBTernaryR<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
285                  string opcodestr, string argstr>
286    : RVInstR4<funct2, funct3, opcode, (outs GPR:$rd),
287               (ins GPR:$rs1, GPR:$rs2, GPR:$rs3), opcodestr, argstr>;
288
289// Currently used by FSRI only
290let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
291class RVBTernaryImm6<bits<3> funct3, RISCVOpcode opcode,
292                     string opcodestr, string argstr>
293    : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
294             opcodestr, argstr, [], InstFormatR4> {
295  bits<5> rs3;
296  bits<6> shamt;
297  bits<5> rs1;
298  bits<5> rd;
299
300  let Inst{31-27} = rs3;
301  let Inst{26} = 1;
302  let Inst{25-20} = shamt;
303  let Inst{19-15} = rs1;
304  let Inst{14-12} = funct3;
305  let Inst{11-7} = rd;
306  let Opcode = opcode.Value;
307}
308
309// Currently used by FSRIW only
310let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
311class RVBTernaryImm5<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
312                     string opcodestr, string argstr>
313    : RVInst<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs3, uimm5:$shamt),
314             opcodestr, argstr, [], InstFormatR4> {
315  bits<5> rs3;
316  bits<5> shamt;
317  bits<5> rs1;
318  bits<5> rd;
319
320  let Inst{31-27} = rs3;
321  let Inst{26-25} = funct2;
322  let Inst{24-20} = shamt;
323  let Inst{19-15} = rs1;
324  let Inst{14-12} = funct3;
325  let Inst{11-7} = rd;
326  let Opcode = opcode.Value;
327}
328
329//===----------------------------------------------------------------------===//
330// Instructions
331//===----------------------------------------------------------------------===//
332
333let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
334def ANDN  : ALU_rr<0b0100000, 0b111, "andn">,
335            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
336def ORN   : ALU_rr<0b0100000, 0b110, "orn">,
337            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
338def XNOR  : ALU_rr<0b0100000, 0b100, "xnor">,
339            Sched<[WriteIALU, ReadIALU, ReadIALU]>;
340} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
341
342let Predicates = [HasStdExtZba] in {
343def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
344             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
345def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
346             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
347def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
348             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
349} // Predicates = [HasStdExtZba]
350
351let Predicates = [HasStdExtZba, IsRV64] in {
352def SLLI_UW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
353              Sched<[WriteShiftImm32, ReadShiftImm32]>;
354def ADD_UW : ALUW_rr<0b0000100, 0b000, "add.uw">,
355             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
356def SH1ADD_UW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
357                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
358def SH2ADD_UW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
359                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
360def SH3ADD_UW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
361                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
362} // Predicates = [HasStdExtZba, IsRV64]
363
364let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
365def ROL   : ALU_rr<0b0110000, 0b001, "rol">,
366            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
367def ROR   : ALU_rr<0b0110000, 0b101, "ror">,
368            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
369
370def RORI  : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
371            Sched<[WriteRotateImm, ReadRotateImm]>;
372} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
373
374let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
375def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">,
376            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
377def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">,
378            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
379
380def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
381            Sched<[WriteRotateImm32, ReadRotateImm32]>;
382} // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
383
384let Predicates = [HasStdExtZbs] in {
385def BCLR : ALU_rr<0b0100100, 0b001, "bclr">,
386           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
387def BSET : ALU_rr<0b0010100, 0b001, "bset">,
388           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
389def BINV : ALU_rr<0b0110100, 0b001, "binv">,
390           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
391def BEXT : ALU_rr<0b0100100, 0b101, "bext">,
392           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
393
394def BCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "bclri">,
395            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
396def BSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "bseti">,
397            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
398def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">,
399            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
400def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">,
401            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
402} // Predicates = [HasStdExtZbs]
403
404let Predicates = [HasStdExtZbp] in {
405def GORC : ALU_rr<0b0010100, 0b101, "gorc">,
406           Sched<[WriteORC, ReadORC, ReadORC]>;
407def GREV : ALU_rr<0b0110100, 0b101, "grev">,
408           Sched<[WriteREV, ReadREV, ReadREV]>;
409
410def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">,
411            Sched<[WriteREVImm, ReadREVImm]>;
412def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">,
413            Sched<[WriteORCImm, ReadORCImm]>;
414
415def SHFL   : ALU_rr<0b0000100, 0b001, "shfl">,
416             Sched<[WriteSHFL, ReadSHFL, ReadSHFL]>;
417def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">,
418             Sched<[WriteUNSHFL, ReadUNSHFL, ReadUNSHFL]>;
419
420def SHFLI   : RVBShfl_ri<0b0000100, 0b001, OPC_OP_IMM, "shfli">,
421              Sched<[WriteSHFLImm, ReadSHFLImm]>;
422def UNSHFLI : RVBShfl_ri<0b0000100, 0b101, OPC_OP_IMM, "unshfli">,
423              Sched<[WriteUNSHFLImm, ReadUNSHFLImm]>;
424
425def XPERM_H : ALU_rr<0b0010100, 0b110, "xperm.h">,
426              Sched<[WriteXPERMH, ReadXPERMH, ReadXPERMH]>;
427} // Predicates = [HasStdExtZbp]
428
429let Predicates = [HasStdExtZbp, IsRV64] in {
430def GORCW  : ALUW_rr<0b0010100, 0b101, "gorcw">,
431             Sched<[WriteORC32, ReadORC32, ReadORC32]>;
432def GREVW  : ALUW_rr<0b0110100, 0b101, "grevw">,
433             Sched<[WriteREV32, ReadREV32, ReadREV32]>;
434
435def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">,
436             Sched<[WriteREVImm32, ReadREVImm32]>;
437def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">,
438             Sched<[WriteORCImm32, ReadORCImm32]>;
439
440def SHFLW   : ALUW_rr<0b0000100, 0b001, "shflw">,
441              Sched<[WriteSHFL32, ReadSHFL32, ReadSHFL32]>;
442def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">,
443              Sched<[WriteUNSHFL32, ReadUNSHFL32, ReadUNSHFL32]>;
444
445def XPERM_W : ALU_rr<0b0010100, 0b000, "xperm.w">,
446              Sched<[WriteXPERMW, ReadXPERMW, ReadXPERMW]>;
447} // Predicates = [HasStdExtZbp, IsRV64]
448
449// These instructions were named xperm.n and xperm.b in the last version of
450// the draft bit manipulation specification they were included in. However, we
451// use the mnemonics given to them in the ratified Zbkx extension.
452let Predicates = [HasStdExtZbpOrZbkx] in {
453def XPERM4 : ALU_rr<0b0010100, 0b010, "xperm4">, Sched<[]>;
454def XPERM8 : ALU_rr<0b0010100, 0b100, "xperm8">, Sched<[]>;
455} // Predicates = [HasStdExtZbpOrZbkx]
456
457let Predicates = [HasStdExtZbt] in {
458def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
459           Sched<[WriteCMix, ReadCMix, ReadCMix, ReadCMix]>;
460def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
461           Sched<[WriteCMov, ReadCMov, ReadCMov, ReadCMov]>;
462def FSL  : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
463           Sched<[WriteFSReg, ReadFSReg, ReadFSReg, ReadFSReg]>;
464def FSR  : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
465           Sched<[WriteFSReg, ReadFSReg, ReadFSReg, ReadFSReg]>;
466def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
467                          "$rd, $rs1, $rs3, $shamt">,
468           Sched<[WriteFSRImm, ReadFSRImm, ReadFSRImm]>;
469} // Predicates = [HasStdExtZbt]
470
471let Predicates = [HasStdExtZbt, IsRV64] in {
472def FSLW  : RVBTernaryR<0b10, 0b001, OPC_OP_32,
473                        "fslw", "$rd, $rs1, $rs3, $rs2">,
474            Sched<[WriteFSReg32, ReadFSReg32, ReadFSReg32, ReadFSReg32]>;
475def FSRW  : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
476                        "$rd, $rs1, $rs3, $rs2">,
477            Sched<[WriteFSReg32, ReadFSReg32, ReadFSReg32, ReadFSReg32]>;
478def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
479                           "fsriw", "$rd, $rs1, $rs3, $shamt">,
480            Sched<[WriteFSRImm32, ReadFSRImm32, ReadFSRImm32]>;
481} // Predicates = [HasStdExtZbt, IsRV64]
482
483let Predicates = [HasStdExtZbb] in {
484def CLZ  : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM, "clz">,
485           Sched<[WriteCLZ, ReadCLZ]>;
486def CTZ  : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM, "ctz">,
487           Sched<[WriteCTZ, ReadCTZ]>;
488def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM, "cpop">,
489           Sched<[WriteCPOP, ReadCPOP]>;
490} // Predicates = [HasStdExtZbb]
491
492let Predicates = [HasStdExtZbb, IsRV64] in {
493def CLZW   : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM_32, "clzw">,
494             Sched<[WriteCLZ32, ReadCLZ32]>;
495def CTZW   : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM_32, "ctzw">,
496             Sched<[WriteCTZ32, ReadCTZ32]>;
497def CPOPW  : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM_32, "cpopw">,
498             Sched<[WriteCPOP32, ReadCPOP32]>;
499} // Predicates = [HasStdExtZbb, IsRV64]
500
501let Predicates = [HasStdExtZbb] in {
502def SEXT_B : RVBUnary<0b0110000, 0b00100, 0b001, OPC_OP_IMM, "sext.b">,
503             Sched<[WriteIALU, ReadIALU]>;
504def SEXT_H : RVBUnary<0b0110000, 0b00101, 0b001, OPC_OP_IMM, "sext.h">,
505             Sched<[WriteIALU, ReadIALU]>;
506} // Predicates = [HasStdExtZbb]
507
508let Predicates = [HasStdExtZbr] in {
509def CRC32_B : RVBUnary<0b0110000, 0b10000, 0b001, OPC_OP_IMM, "crc32.b">,
510              Sched<[WriteCRCB, ReadCRCB]>;
511def CRC32_H : RVBUnary<0b0110000, 0b10001, 0b001, OPC_OP_IMM, "crc32.h">,
512              Sched<[WriteCRCH, ReadCRCH]>;
513def CRC32_W : RVBUnary<0b0110000, 0b10010, 0b001, OPC_OP_IMM, "crc32.w">,
514              Sched<[WriteCRCW, ReadCRCW]>;
515
516def CRC32C_B : RVBUnary<0b0110000, 0b11000, 0b001, OPC_OP_IMM, "crc32c.b">,
517               Sched<[WriteCRCCB, ReadCRCCB]>;
518def CRC32C_H : RVBUnary<0b0110000, 0b11001, 0b001, OPC_OP_IMM, "crc32c.h">,
519               Sched<[WriteCRCCH, ReadCRCCH]>;
520def CRC32C_W : RVBUnary<0b0110000, 0b11010, 0b001, OPC_OP_IMM, "crc32c.w">,
521               Sched<[WriteCRCCW, ReadCRCCW]>;
522} // Predicates = [HasStdExtZbr]
523
524let Predicates = [HasStdExtZbr, IsRV64] in {
525def CRC32_D  : RVBUnary<0b0110000, 0b10011, 0b001, OPC_OP_IMM, "crc32.d">,
526               Sched<[WriteCRCD, ReadCRCD]>;
527
528def CRC32C_D : RVBUnary<0b0110000, 0b11011, 0b001, OPC_OP_IMM, "crc32c.d">,
529               Sched<[WriteCRCCD, ReadCRCCD]>;
530} // Predicates = [HasStdExtZbr, IsRV64]
531
532let Predicates = [HasStdExtZbc] in {
533def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr", /*Commutable*/1>,
534             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
535} // Predicates = [HasStdExtZbc]
536
537let Predicates = [HasStdExtZbcOrZbkc] in {
538def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul", /*Commutable*/1>,
539             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
540def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh", /*Commutable*/1>,
541             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
542} // Predicates = [HasStdExtZbcOrZbkc]
543
544let Predicates = [HasStdExtZbb] in {
545def MIN  : ALU_rr<0b0000101, 0b100, "min", /*Commutable*/1>,
546           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
547def MINU : ALU_rr<0b0000101, 0b101, "minu", /*Commutable*/1>,
548           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
549def MAX  : ALU_rr<0b0000101, 0b110, "max", /*Commutable*/1>,
550           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
551def MAXU : ALU_rr<0b0000101, 0b111, "maxu", /*Commutable*/1>,
552           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
553} // Predicates = [HasStdExtZbb]
554
555let Predicates = [HasStdExtZbe] in {
556// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
557// bext in the 0.93 spec.
558def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">,
559                  Sched<[WriteDecompress, ReadDecompress, ReadDecompress]>;
560def BCOMPRESS   : ALU_rr<0b0000100, 0b110, "bcompress">,
561                  Sched<[WriteCompress, ReadCompress, ReadCompress]>;
562} // Predicates = [HasStdExtZbe]
563
564let Predicates = [HasStdExtZbe, IsRV64] in {
565// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
566// bextw in the 0.93 spec.
567def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">,
568                   Sched<[WriteDecompress32, ReadDecompress32, ReadDecompress32]>;
569def BCOMPRESSW   : ALUW_rr<0b0000100, 0b110, "bcompressw">,
570                   Sched<[WriteCompress32, ReadCompress32, ReadCompress32]>;
571} // Predicates = [HasStdExtZbe, IsRV64]
572
573let Predicates = [HasStdExtZbpOrZbkb] in {
574def PACK  : ALU_rr<0b0000100, 0b100, "pack">,
575            Sched<[WritePACK, ReadPACK, ReadPACK]>;
576def PACKH : ALU_rr<0b0000100, 0b111, "packh">,
577            Sched<[WritePACK, ReadPACK, ReadPACK]>;
578} // Predicates = [HasStdExtZbpOrZbkb]
579
580let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in
581def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">,
582             Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
583
584let Predicates = [HasStdExtZbp] in
585def PACKU : ALU_rr<0b0100100, 0b100, "packu">,
586            Sched<[WritePACKU, ReadPACKU, ReadPACKU]>;
587
588let Predicates = [HasStdExtZbp, IsRV64] in
589def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">,
590             Sched<[WritePACKU32, ReadPACKU32, ReadPACKU32]>;
591
592let Predicates = [HasStdExtZbm, IsRV64] in {
593def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, OPC_OP_IMM, "bmatflip">,
594               Sched<[WriteBMatrix, ReadBMatrix]>;
595
596def BMATOR   : ALU_rr<0b0000100, 0b011, "bmator">,
597               Sched<[WriteBMatrix, ReadBMatrix, ReadBMatrix]>;
598def BMATXOR  : ALU_rr<0b0100100, 0b011, "bmatxor">,
599               Sched<[WriteBMatrix, ReadBMatrix, ReadBMatrix]>;
600} // Predicates = [HasStdExtZbm, IsRV64]
601
602let Predicates = [HasStdExtZbf] in
603def BFP : ALU_rr<0b0100100, 0b111, "bfp">,
604          Sched<[WriteBFP, ReadBFP, ReadBFP]>;
605
606let Predicates = [HasStdExtZbf, IsRV64] in
607def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">,
608           Sched<[WriteBFP32, ReadBFP32, ReadBFP32]>;
609
610let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
611def ZEXT_H_RV32 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP, "zext.h">,
612                  Sched<[WriteIALU, ReadIALU]>;
613} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
614
615let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
616def ZEXT_H_RV64 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP_32, "zext.h">,
617                  Sched<[WriteIALU, ReadIALU]>;
618} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
619
620// We treat rev8 and orc.b as standalone instructions even though they use a
621// portion of the encodings for grevi and gorci. This allows us to support only
622// those encodings when only Zbb is enabled. We do this even when grevi and
623// gorci are available with Zbp. Trying to use 'HasStdExtZbb, NotHasStdExtZbp'
624// causes diagnostics to suggest that Zbp rather than Zbb is required for rev8
625// or gorci. Since Zbb is closer to being finalized than Zbp this will be
626// misleading to users.
627let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV32] in {
628def REV8_RV32 : RVBUnary<0b0110100, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
629                Sched<[WriteREV8, ReadREV8]>;
630} // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV32]
631
632let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
633def REV8_RV64 : RVBUnary<0b0110101, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
634                Sched<[WriteREV8, ReadREV8]>;
635} // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
636
637let Predicates = [HasStdExtZbbOrZbp] in {
638def ORC_B : RVBUnary<0b0010100, 0b00111, 0b101, OPC_OP_IMM, "orc.b">,
639            Sched<[WriteORCB, ReadORCB]>;
640} // Predicates = [HasStdExtZbbOrZbp]
641
642let Predicates = [HasStdExtZbpOrZbkb] in
643def BREV8 : RVBUnary<0b0110100, 0b00111, 0b101, OPC_OP_IMM, "brev8">,
644            Sched<[]>;
645
646let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in {
647def ZIP_RV32   : RVBUnary<0b0000100, 0b01111, 0b001, OPC_OP_IMM, "zip">,
648                 Sched<[]>;
649def UNZIP_RV32 : RVBUnary<0b0000100, 0b01111, 0b101, OPC_OP_IMM, "unzip">,
650                 Sched<[]>;
651} // Predicates = [HasStdExtZbpOrZbkb, IsRV32]
652
653
654//===----------------------------------------------------------------------===//
655// Pseudo Instructions
656//===----------------------------------------------------------------------===//
657
658let Predicates = [HasStdExtZba, IsRV64] in {
659def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;
660} // Predicates = [HasStdExtZba, IsRV64]
661
662let Predicates = [HasStdExtZbp] in {
663def : InstAlias<"rev.p $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
664def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
665def : InstAlias<"rev.n $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
666def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
667def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
668def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
669def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
670def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
671def : InstAlias<"rev.h $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
672def : InstAlias<"rev.b $rd, $rs",  (BREV8 GPR:$rd, GPR:$rs)>;
673
674def : InstAlias<"zip.n $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0001)>;
675def : InstAlias<"unzip.n $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
676def : InstAlias<"zip2.b $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0010)>;
677def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
678def : InstAlias<"zip.b $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0011)>;
679def : InstAlias<"unzip.b $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
680def : InstAlias<"zip4.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0100)>;
681def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
682def : InstAlias<"zip2.h $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b0110)>;
683def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
684def : InstAlias<"zip.h $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b0111)>;
685def : InstAlias<"unzip.h $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
686
687def : InstAlias<"orc.p $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
688def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
689def : InstAlias<"orc.n $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
690def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
691def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
692// orc.b is considered an instruction rather than an alias.
693def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
694def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
695def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
696def : InstAlias<"orc.h $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
697} // Predicates = [HasStdExtZbp]
698
699let Predicates = [HasStdExtZbp, IsRV32] in {
700def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
701// rev8 is considered an instruction rather than an alias.
702def : InstAlias<"rev4 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
703def : InstAlias<"rev2 $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
704def : InstAlias<"rev $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
705
706def : InstAlias<"zip8 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1000)>;
707def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
708def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>;
709def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
710def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>;
711def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
712// zip and unzip are considered instructions rather than an alias.
713
714def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
715def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
716def : InstAlias<"orc4 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
717def : InstAlias<"orc2 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
718def : InstAlias<"orc $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
719} // Predicates = [HasStdExtZbp, IsRV32]
720
721let Predicates = [HasStdExtZbp, IsRV64] in {
722def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
723def : InstAlias<"rev8.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
724def : InstAlias<"rev4.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
725def : InstAlias<"rev2.w $rd, $rs",  (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
726def : InstAlias<"rev.w $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
727def : InstAlias<"rev32 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
728def : InstAlias<"rev16 $rd, $rs",   (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
729// rev8 is considered an instruction rather than an alias.
730def : InstAlias<"rev4 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
731def : InstAlias<"rev2 $rd, $rs",    (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
732def : InstAlias<"rev $rd, $rs",     (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
733
734def : InstAlias<"zip8.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01000)>;
735def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
736def : InstAlias<"zip4.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01100)>;
737def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
738def : InstAlias<"zip2.w $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b01110)>;
739def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
740def : InstAlias<"zip.w $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b01111)>;
741def : InstAlias<"unzip.w $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
742def : InstAlias<"zip16 $rd, $rs",    (SHFLI   GPR:$rd, GPR:$rs, 0b10000)>;
743def : InstAlias<"unzip16 $rd, $rs",  (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
744def : InstAlias<"zip8 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11000)>;
745def : InstAlias<"unzip8 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
746def : InstAlias<"zip4 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11100)>;
747def : InstAlias<"unzip4 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
748def : InstAlias<"zip2 $rd, $rs",     (SHFLI   GPR:$rd, GPR:$rs, 0b11110)>;
749def : InstAlias<"unzip2 $rd, $rs",   (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
750def : InstAlias<"zip $rd, $rs",      (SHFLI   GPR:$rd, GPR:$rs, 0b11111)>;
751def : InstAlias<"unzip $rd, $rs",    (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
752
753def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
754def : InstAlias<"orc8.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
755def : InstAlias<"orc4.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
756def : InstAlias<"orc2.w $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
757def : InstAlias<"orc.w $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
758def : InstAlias<"orc32 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
759def : InstAlias<"orc16 $rd, $rs",   (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
760def : InstAlias<"orc8 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
761def : InstAlias<"orc4 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
762def : InstAlias<"orc2 $rd, $rs",    (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
763def : InstAlias<"orc $rd, $rs",     (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
764} // Predicates = [HasStdExtZbp, IsRV64]
765
766let Predicates = [HasStdExtZbbOrZbp] in {
767def : InstAlias<"ror $rd, $rs1, $shamt",
768                (RORI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
769} // Predicates = [HasStdExtZbbOrZbp]
770
771let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
772def : InstAlias<"rorw $rd, $rs1, $shamt",
773                (RORIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
774} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
775
776let Predicates = [HasStdExtZbp] in {
777def : InstAlias<"grev $rd, $rs1, $shamt",
778                (GREVI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
779def : InstAlias<"gorc $rd, $rs1, $shamt",
780                (GORCI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
781def : InstAlias<"shfl $rd, $rs1, $shamt",
782                (SHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
783def : InstAlias<"unshfl $rd, $rs1, $shamt",
784                (UNSHFLI  GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
785} // Predicates = [HasStdExtZbp]
786
787let Predicates = [HasStdExtZbp, IsRV64] in {
788def : InstAlias<"grevw $rd, $rs1, $shamt",
789                (GREVIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
790def : InstAlias<"gorcw $rd, $rs1, $shamt",
791                (GORCIW  GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
792} // Predicates = [HasStdExtZbp, IsRV64]
793
794// Zbp is unratified and that it would likely adopt the already ratified Zbkx names.
795// Thus current Zbp instructions are defined as aliases for Zbkx instructions.
796let Predicates = [HasStdExtZbp] in {
797  def : InstAlias<"xperm.b $rd, $rs1, $rs2",
798                  (XPERM8 GPR:$rd, GPR:$rs1, GPR:$rs2)>;
799  def : InstAlias<"xperm.n $rd, $rs1, $rs2",
800                  (XPERM4 GPR:$rd, GPR:$rs1, GPR:$rs2)>;
801} // Predicates = [HasStdExtZbp]
802
803let Predicates = [HasStdExtZbs] in {
804def : InstAlias<"bset $rd, $rs1, $shamt",
805                (BSETI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
806def : InstAlias<"bclr $rd, $rs1, $shamt",
807                (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
808def : InstAlias<"binv $rd, $rs1, $shamt",
809                (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
810def : InstAlias<"bext $rd, $rs1, $shamt",
811                (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
812} // Predicates = [HasStdExtZbs]
813
814//===----------------------------------------------------------------------===//
815// Codegen patterns
816//===----------------------------------------------------------------------===//
817
818let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
819def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
820def : Pat<(or  GPR:$rs1, (not GPR:$rs2)), (ORN  GPR:$rs1, GPR:$rs2)>;
821def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
822} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
823
824let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
825def : PatGprGpr<shiftop<rotl>, ROL>;
826def : PatGprGpr<shiftop<rotr>, ROR>;
827
828def : PatGprImm<rotr, RORI, uimmlog2xlen>;
829// There's no encoding for roli in the the 'B' extension as it can be
830// implemented with rori by negating the immediate.
831def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
832          (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
833} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
834
835let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
836def : PatGprGpr<shiftopw<riscv_rolw>, ROLW>;
837def : PatGprGpr<shiftopw<riscv_rorw>, RORW>;
838def : PatGprImm<riscv_rorw, RORIW, uimm5>;
839def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
840          (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
841} // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
842
843let Predicates = [HasStdExtZbs] in {
844def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
845          (BCLR GPR:$rs1, GPR:$rs2)>;
846def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (BCLR GPR:$rs1, GPR:$rs2)>;
847def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
848          (BSET GPR:$rs1, GPR:$rs2)>;
849def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
850          (BINV GPR:$rs1, GPR:$rs2)>;
851def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
852          (BEXT GPR:$rs1, GPR:$rs2)>;
853
854def : Pat<(shiftop<shl> 1, GPR:$rs2),
855          (BSET X0, GPR:$rs2)>;
856
857def : Pat<(and GPR:$rs1, BCLRMask:$mask),
858          (BCLRI GPR:$rs1, BCLRMask:$mask)>;
859def : Pat<(or GPR:$rs1, BSETINVMask:$mask),
860          (BSETI GPR:$rs1, BSETINVMask:$mask)>;
861def : Pat<(xor GPR:$rs1, BSETINVMask:$mask),
862          (BINVI GPR:$rs1, BSETINVMask:$mask)>;
863
864def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
865          (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
866
867def : Pat<(and (not (srl GPR:$rs1, uimmlog2xlen:$shamt)), (XLenVT 1)),
868          (XORI (BEXTI GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1))>;
869
870def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
871          (BSETI (BSETI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
872                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
873def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
874          (BINVI (BINVI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
875                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
876def : Pat<(or GPR:$r, BSETINVORIMask:$i),
877          (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
878                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
879def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
880          (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
881                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
882def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
883          (BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
884                 (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
885def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
886          (BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
887                 (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
888} // Predicates = [HasStdExtZbs]
889
890let Predicates = [HasStdExtZbbOrZbp] in {
891// We treat orc.b as a separate instruction, so match it directly. We also
892// lower the Zbb orc.b intrinsic to this.
893def : Pat<(riscv_gorc GPR:$rs1, 7), (ORC_B GPR:$rs1)>;
894} // Predicates = [HasStdExtZbbOrZbp]
895
896let Predicates = [HasStdExtZbpOrZbkb] in {
897// We treat brev8 as a separate instruction, so match it directly. We also
898// use this for brev8 when lowering bitreverse with Zbkb.
899def : Pat<(riscv_grev GPR:$rs1, 7), (BREV8 GPR:$rs1)>;
900} // Predicates = [HasStdExtZbpOrZbkb]
901
902let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in {
903// We treat zip and unzip as separate instructions, so match it directly.
904def : Pat<(i32 (riscv_shfl GPR:$rs1, 15)), (ZIP_RV32 GPR:$rs1)>;
905def : Pat<(i32 (riscv_unshfl GPR:$rs1, 15)), (UNZIP_RV32 GPR:$rs1)>;
906} // Predicates = [HasStdExtZbpOrZbkb, IsRV32]
907
908let Predicates = [HasStdExtZbp] in {
909def : PatGprGpr<riscv_grev, GREV>;
910def : PatGprGpr<riscv_gorc, GORC>;
911def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
912def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
913
914def : PatGprGpr<riscv_shfl, SHFL>;
915def : PatGprGpr<riscv_unshfl, UNSHFL>;
916def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
917def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
918
919def : PatGprGpr<int_riscv_xperm_n, XPERM4>;
920def : PatGprGpr<int_riscv_xperm_b, XPERM8>;
921def : PatGprGpr<int_riscv_xperm_h, XPERM_H>;
922} // Predicates = [HasStdExtZbp]
923
924let Predicates = [HasStdExtZbp, IsRV64] in {
925def : PatGprGpr<riscv_grevw, GREVW>;
926def : PatGprGpr<riscv_gorcw, GORCW>;
927
928// Select GREVIW/GORCIW when the immediate doesn't have bit 5 set and the result
929// is sign extended.
930// FIXME: Two special patterns keeped when Imm is 7.
931def : Pat<(i64 (sext_inreg (binop_oneuse<riscv_grev> GPR:$rs1, 7), i32)),
932          (GREVIW GPR:$rs1, 7)>;
933def : Pat<(i64 (sext_inreg (binop_oneuse<riscv_gorc> GPR:$rs1, 7), i32)),
934          (GORCIW GPR:$rs1, 7)>;
935def : PatGprImm<binop_allwusers<riscv_grev>, GREVIW, uimm5>;
936def : PatGprImm<binop_allwusers<riscv_gorc>, GORCIW, uimm5>;
937
938def : PatGprGpr<riscv_shflw, SHFLW>;
939def : PatGprGpr<riscv_unshflw, UNSHFLW>;
940} // Predicates = [HasStdExtZbp, IsRV64]
941
942let Predicates = [HasStdExtZbp, IsRV64] in
943def : PatGprGpr<int_riscv_xperm_w, XPERM_W>;
944
945let Predicates = [HasStdExtZbp, IsRV32] in {
946// We treat rev8 as a separate instruction, so match it directly.
947def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
948} // Predicates = [HasStdExtZbp, IsRV32]
949
950let Predicates = [HasStdExtZbp, IsRV64] in {
951// We treat rev8 as a separate instruction, so match it directly.
952def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
953} // Predicates = [HasStdExtZbp, IsRV64]
954
955let Predicates = [HasStdExtZbt] in {
956def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
957          (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
958def : Pat<(xor (and (xor GPR:$rs1, GPR:$rs3), GPR:$rs2), GPR:$rs3),
959          (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
960
961def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
962          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
963def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
964          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
965def : Pat<(select (XLenVT (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, GPR:$rs3),
966          (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
967def : Pat<(select (XLenVT (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs3, GPR:$rs1),
968          (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
969def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3),
970          (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
971def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
972          (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
973def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
974          (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
975def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
976          (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
977def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
978          (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
979def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
980          (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
981
982// setge X, Imm is canonicalized to setgt X, (Imm - 1).
983def : Pat<(select (XLenVT (setgt GPR:$x, simm12_minus1_nonzero:$imm)), GPR:$rs3, GPR:$rs1),
984          (CMOV GPR:$rs1, (SLTI GPR:$x, (ImmPlus1 simm12_minus1_nonzero:$imm)), GPR:$rs3)>;
985def : Pat<(select (XLenVT (setugt GPR:$x, simm12_minus1_nonzero:$imm)), GPR:$rs3, GPR:$rs1),
986          (CMOV GPR:$rs1, (SLTIU GPR:$x, (ImmPlus1 simm12_minus1_nonzero:$imm)), GPR:$rs3)>;
987
988def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
989          (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
990} // Predicates = [HasStdExtZbt]
991
992let Predicates = [HasStdExtZbt] in {
993def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
994          (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
995def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, GPR:$rs2),
996          (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
997def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt),
998          (FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
999// We can use FSRI for FSL by immediate if we subtract the immediate from
1000// XLen and swap the operands.
1001def : Pat<(riscv_fsl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
1002          (FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
1003} // Predicates = [HasStdExtZbt]
1004
1005let Predicates = [HasStdExtZbt, IsRV64] in {
1006def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
1007          (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1008def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, GPR:$rs2),
1009          (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
1010def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, uimm5:$shamt),
1011          (FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
1012// We can use FSRIW for FSLW by immediate if we subtract the immediate from
1013// 32 and swap the operands.
1014def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
1015          (FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
1016} // Predicates = [HasStdExtZbt, IsRV64]
1017
1018let Predicates = [HasStdExtZbb] in {
1019def : PatGpr<ctlz, CLZ>;
1020def : PatGpr<cttz, CTZ>;
1021def : PatGpr<ctpop, CPOP>;
1022} // Predicates = [HasStdExtZbb]
1023
1024let Predicates = [HasStdExtZbb, IsRV64] in {
1025def : PatGpr<riscv_clzw, CLZW>;
1026def : PatGpr<riscv_ctzw, CTZW>;
1027def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
1028} // Predicates = [HasStdExtZbb, IsRV64]
1029
1030let Predicates = [HasStdExtZbb] in {
1031def : Pat<(sext_inreg GPR:$rs1, i8), (SEXT_B GPR:$rs1)>;
1032def : Pat<(sext_inreg GPR:$rs1, i16), (SEXT_H GPR:$rs1)>;
1033} // Predicates = [HasStdExtZbb]
1034
1035let Predicates = [HasStdExtZbb] in {
1036def : PatGprGpr<smin, MIN>;
1037def : PatGprGpr<smax, MAX>;
1038def : PatGprGpr<umin, MINU>;
1039def : PatGprGpr<umax, MAXU>;
1040} // Predicates = [HasStdExtZbb]
1041
1042let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
1043def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
1044} // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
1045
1046let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
1047def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
1048} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
1049
1050let Predicates = [HasStdExtZbpOrZbkb] in {
1051def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
1052              (and GPR:$rs1, 0x00FF)),
1053          (PACKH GPR:$rs1, GPR:$rs2)>;
1054def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)),
1055              (and GPR:$rs1, 0x00FF)),
1056          (PACKH GPR:$rs1, GPR:$rs2)>;
1057} // Predicates = [HasStdExtZbpOrZbkb]
1058
1059let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in
1060def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
1061          (PACK GPR:$rs1, GPR:$rs2)>;
1062
1063let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in {
1064def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
1065          (PACK GPR:$rs1, GPR:$rs2)>;
1066
1067def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
1068                               (and GPR:$rs1, 0x000000000000FFFF)),
1069                           i32)),
1070          (PACKW GPR:$rs1, GPR:$rs2)>;
1071def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
1072                   (and GPR:$rs1, 0x000000000000FFFF))),
1073          (PACKW GPR:$rs1, GPR:$rs2)>;
1074} // Predicates = [HasStdExtZbpOrZbkb, IsRV64]
1075
1076let Predicates = [HasStdExtZbp, IsRV32] in
1077def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
1078          (PACKU GPR:$rs1, GPR:$rs2)>;
1079
1080let Predicates = [HasStdExtZbp, IsRV64] in {
1081def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
1082          (PACKU GPR:$rs1, GPR:$rs2)>;
1083
1084def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
1085                   (srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
1086          (PACKUW GPR:$rs1, GPR:$rs2)>;
1087} // Predicates = [HasStdExtZbp, IsRV64]
1088
1089let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
1090def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
1091let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
1092def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
1093
1094let Predicates = [HasStdExtZba] in {
1095def : Pat<(add (shl GPR:$rs1, (XLenVT 1)), non_imm12:$rs2),
1096          (SH1ADD GPR:$rs1, GPR:$rs2)>;
1097def : Pat<(add (shl GPR:$rs1, (XLenVT 2)), non_imm12:$rs2),
1098          (SH2ADD GPR:$rs1, GPR:$rs2)>;
1099def : Pat<(add (shl GPR:$rs1, (XLenVT 3)), non_imm12:$rs2),
1100          (SH3ADD GPR:$rs1, GPR:$rs2)>;
1101
1102// More complex cases use a ComplexPattern.
1103def : Pat<(add sh1add_op:$rs1, non_imm12:$rs2),
1104          (SH1ADD sh1add_op:$rs1, GPR:$rs2)>;
1105def : Pat<(add sh2add_op:$rs1, non_imm12:$rs2),
1106          (SH2ADD sh2add_op:$rs1, GPR:$rs2)>;
1107def : Pat<(add sh3add_op:$rs1, non_imm12:$rs2),
1108          (SH3ADD sh3add_op:$rs1, GPR:$rs2)>;
1109
1110def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
1111          (SH1ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1112def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
1113          (SH1ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1114def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
1115          (SH1ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1116def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
1117          (SH2ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1118def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
1119          (SH2ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1120def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
1121          (SH2ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1122def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
1123          (SH3ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1124def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
1125          (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1126def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
1127          (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1128
1129def : Pat<(add GPR:$r, CSImm12MulBy4:$i),
1130          (SH2ADD (ADDI X0, (SimmShiftRightBy2XForm CSImm12MulBy4:$i)),
1131                  GPR:$r)>;
1132def : Pat<(add GPR:$r, CSImm12MulBy8:$i),
1133          (SH3ADD (ADDI X0, (SimmShiftRightBy3XForm CSImm12MulBy8:$i)),
1134                  GPR:$r)>;
1135
1136def : Pat<(mul GPR:$r, C3LeftShift:$i),
1137          (SLLI (SH1ADD GPR:$r, GPR:$r),
1138                (TrailingZerosXForm C3LeftShift:$i))>;
1139def : Pat<(mul GPR:$r, C5LeftShift:$i),
1140          (SLLI (SH2ADD GPR:$r, GPR:$r),
1141                (TrailingZerosXForm C5LeftShift:$i))>;
1142def : Pat<(mul GPR:$r, C9LeftShift:$i),
1143          (SLLI (SH3ADD GPR:$r, GPR:$r),
1144                (TrailingZerosXForm C9LeftShift:$i))>;
1145
1146def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
1147          (SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1148def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
1149          (SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1150def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
1151          (SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1152def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
1153          (SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1154def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
1155          (SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1156def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
1157          (SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1158def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
1159          (SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1160def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
1161          (SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1162def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
1163          (SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1164def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
1165          (SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1166def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
1167          (SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1168} // Predicates = [HasStdExtZba]
1169
1170let Predicates = [HasStdExtZba, IsRV64] in {
1171def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
1172          (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
1173def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFF), non_imm12:$rs2)),
1174          (ADD_UW GPR:$rs1, GPR:$rs2)>;
1175def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, X0)>;
1176
1177def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 1)), non_imm12:$rs2)),
1178          (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
1179def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 2)), non_imm12:$rs2)),
1180          (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
1181def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 3)), non_imm12:$rs2)),
1182          (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
1183
1184def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), non_imm12:$rs2)),
1185          (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
1186def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), non_imm12:$rs2)),
1187          (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
1188def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2)),
1189          (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
1190
1191def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFE), non_imm12:$rs2)),
1192          (SH1ADD (SRLIW GPR:$rs1, 1), GPR:$rs2)>;
1193def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFC), non_imm12:$rs2)),
1194          (SH2ADD (SRLIW GPR:$rs1, 2), GPR:$rs2)>;
1195def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFF8), non_imm12:$rs2)),
1196          (SH3ADD (SRLIW GPR:$rs1, 3), GPR:$rs2)>;
1197
1198// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
1199def : Pat<(i64 (add (and GPR:$rs1, 0x1FFFFFFFE), non_imm12:$rs2)),
1200          (SH1ADD_UW (SRLI GPR:$rs1, 1), GPR:$rs2)>;
1201def : Pat<(i64 (add (and GPR:$rs1, 0x3FFFFFFFC), non_imm12:$rs2)),
1202          (SH2ADD_UW (SRLI GPR:$rs1, 2), GPR:$rs2)>;
1203def : Pat<(i64 (add (and GPR:$rs1, 0x7FFFFFFF8), non_imm12:$rs2)),
1204          (SH3ADD_UW (SRLI GPR:$rs1, 3), GPR:$rs2)>;
1205} // Predicates = [HasStdExtZba, IsRV64]
1206
1207let Predicates = [HasStdExtZbcOrZbkc] in {
1208def : PatGprGpr<int_riscv_clmul, CLMUL>;
1209def : PatGprGpr<int_riscv_clmulh, CLMULH>;
1210} // Predicates = [HasStdExtZbcOrZbkc]
1211
1212let Predicates = [HasStdExtZbc] in
1213def : PatGprGpr<int_riscv_clmulr, CLMULR>;
1214
1215let Predicates = [HasStdExtZbe] in {
1216def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
1217def : PatGprGpr<riscv_bdecompress, BDECOMPRESS>;
1218} // Predicates = [HasStdExtZbe]
1219
1220let Predicates = [HasStdExtZbe, IsRV64] in {
1221def : PatGprGpr<riscv_bcompressw, BCOMPRESSW>;
1222def : PatGprGpr<riscv_bdecompressw, BDECOMPRESSW>;
1223} // Predicates = [HasStdExtZbe, IsRV64]
1224
1225let Predicates = [HasStdExtZbr] in {
1226def : PatGpr<int_riscv_crc32_b, CRC32_B>;
1227def : PatGpr<int_riscv_crc32_h, CRC32_H>;
1228def : PatGpr<int_riscv_crc32_w, CRC32_W>;
1229def : PatGpr<int_riscv_crc32c_b, CRC32C_B>;
1230def : PatGpr<int_riscv_crc32c_h, CRC32C_H>;
1231def : PatGpr<int_riscv_crc32c_w, CRC32C_W>;
1232} // Predicates = [HasStdExtZbr]
1233
1234let Predicates = [HasStdExtZbr, IsRV64] in {
1235def : PatGpr<int_riscv_crc32_d, CRC32_D>;
1236def : PatGpr<int_riscv_crc32c_d, CRC32C_D>;
1237} // Predicates = [HasStdExtZbr, IsRV64]
1238
1239let Predicates = [HasStdExtZbf] in
1240def : PatGprGpr<riscv_bfp, BFP>;
1241
1242let Predicates = [HasStdExtZbf, IsRV64] in
1243def : PatGprGpr<riscv_bfpw, BFPW>;
1244
1245let Predicates = [HasStdExtZbkx] in {
1246def : PatGprGpr<int_riscv_xperm4, XPERM4>;
1247def : PatGprGpr<int_riscv_xperm8, XPERM8>;
1248} // Predicates = [HasStdExtZbkx]
1249