1 //===-- RISCVInstrInfoZb.td - RISC-V Bitmanip instructions -*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the RISC-V instructions from the standard Bitmanip
10 // extensions, versions:
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
22 // The experimental extensions appeared in an earlier draft of the Bitmanip
23 // extensions. They are not ratified and subject to change.
25 // This file also describes RISC-V instructions from the Zbk* extensions in
26 // Cryptography Extensions Volume I: Scalar & Entropy Source Instructions,
32 //===----------------------------------------------------------------------===//
34 //===----------------------------------------------------------------------===//
35 // Operand and SDNode transformation definitions.
36 //===----------------------------------------------------------------------===//
38 def riscv_clzw : SDNode<"RISCVISD::CLZW", SDT_RISCVIntUnaryOpW>;
39 def riscv_ctzw : SDNode<"RISCVISD::CTZW", SDT_RISCVIntUnaryOpW>;
40 def riscv_rolw : SDNode<"RISCVISD::ROLW", SDT_RISCVIntBinOpW>;
41 def riscv_rorw : SDNode<"RISCVISD::RORW", SDT_RISCVIntBinOpW>;
42 def riscv_fslw : SDNode<"RISCVISD::FSLW", SDT_RISCVIntShiftDOpW>;
43 def riscv_fsrw : SDNode<"RISCVISD::FSRW", SDT_RISCVIntShiftDOpW>;
44 def riscv_fsl : SDNode<"RISCVISD::FSL", SDTIntShiftDOp>;
45 def riscv_fsr : SDNode<"RISCVISD::FSR", SDTIntShiftDOp>;
46 def riscv_grev : SDNode<"RISCVISD::GREV", SDTIntBinOp>;
47 def riscv_grevw : SDNode<"RISCVISD::GREVW", SDT_RISCVIntBinOpW>;
48 def riscv_gorc : SDNode<"RISCVISD::GORC", SDTIntBinOp>;
49 def riscv_gorcw : SDNode<"RISCVISD::GORCW", SDT_RISCVIntBinOpW>;
50 def riscv_shfl : SDNode<"RISCVISD::SHFL", SDTIntBinOp>;
51 def riscv_shflw : SDNode<"RISCVISD::SHFLW", SDT_RISCVIntBinOpW>;
52 def riscv_unshfl : SDNode<"RISCVISD::UNSHFL", SDTIntBinOp>;
53 def riscv_unshflw: SDNode<"RISCVISD::UNSHFLW",SDT_RISCVIntBinOpW>;
54 def riscv_bfp : SDNode<"RISCVISD::BFP", SDTIntBinOp>;
55 def riscv_bfpw : SDNode<"RISCVISD::BFPW", SDT_RISCVIntBinOpW>;
56 def riscv_bcompress : SDNode<"RISCVISD::BCOMPRESS", SDTIntBinOp>;
57 def riscv_bcompressw : SDNode<"RISCVISD::BCOMPRESSW", SDT_RISCVIntBinOpW>;
58 def riscv_bdecompress : SDNode<"RISCVISD::BDECOMPRESS", SDTIntBinOp>;
59 def riscv_bdecompressw : SDNode<"RISCVISD::BDECOMPRESSW",SDT_RISCVIntBinOpW>;
61 def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
62 let Name = "UImmLog2XLenHalf";
63 let RenderMethod = "addImmOperands";
64 let DiagnosticType = "InvalidUImmLog2XLenHalf";
67 def shfl_uimm : Operand<XLenVT>, ImmLeaf<XLenVT, [{
68 if (Subtarget->is64Bit())
69 return isUInt<5>(Imm);
70 return isUInt<4>(Imm);
72 let ParserMatchClass = UImmLog2XLenHalfAsmOperand;
73 let DecoderMethod = "decodeUImmOperand<5>";
74 let MCOperandPredicate = [{
76 if (!MCOp.evaluateAsConstantImm(Imm))
78 if (STI.getTargetTriple().isArch64Bit())
79 return isUInt<5>(Imm);
80 return isUInt<4>(Imm);
84 def BCLRXForm : SDNodeXForm<imm, [{
86 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
87 SDLoc(N), N->getValueType(0));
90 def BSETINVXForm : SDNodeXForm<imm, [{
92 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
93 SDLoc(N), N->getValueType(0));
96 // Checks if this mask has a single 0 bit and cannot be used with ANDI.
97 def BCLRMask : ImmLeaf<XLenVT, [{
98 if (Subtarget->is64Bit())
99 return !isInt<12>(Imm) && isPowerOf2_64(~Imm);
100 return !isInt<12>(Imm) && isPowerOf2_32(~Imm);
103 // Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.
104 def BSETINVMask : ImmLeaf<XLenVT, [{
105 if (Subtarget->is64Bit())
106 return !isInt<12>(Imm) && isPowerOf2_64(Imm);
107 return !isInt<12>(Imm) && isPowerOf2_32(Imm);
110 // Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
111 // in which i = (1 << i0) | (1 << i1).
112 def BSETINVTwoBitsMask : PatLeaf<(imm), [{
115 // The immediate should not be a simm12.
116 if (isInt<12>(N->getSExtValue()))
118 // The immediate must have exactly two bits set.
119 return countPopulation(N->getZExtValue()) == 2;
122 def TrailingZerosXForm : SDNodeXForm<imm, [{
123 uint64_t I = N->getZExtValue();
124 return CurDAG->getTargetConstant(countTrailingZeros(I), SDLoc(N),
128 def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
129 uint64_t I = N->getZExtValue();
130 return CurDAG->getTargetConstant(63 - countLeadingZeros(I), SDLoc(N),
134 // Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
135 // in which imm = i0 | (1 << i1).
136 def BSETINVORIMask : PatLeaf<(imm), [{
139 // The immediate should not be a simm12.
140 if (isInt<12>(N->getSExtValue()))
142 // There should be only one set bit from bit 11 to the top.
143 return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
146 def BSETINVORIMaskLow : SDNodeXForm<imm, [{
147 return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
148 SDLoc(N), N->getValueType(0));
151 // Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
152 // in which i = ~((1<<i0) | (1<<i1)).
153 def BCLRITwoBitsMask : PatLeaf<(imm), [{
156 // The immediate should not be a simm12.
157 if (isInt<12>(N->getSExtValue()))
159 // The immediate must have exactly two bits clear.
160 return countPopulation(N->getZExtValue()) == Subtarget->getXLen() - 2;
163 def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
164 return CurDAG->getTargetConstant(countTrailingZeros(~N->getZExtValue()),
165 SDLoc(N), N->getValueType(0));
168 def 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),
176 // Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
177 // in which i = i0 & ~(1<<i1).
178 def BCLRIANDIMask : PatLeaf<(imm), [{
181 // The immediate should not be a simm12.
182 if (isInt<12>(N->getSExtValue()))
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);
189 def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
190 return CurDAG->getTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
191 SDLoc(N), N->getValueType(0));
194 def C3LeftShift : PatLeaf<(imm), [{
195 uint64_t C = N->getZExtValue();
196 return C > 3 && ((C % 3) == 0) && isPowerOf2_64(C / 3);
199 def C5LeftShift : PatLeaf<(imm), [{
200 uint64_t C = N->getZExtValue();
201 return C > 5 && ((C % 5) == 0) && isPowerOf2_64(C / 5);
204 def C9LeftShift : PatLeaf<(imm), [{
205 uint64_t C = N->getZExtValue();
206 return C > 9 && ((C % 9) == 0) && isPowerOf2_64(C / 9);
209 def CSImm12MulBy4 : PatLeaf<(imm), [{
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;
217 def CSImm12MulBy8 : PatLeaf<(imm), [{
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;
225 def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{
226 return CurDAG->getTargetConstant(N->getSExtValue() >> 2, SDLoc(N),
230 def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{
231 return CurDAG->getTargetConstant(N->getSExtValue() >> 3, SDLoc(N),
235 //===----------------------------------------------------------------------===//
236 // Instruction class templates
237 //===----------------------------------------------------------------------===//
239 // Some of these templates should be moved to RISCVInstrFormats.td once the B
240 // extension has been ratified.
242 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
243 class 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"> {
250 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
251 class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
253 : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),
254 (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
255 "$rd, $rs1, $shamt">;
257 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
258 class RVBShiftW_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
260 : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
261 (ins GPR:$rs1, uimm5:$shamt), opcodestr,
262 "$rd, $rs1, $shamt">;
264 // Using RVInstIShiftW since it allocates 5 bits instead of 6 to shamt.
265 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
266 class RVBShfl_ri<bits<7> imm11_5, bits<3> funct3, RISCVOpcode opcode,
268 : RVInstIShiftW<imm11_5, funct3, opcode, (outs GPR:$rd),
269 (ins GPR:$rs1, shfl_uimm:$shamt), opcodestr,
270 "$rd, $rs1, $shamt">;
272 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
273 class 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>;
278 // Currently used by FSRI only
279 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
280 class 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> {
289 let Inst{31-27} = rs3;
291 let Inst{25-20} = shamt;
292 let Inst{19-15} = rs1;
293 let Inst{14-12} = funct3;
295 let Opcode = opcode.Value;
298 // Currently used by FSRIW only
299 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
300 class 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> {
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;
315 let Opcode = opcode.Value;
318 //===----------------------------------------------------------------------===//
320 //===----------------------------------------------------------------------===//
322 let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
323 def ANDN : ALU_rr<0b0100000, 0b111, "andn">,
324 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
325 def ORN : ALU_rr<0b0100000, 0b110, "orn">,
326 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
327 def XNOR : ALU_rr<0b0100000, 0b100, "xnor">,
328 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
329 } // Predicates = [HasStdExtZbbOrZbpOrZbkb]
331 let Predicates = [HasStdExtZba] in {
332 def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
333 Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
334 def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,
335 Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
336 def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
337 Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
338 } // Predicates = [HasStdExtZba]
340 let Predicates = [HasStdExtZba, IsRV64] in {
341 def SLLI_UW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
342 Sched<[WriteShiftImm32, ReadShiftImm32]>;
343 def ADD_UW : ALUW_rr<0b0000100, 0b000, "add.uw">,
344 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
345 def SH1ADD_UW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,
346 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
347 def SH2ADD_UW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
348 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
349 def SH3ADD_UW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
350 Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
351 } // Predicates = [HasStdExtZbb, IsRV64]
353 let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
354 def ROL : ALU_rr<0b0110000, 0b001, "rol">,
355 Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
356 def ROR : ALU_rr<0b0110000, 0b101, "ror">,
357 Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
359 def RORI : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
360 Sched<[WriteRotateImm, ReadRotateImm]>;
361 } // Predicates = [HasStdExtZbbOrZbpOrZbkb]
363 let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
364 def ROLW : ALUW_rr<0b0110000, 0b001, "rolw">,
365 Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
366 def RORW : ALUW_rr<0b0110000, 0b101, "rorw">,
367 Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
369 def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
370 Sched<[WriteRotateImm32, ReadRotateImm32]>;
371 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
373 let Predicates = [HasStdExtZbs] in {
374 def BCLR : ALU_rr<0b0100100, 0b001, "bclr">,
375 Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
376 def BSET : ALU_rr<0b0010100, 0b001, "bset">,
377 Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
378 def BINV : ALU_rr<0b0110100, 0b001, "binv">,
379 Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
380 def BEXT : ALU_rr<0b0100100, 0b101, "bext">,
381 Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;
383 def BCLRI : RVBShift_ri<0b01001, 0b001, OPC_OP_IMM, "bclri">,
384 Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
385 def BSETI : RVBShift_ri<0b00101, 0b001, OPC_OP_IMM, "bseti">,
386 Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
387 def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">,
388 Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
389 def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">,
390 Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
391 } // Predicates = [HasStdExtZbs]
393 let Predicates = [HasStdExtZbp] in {
394 def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
395 def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
397 def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
398 def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
400 def SHFL : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
401 def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
403 def SHFLI : RVBShfl_ri<0b0000100, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
404 def UNSHFLI : RVBShfl_ri<0b0000100, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
406 def XPERM_H : ALU_rr<0b0010100, 0b110, "xperm.h">, Sched<[]>;
407 } // Predicates = [HasStdExtZbp]
409 let Predicates = [HasStdExtZbp, IsRV64] in {
410 def GORCW : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
411 def GREVW : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
413 def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
414 def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
416 def SHFLW : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
417 def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
419 def XPERM_W : ALU_rr<0b0010100, 0b000, "xperm.w">, Sched<[]>;
420 } // Predicates = [HasStdExtZbp, IsRV64]
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.
425 let Predicates = [HasStdExtZbpOrZbkx] in {
426 def XPERM4 : ALU_rr<0b0010100, 0b010, "xperm4">, Sched<[]>;
427 def XPERM8 : ALU_rr<0b0010100, 0b100, "xperm8">, Sched<[]>;
428 } // Predicates = [HasStdExtZbpOrZbkx]
430 let Predicates = [HasStdExtZbt] in {
431 def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
433 def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
435 def FSL : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
437 def FSR : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
439 def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
440 "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
441 } // Predicates = [HasStdExtZbt]
443 let Predicates = [HasStdExtZbt, IsRV64] in {
444 def FSLW : RVBTernaryR<0b10, 0b001, OPC_OP_32,
445 "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
446 def FSRW : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
447 "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
448 def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
449 "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
450 } // Predicates = [HasStdExtZbt, IsRV64]
452 let Predicates = [HasStdExtZbb] in {
453 def CLZ : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM, "clz">,
454 Sched<[WriteCLZ, ReadCLZ]>;
455 def CTZ : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM, "ctz">,
456 Sched<[WriteCTZ, ReadCTZ]>;
457 def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM, "cpop">,
458 Sched<[WriteCPOP, ReadCPOP]>;
459 } // Predicates = [HasStdExtZbb]
461 let Predicates = [HasStdExtZbb, IsRV64] in {
462 def CLZW : RVBUnary<0b0110000, 0b00000, 0b001, OPC_OP_IMM_32, "clzw">,
463 Sched<[WriteCLZ32, ReadCLZ32]>;
464 def CTZW : RVBUnary<0b0110000, 0b00001, 0b001, OPC_OP_IMM_32, "ctzw">,
465 Sched<[WriteCTZ32, ReadCTZ32]>;
466 def CPOPW : RVBUnary<0b0110000, 0b00010, 0b001, OPC_OP_IMM_32, "cpopw">,
467 Sched<[WriteCPOP32, ReadCPOP32]>;
468 } // Predicates = [HasStdExtZbb, IsRV64]
470 let Predicates = [HasStdExtZbb] in {
471 def SEXT_B : RVBUnary<0b0110000, 0b00100, 0b001, OPC_OP_IMM, "sext.b">,
472 Sched<[WriteIALU, ReadIALU]>;
473 def SEXT_H : RVBUnary<0b0110000, 0b00101, 0b001, OPC_OP_IMM, "sext.h">,
474 Sched<[WriteIALU, ReadIALU]>;
475 } // Predicates = [HasStdExtZbb]
477 let Predicates = [HasStdExtZbr] in {
478 def CRC32_B : RVBUnary<0b0110000, 0b10000, 0b001, OPC_OP_IMM, "crc32.b">,
480 def CRC32_H : RVBUnary<0b0110000, 0b10001, 0b001, OPC_OP_IMM, "crc32.h">,
482 def CRC32_W : RVBUnary<0b0110000, 0b10010, 0b001, OPC_OP_IMM, "crc32.w">,
485 def CRC32C_B : RVBUnary<0b0110000, 0b11000, 0b001, OPC_OP_IMM, "crc32c.b">,
487 def CRC32C_H : RVBUnary<0b0110000, 0b11001, 0b001, OPC_OP_IMM, "crc32c.h">,
489 def CRC32C_W : RVBUnary<0b0110000, 0b11010, 0b001, OPC_OP_IMM, "crc32c.w">,
491 } // Predicates = [HasStdExtZbr]
493 let Predicates = [HasStdExtZbr, IsRV64] in {
494 def CRC32_D : RVBUnary<0b0110000, 0b10011, 0b001, OPC_OP_IMM, "crc32.d">,
497 def CRC32C_D : RVBUnary<0b0110000, 0b11011, 0b001, OPC_OP_IMM, "crc32c.d">,
499 } // Predicates = [HasStdExtZbr, IsRV64]
501 let Predicates = [HasStdExtZbc] in {
502 def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">,
503 Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
504 } // Predicates = [HasStdExtZbc]
506 let Predicates = [HasStdExtZbcOrZbkc] in {
507 def CLMUL : ALU_rr<0b0000101, 0b001, "clmul">,
508 Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
509 def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">,
510 Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;
511 } // Predicates = [HasStdExtZbcOrZbkc]
513 let Predicates = [HasStdExtZbb] in {
514 def MIN : ALU_rr<0b0000101, 0b100, "min">,
515 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
516 def MINU : ALU_rr<0b0000101, 0b101, "minu">,
517 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
518 def MAX : ALU_rr<0b0000101, 0b110, "max">,
519 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
520 def MAXU : ALU_rr<0b0000101, 0b111, "maxu">,
521 Sched<[WriteIALU, ReadIALU, ReadIALU]>;
522 } // Predicates = [HasStdExtZbb]
524 let Predicates = [HasStdExtZbp] in {
525 } // Predicates = [HasStdExtZbp]
527 let 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.
530 def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">, Sched<[]>;
531 def BCOMPRESS : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>;
532 } // Predicates = [HasStdExtZbe]
534 let 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.
537 def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">, Sched<[]>;
538 def BCOMPRESSW : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>;
539 } // Predicates = [HasStdExtZbe, IsRV64]
541 let Predicates = [HasStdExtZbpOrZbkb] in {
542 def PACK : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
543 def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
544 } // Predicates = [HasStdExtZbpOrZbkb]
546 let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in
547 def PACKW : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
549 let Predicates = [HasStdExtZbp] in
550 def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
552 let Predicates = [HasStdExtZbp, IsRV64] in
553 def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
555 let Predicates = [HasStdExtZbm, IsRV64] in {
556 def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, OPC_OP_IMM, "bmatflip">,
559 def BMATOR : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
560 def BMATXOR : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
561 } // Predicates = [HasStdExtZbm, IsRV64]
563 let Predicates = [HasStdExtZbf] in
564 def BFP : ALU_rr<0b0100100, 0b111, "bfp">,
565 Sched<[WriteBFP, ReadBFP, ReadBFP]>;
567 let Predicates = [HasStdExtZbf, IsRV64] in
568 def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">,
569 Sched<[WriteBFP32, ReadBFP32, ReadBFP32]>;
571 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
572 def ZEXT_H_RV32 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP, "zext.h">,
573 Sched<[WriteIALU, ReadIALU]>;
574 } // Predicates = [HasStdExtZbbOrZbp, IsRV32]
576 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
577 def ZEXT_H_RV64 : RVBUnary<0b0000100, 0b00000, 0b100, OPC_OP_32, "zext.h">,
578 Sched<[WriteIALU, ReadIALU]>;
579 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
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.
588 let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV32] in {
589 def REV8_RV32 : RVBUnary<0b0110100, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
590 Sched<[WriteREV8, ReadREV8]>;
591 } // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV32]
593 let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
594 def REV8_RV64 : RVBUnary<0b0110101, 0b11000, 0b101, OPC_OP_IMM, "rev8">,
595 Sched<[WriteREV8, ReadREV8]>;
596 } // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
598 let Predicates = [HasStdExtZbbOrZbp] in {
599 def ORC_B : RVBUnary<0b0010100, 0b00111, 0b101, OPC_OP_IMM, "orc.b">,
600 Sched<[WriteORCB, ReadORCB]>;
601 } // Predicates = [HasStdExtZbbOrZbp]
603 let Predicates = [HasStdExtZbpOrZbkb] in
604 def BREV8 : RVBUnary<0b0110100, 0b00111, 0b101, OPC_OP_IMM, "brev8">;
606 let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in {
607 def ZIP_RV32 : RVBUnary<0b0000100, 0b01111, 0b001, OPC_OP_IMM, "zip">;
608 def UNZIP_RV32 : RVBUnary<0b0000100, 0b01111, 0b101, OPC_OP_IMM, "unzip">;
609 } // Predicates = [HasStdExtZbkb, IsRV32]
612 //===----------------------------------------------------------------------===//
613 // Pseudo Instructions
614 //===----------------------------------------------------------------------===//
616 let Predicates = [HasStdExtZba, IsRV64] in {
617 def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;
620 let Predicates = [HasStdExtZbp] in {
621 def : InstAlias<"rev.p $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
622 def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
623 def : InstAlias<"rev.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
624 def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
625 def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
626 def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
627 def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
628 def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
629 def : InstAlias<"rev.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
630 def : InstAlias<"rev.b $rd, $rs", (BREV8 GPR:$rd, GPR:$rs)>;
632 def : InstAlias<"zip.n $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0001)>;
633 def : InstAlias<"unzip.n $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
634 def : InstAlias<"zip2.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0010)>;
635 def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
636 def : InstAlias<"zip.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0011)>;
637 def : InstAlias<"unzip.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
638 def : InstAlias<"zip4.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0100)>;
639 def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
640 def : InstAlias<"zip2.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0110)>;
641 def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
642 def : InstAlias<"zip.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0111)>;
643 def : InstAlias<"unzip.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
645 def : InstAlias<"orc.p $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
646 def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
647 def : InstAlias<"orc.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
648 def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
649 def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
650 // orc.b is considered an instruction rather than an alias.
651 def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
652 def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
653 def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
654 def : InstAlias<"orc.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
655 } // Predicates = [HasStdExtZbp]
657 let Predicates = [HasStdExtZbp, IsRV32] in {
658 def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
659 // rev8 is considered an instruction rather than an alias.
660 def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
661 def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
662 def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
664 def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1000)>;
665 def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
666 def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1100)>;
667 def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
668 def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1110)>;
669 def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
670 // zip and unzip are considered instructions rather than an alias.
672 def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
673 def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
674 def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
675 def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
676 def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
677 } // Predicates = [HasStdExtZbp, IsRV32]
679 let Predicates = [HasStdExtZbp, IsRV64] in {
680 def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
681 def : InstAlias<"rev8.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
682 def : InstAlias<"rev4.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
683 def : InstAlias<"rev2.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
684 def : InstAlias<"rev.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
685 def : InstAlias<"rev32 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
686 def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
687 // rev8 is considered an instruction rather than an alias.
688 def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
689 def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
690 def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
692 def : InstAlias<"zip8.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01000)>;
693 def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
694 def : InstAlias<"zip4.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01100)>;
695 def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
696 def : InstAlias<"zip2.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01110)>;
697 def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
698 def : InstAlias<"zip.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01111)>;
699 def : InstAlias<"unzip.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
700 def : InstAlias<"zip16 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b10000)>;
701 def : InstAlias<"unzip16 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
702 def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11000)>;
703 def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
704 def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11100)>;
705 def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
706 def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11110)>;
707 def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
708 def : InstAlias<"zip $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11111)>;
709 def : InstAlias<"unzip $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
711 def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
712 def : InstAlias<"orc8.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
713 def : InstAlias<"orc4.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
714 def : InstAlias<"orc2.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
715 def : InstAlias<"orc.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
716 def : InstAlias<"orc32 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
717 def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
718 def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
719 def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
720 def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
721 def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
722 } // Predicates = [HasStdExtZbp, IsRV64]
724 let Predicates = [HasStdExtZbbOrZbp] in {
725 def : InstAlias<"ror $rd, $rs1, $shamt",
726 (RORI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
727 } // Predicates = [HasStdExtZbbOrZbp]
729 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
730 def : InstAlias<"rorw $rd, $rs1, $shamt",
731 (RORIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
732 } // Predicates = [HasStdExtZbbOrZbp, IsRV64]
734 let Predicates = [HasStdExtZbp] in {
735 def : InstAlias<"grev $rd, $rs1, $shamt",
736 (GREVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
737 def : InstAlias<"gorc $rd, $rs1, $shamt",
738 (GORCI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
739 def : InstAlias<"shfl $rd, $rs1, $shamt",
740 (SHFLI GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
741 def : InstAlias<"unshfl $rd, $rs1, $shamt",
742 (UNSHFLI GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
743 } // Predicates = [HasStdExtZbp]
745 let Predicates = [HasStdExtZbp, IsRV64] in {
746 def : InstAlias<"grevw $rd, $rs1, $shamt",
747 (GREVIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
748 def : InstAlias<"gorcw $rd, $rs1, $shamt",
749 (GORCIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
750 } // Predicates = [HasStdExtZbp, IsRV64]
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.
754 let 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]
761 let Predicates = [HasStdExtZbs] in {
762 def : InstAlias<"bset $rd, $rs1, $shamt",
763 (BSETI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
764 def : InstAlias<"bclr $rd, $rs1, $shamt",
765 (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
766 def : InstAlias<"binv $rd, $rs1, $shamt",
767 (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
768 def : InstAlias<"bext $rd, $rs1, $shamt",
769 (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
770 } // Predicates = [HasStdExtZbs]
772 //===----------------------------------------------------------------------===//
774 //===----------------------------------------------------------------------===//
776 let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
777 def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
778 def : Pat<(or GPR:$rs1, (not GPR:$rs2)), (ORN GPR:$rs1, GPR:$rs2)>;
779 def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
780 } // Predicates = [HasStdExtZbbOrZbpOrZbkb]
782 let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
783 def : PatGprGpr<rotl, ROL>;
784 def : PatGprGpr<rotr, ROR>;
786 def : 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.
789 def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
790 (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
791 } // Predicates = [HasStdExtZbbOrZbpOrZbkb]
793 let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
794 def : PatGprGpr<riscv_rolw, ROLW>;
795 def : PatGprGpr<riscv_rorw, RORW>;
796 def : PatGprImm<riscv_rorw, RORIW, uimm5>;
797 def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
798 (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
799 } // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
801 let Predicates = [HasStdExtZbs] in {
802 def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
803 (BCLR GPR:$rs1, GPR:$rs2)>;
804 def : Pat<(and (rotl -2, GPR:$rs2), GPR:$rs1), (BCLR GPR:$rs1, GPR:$rs2)>;
805 def : Pat<(or (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
806 (BSET GPR:$rs1, GPR:$rs2)>;
807 def : Pat<(xor (shiftop<shl> 1, GPR:$rs2), GPR:$rs1),
808 (BINV GPR:$rs1, GPR:$rs2)>;
809 def : Pat<(and (shiftop<srl> GPR:$rs1, GPR:$rs2), 1),
810 (BEXT GPR:$rs1, GPR:$rs2)>;
812 def : Pat<(shiftop<shl> 1, GPR:$rs2),
813 (BSET X0, GPR:$rs2)>;
815 def : Pat<(and GPR:$rs1, BCLRMask:$mask),
816 (BCLRI GPR:$rs1, BCLRMask:$mask)>;
817 def : Pat<(or GPR:$rs1, BSETINVMask:$mask),
818 (BSETI GPR:$rs1, BSETINVMask:$mask)>;
819 def : Pat<(xor GPR:$rs1, BSETINVMask:$mask),
820 (BINVI GPR:$rs1, BSETINVMask:$mask)>;
822 def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
823 (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
825 def : Pat<(and (not (srl GPR:$rs1, uimmlog2xlen:$shamt)), (XLenVT 1)),
826 (XORI (BEXTI GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1))>;
828 def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
829 (BSETI (BSETI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
830 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
831 def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
832 (BINVI (BINVI GPR:$r, (TrailingZerosXForm BSETINVTwoBitsMask:$i)),
833 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
834 def : Pat<(or GPR:$r, BSETINVORIMask:$i),
835 (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
836 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
837 def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
838 (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
839 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
840 def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
841 (BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
842 (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
843 def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
844 (BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
845 (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
848 let 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.
851 def : Pat<(riscv_gorc GPR:$rs1, 7), (ORC_B GPR:$rs1)>;
854 let 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.
857 def : Pat<(riscv_grev GPR:$rs1, 7), (BREV8 GPR:$rs1)>;
859 // We treat zip and unzip as separate instructions, so match it directly.
860 def : Pat<(i32 (riscv_shfl GPR:$rs1, 15)), (ZIP_RV32 GPR:$rs1)>;
861 def : Pat<(i32 (riscv_unshfl GPR:$rs1, 15)), (UNZIP_RV32 GPR:$rs1)>;
864 let Predicates = [HasStdExtZbp] in {
865 def : PatGprGpr<riscv_grev, GREV>;
866 def : PatGprGpr<riscv_gorc, GORC>;
867 def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
868 def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
870 def : PatGprGpr<riscv_shfl, SHFL>;
871 def : PatGprGpr<riscv_unshfl, UNSHFL>;
872 def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
873 def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
875 def : PatGprGpr<int_riscv_xperm_n, XPERM4>;
876 def : PatGprGpr<int_riscv_xperm_b, XPERM8>;
877 def : PatGprGpr<int_riscv_xperm_h, XPERM_H>;
878 } // Predicates = [HasStdExtZbp]
880 let Predicates = [HasStdExtZbp, IsRV64] in {
881 def : PatGprGpr<riscv_grevw, GREVW>;
882 def : PatGprGpr<riscv_gorcw, GORCW>;
883 def : PatGprImm<riscv_grevw, GREVIW, uimm5>;
884 def : PatGprImm<riscv_gorcw, GORCIW, uimm5>;
886 // FIXME: Move to DAG combine.
887 def : Pat<(riscv_rorw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
888 def : Pat<(riscv_rolw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
890 def : PatGprGpr<riscv_shflw, SHFLW>;
891 def : PatGprGpr<riscv_unshflw, UNSHFLW>;
892 } // Predicates = [HasStdExtZbp, IsRV64]
894 let Predicates = [HasStdExtZbp, IsRV64] in
895 def : PatGprGpr<int_riscv_xperm_w, XPERM_W>;
897 let Predicates = [HasStdExtZbp, IsRV32] in {
898 // FIXME : Move to DAG combine.
899 def : Pat<(i32 (rotr (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
900 def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
902 // We treat rev8 as a separate instruction, so match it directly.
903 def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
904 } // Predicates = [HasStdExtZbp, IsRV32]
906 let Predicates = [HasStdExtZbp, IsRV64] in {
907 // We treat rev8 as a separate instruction, so match it directly.
908 def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
909 } // Predicates = [HasStdExtZbp, IsRV64]
911 let Predicates = [HasStdExtZbt] in {
912 def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
913 (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
915 def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
916 (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
917 def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
918 (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
919 def : 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)>;
921 def : 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)>;
923 def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3),
924 (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
925 def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
926 (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
927 def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
928 (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
929 def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
930 (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
931 def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
932 (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
933 def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
934 (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
935 def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
936 (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
937 } // Predicates = [HasStdExtZbt]
939 let Predicates = [HasStdExtZbt] in {
940 def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
941 (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
942 def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, GPR:$rs2),
943 (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
944 def : 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.
948 def : Pat<(riscv_fsl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
949 (FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
950 } // Predicates = [HasStdExtZbt]
952 let Predicates = [HasStdExtZbt, IsRV64] in {
953 def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
954 (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
955 def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, GPR:$rs2),
956 (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
957 def : 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.
961 def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
962 (FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
963 } // Predicates = [HasStdExtZbt, IsRV64]
965 let Predicates = [HasStdExtZbb] in {
966 def : PatGpr<ctlz, CLZ>;
967 def : PatGpr<cttz, CTZ>;
968 def : PatGpr<ctpop, CPOP>;
969 } // Predicates = [HasStdExtZbb]
971 let Predicates = [HasStdExtZbb, IsRV64] in {
972 def : PatGpr<riscv_clzw, CLZW>;
973 def : PatGpr<riscv_ctzw, CTZW>;
974 def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
975 } // Predicates = [HasStdExtZbb, IsRV64]
977 let Predicates = [HasStdExtZbb] in {
978 def : Pat<(sext_inreg GPR:$rs1, i8), (SEXT_B GPR:$rs1)>;
979 def : Pat<(sext_inreg GPR:$rs1, i16), (SEXT_H GPR:$rs1)>;
982 let Predicates = [HasStdExtZbb] in {
983 def : PatGprGpr<smin, MIN>;
984 def : PatGprGpr<smax, MAX>;
985 def : PatGprGpr<umin, MINU>;
986 def : PatGprGpr<umax, MAXU>;
987 } // Predicates = [HasStdExtZbb]
989 let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
990 def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
991 } // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
993 let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
994 def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
995 } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
997 let Predicates = [HasStdExtZbpOrZbkb] in {
998 def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
999 (and GPR:$rs1, 0x00FF)),
1000 (PACKH GPR:$rs1, GPR:$rs2)>;
1001 def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)),
1002 (and GPR:$rs1, 0x00FF)),
1003 (PACKH GPR:$rs1, GPR:$rs2)>;
1004 } // Predicates = [HasStdExtZbpOrZbkb]
1006 let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in
1007 def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
1008 (PACK GPR:$rs1, GPR:$rs2)>;
1010 let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in {
1011 def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
1012 (PACK GPR:$rs1, GPR:$rs2)>;
1014 def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
1015 (and GPR:$rs1, 0x000000000000FFFF)),
1017 (PACKW GPR:$rs1, GPR:$rs2)>;
1018 def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
1019 (and GPR:$rs1, 0x000000000000FFFF))),
1020 (PACKW GPR:$rs1, GPR:$rs2)>;
1023 let Predicates = [HasStdExtZbp, IsRV32] in
1024 def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
1025 (PACKU GPR:$rs1, GPR:$rs2)>;
1027 let Predicates = [HasStdExtZbp, IsRV64] in {
1028 def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
1029 (PACKU GPR:$rs1, GPR:$rs2)>;
1031 def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
1032 (srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
1033 (PACKUW GPR:$rs1, GPR:$rs2)>;
1036 let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
1037 def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
1038 let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
1039 def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
1041 // Pattern to exclude simm12 immediates from matching.
1042 def non_imm12 : PatLeaf<(XLenVT GPR:$a), [{
1043 auto *C = dyn_cast<ConstantSDNode>(N);
1044 return !C || !isInt<12>(C->getSExtValue());
1047 let Predicates = [HasStdExtZba] in {
1048 def : Pat<(add (shl GPR:$rs1, (XLenVT 1)), non_imm12:$rs2),
1049 (SH1ADD GPR:$rs1, GPR:$rs2)>;
1050 def : Pat<(add (shl GPR:$rs1, (XLenVT 2)), non_imm12:$rs2),
1051 (SH2ADD GPR:$rs1, GPR:$rs2)>;
1052 def : Pat<(add (shl GPR:$rs1, (XLenVT 3)), non_imm12:$rs2),
1053 (SH3ADD GPR:$rs1, GPR:$rs2)>;
1055 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2),
1056 (SH1ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1057 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2),
1058 (SH1ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1059 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2),
1060 (SH1ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1061 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2),
1062 (SH2ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1063 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2),
1064 (SH2ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1065 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2),
1066 (SH2ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1067 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2),
1068 (SH3ADD (SH1ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1069 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2),
1070 (SH3ADD (SH2ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1071 def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2),
1072 (SH3ADD (SH3ADD GPR:$rs1, GPR:$rs1), GPR:$rs2)>;
1074 def : Pat<(add GPR:$r, CSImm12MulBy4:$i),
1075 (SH2ADD (ADDI X0, (SimmShiftRightBy2XForm CSImm12MulBy4:$i)),
1077 def : Pat<(add GPR:$r, CSImm12MulBy8:$i),
1078 (SH3ADD (ADDI X0, (SimmShiftRightBy3XForm CSImm12MulBy8:$i)),
1081 def : Pat<(mul GPR:$r, C3LeftShift:$i),
1082 (SLLI (SH1ADD GPR:$r, GPR:$r),
1083 (TrailingZerosXForm C3LeftShift:$i))>;
1084 def : Pat<(mul GPR:$r, C5LeftShift:$i),
1085 (SLLI (SH2ADD GPR:$r, GPR:$r),
1086 (TrailingZerosXForm C5LeftShift:$i))>;
1087 def : Pat<(mul GPR:$r, C9LeftShift:$i),
1088 (SLLI (SH3ADD GPR:$r, GPR:$r),
1089 (TrailingZerosXForm C9LeftShift:$i))>;
1091 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
1092 (SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1093 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
1094 (SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1095 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
1096 (SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1097 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
1098 (SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1099 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
1100 (SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1101 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
1102 (SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
1103 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
1104 (SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
1105 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
1106 (SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
1107 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
1108 (SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1109 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
1110 (SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1111 def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
1112 (SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
1113 } // Predicates = [HasStdExtZba]
1115 let Predicates = [HasStdExtZba, IsRV64] in {
1116 def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
1117 (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
1118 def : Pat<(i64 (add (and GPR:$rs1, 0xFFFFFFFF), non_imm12:$rs2)),
1119 (ADD_UW GPR:$rs1, GPR:$rs2)>;
1120 def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, X0)>;
1122 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 1)), non_imm12:$rs2)),
1123 (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
1124 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 2)), non_imm12:$rs2)),
1125 (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
1126 def : Pat<(i64 (add (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 3)), non_imm12:$rs2)),
1127 (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
1129 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), non_imm12:$rs2)),
1130 (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
1131 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), non_imm12:$rs2)),
1132 (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
1133 def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2)),
1134 (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
1135 } // Predicates = [HasStdExtZba, IsRV64]
1137 let Predicates = [HasStdExtZbcOrZbkc] in {
1138 def : PatGprGpr<int_riscv_clmul, CLMUL>;
1139 def : PatGprGpr<int_riscv_clmulh, CLMULH>;
1140 } // Predicates = [HasStdExtZbcOrZbkc]
1142 let Predicates = [HasStdExtZbc] in
1143 def : PatGprGpr<int_riscv_clmulr, CLMULR>;
1145 let Predicates = [HasStdExtZbe] in {
1146 def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
1147 def : PatGprGpr<riscv_bdecompress, BDECOMPRESS>;
1148 } // Predicates = [HasStdExtZbe]
1150 let Predicates = [HasStdExtZbe, IsRV64] in {
1151 def : PatGprGpr<riscv_bcompressw, BCOMPRESSW>;
1152 def : PatGprGpr<riscv_bdecompressw, BDECOMPRESSW>;
1153 } // Predicates = [HasStdExtZbe, IsRV64]
1155 let Predicates = [HasStdExtZbr] in {
1156 def : PatGpr<int_riscv_crc32_b, CRC32_B>;
1157 def : PatGpr<int_riscv_crc32_h, CRC32_H>;
1158 def : PatGpr<int_riscv_crc32_w, CRC32_W>;
1159 def : PatGpr<int_riscv_crc32c_b, CRC32C_B>;
1160 def : PatGpr<int_riscv_crc32c_h, CRC32C_H>;
1161 def : PatGpr<int_riscv_crc32c_w, CRC32C_W>;
1162 } // Predicates = [HasStdExtZbr]
1164 let Predicates = [HasStdExtZbr, IsRV64] in {
1165 def : PatGpr<int_riscv_crc32_d, CRC32_D>;
1166 def : PatGpr<int_riscv_crc32c_d, CRC32C_D>;
1167 } // Predicates = [HasStdExtZbr, IsRV64]
1169 let Predicates = [HasStdExtZbf] in
1170 def : PatGprGpr<riscv_bfp, BFP>;
1172 let Predicates = [HasStdExtZbf, IsRV64] in
1173 def : PatGprGpr<riscv_bfpw, BFPW>;
1175 let Predicates = [HasStdExtZbkx] in {
1176 def : PatGprGpr<int_riscv_xperm4, XPERM4>;
1177 def : PatGprGpr<int_riscv_xperm8, XPERM8>;