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