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