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