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