brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.8 KiB · 5429c2a Raw
878 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the RISC-V instructions from the standard Bitmanip10// extensions, versions:11//   Zba - 1.012//   Zbb - 1.013//   Zbc - 1.014//   Zbs - 1.015//16// This file also describes RISC-V instructions from the Zbk* extensions in17// Cryptography Extensions Volume I: Scalar & Entropy Source Instructions,18// versions:19//   Zbkb - 1.020//   Zbkc - 1.021//   Zbkx - 1.022//23//===----------------------------------------------------------------------===//24 25//===----------------------------------------------------------------------===//26// Operand and SDNode transformation definitions.27//===----------------------------------------------------------------------===//28 29def SDTIntShiftAddOp : SDTypeProfile<1, 3, [   // shl_add30  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 3>, SDTCisInt<0>, SDTCisInt<2>,31  SDTCisInt<3>32]>;33 34def riscv_shl_add : RVSDNode<"SHL_ADD", SDTIntShiftAddOp>;35 36// RV64IB rotates, directly matching the semantics of the named RISC-V37// instructions.38def riscv_rolw    : RVSDNode<"ROLW",    SDT_RISCVIntBinOpW>;39def riscv_rorw    : RVSDNode<"RORW",    SDT_RISCVIntBinOpW>;40 41// RV64IZbb bit counting instructions directly matching the semantics of the42// named RISC-V instructions.43def riscv_clzw    : RVSDNode<"CLZW",    SDT_RISCVIntUnaryOpW>;44def riscv_ctzw    : RVSDNode<"CTZW",    SDT_RISCVIntUnaryOpW>;45 46// brev8, orc.b, zip, and unzip from Zbb and Zbkb. All operands are i32 or47// XLenVT.48def riscv_brev8   : RVSDNode<"BREV8",   SDTIntUnaryOp>;49def riscv_orc_b   : RVSDNode<"ORC_B",   SDTIntUnaryOp>;50def riscv_zip     : RVSDNode<"ZIP",     SDTIntUnaryOp>;51def riscv_unzip   : RVSDNode<"UNZIP",   SDTIntUnaryOp>;52 53// RV64IZbb absolute value for i32. Expanded to (max (negw X), X) during isel.54def riscv_negw_max : RVSDNode<"NEGW_MAX",    SDTIntUnaryOp>;55 56// Scalar cryptography57def riscv_clmul   : RVSDNode<"CLMUL",   SDTIntBinOp>;58def riscv_clmulh  : RVSDNode<"CLMULH",  SDTIntBinOp>;59def riscv_clmulr  : RVSDNode<"CLMULR",  SDTIntBinOp>;60 61def BCLRXForm : SDNodeXForm<imm, [{62  // Find the lowest 0.63  return CurDAG->getTargetConstant(llvm::countr_one(N->getZExtValue()),64                                   SDLoc(N), N->getValueType(0));65}]>;66 67def SingleBitSetMaskToIndex : SDNodeXForm<imm, [{68  // Find the lowest 1.69  return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),70                                   SDLoc(N), N->getValueType(0));71}]>;72 73// Checks if this mask has a single 0 bit and cannot be used with ANDI.74def BCLRMask : ImmLeaf<XLenVT, [{75  if (Subtarget->is64Bit())76    return !isInt<12>(Imm) && isPowerOf2_64(~Imm);77  return !isInt<12>(Imm) && isPowerOf2_32(~Imm);78}], BCLRXForm>;79 80// Checks if this mask has a single 1 bit and cannot be used with ORI/XORI.81def SingleBitSetMask : ImmLeaf<XLenVT, [{82  if (Subtarget->is64Bit())83    return !isInt<12>(Imm) && isPowerOf2_64(Imm);84  return !isInt<12>(Imm) && isPowerOf2_32(Imm);85}], SingleBitSetMaskToIndex>;86 87// Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),88// in which i = (1 << i0) | (1 << i1).89def BSETINVTwoBitsMask : PatLeaf<(imm), [{90  if (!N->hasOneUse())91    return false;92  // The immediate should not be a simm12.93  if (isInt<12>(N->getSExtValue()))94    return false;95  // The immediate must have exactly two bits set.96  return llvm::popcount(N->getZExtValue()) == 2;97}]>;98 99def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{100  uint64_t I = N->getZExtValue();101  return CurDAG->getTargetConstant(llvm::Log2_64(I), SDLoc(N),102                                   N->getValueType(0));103}]>;104 105// Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),106// in which imm = i0 | (1 << i1).107def BSETINVORIMask : PatLeaf<(imm), [{108  if (!N->hasOneUse())109    return false;110  // The immediate should not be a simm12.111  if (isInt<12>(N->getSExtValue()))112    return false;113  // There should be only one set bit from bit 11 to the top.114  return isPowerOf2_64(N->getZExtValue() & ~0x7ff);115}]>;116 117def BSETINVORIMaskLow : SDNodeXForm<imm, [{118  return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,119                                   SDLoc(N), N->getValueType(0));120}]>;121 122// Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),123// in which i = ~((1<<i0) | (1<<i1)).124def BCLRITwoBitsMask : PatLeaf<(imm), [{125  if (!N->hasOneUse())126    return false;127  // The immediate should not be a simm12.128  if (isInt<12>(N->getSExtValue()))129    return false;130  // The immediate must have exactly two bits clear.131  return (unsigned)llvm::popcount(N->getZExtValue()) == Subtarget->getXLen() - 2;132}]>;133 134def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{135  return CurDAG->getTargetConstant(llvm::countr_zero(~N->getZExtValue()),136                                   SDLoc(N), N->getValueType(0));137}]>;138 139def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{140  uint64_t I = N->getZExtValue();141  if (!Subtarget->is64Bit())142    I |= maskLeadingOnes<uint64_t>(32);143  return CurDAG->getTargetConstant(llvm::Log2_64(~I), SDLoc(N),144                                   N->getValueType(0));145}]>;146 147// Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),148// in which i = i0 & ~(1<<i1).149def BCLRIANDIMask : PatLeaf<(imm), [{150  if (!N->hasOneUse())151    return false;152  // The immediate should not be a simm12.153  if (isInt<12>(N->getSExtValue()))154    return false;155  // There should be only one clear bit from bit 11 to the top.156  uint64_t I = N->getZExtValue() | 0x7ff;157  return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);158}]>;159 160def BCLRIANDIMaskLow : SDNodeXForm<imm, [{161  return CurDAG->getSignedTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,162                                         SDLoc(N), N->getValueType(0));163}]>;164 165def SimmShiftRightBy2XForm : SDNodeXForm<imm, [{166  return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 2, SDLoc(N),167                                         N->getValueType(0));168}]>;169 170def SimmShiftRightBy3XForm : SDNodeXForm<imm, [{171  return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 3, SDLoc(N),172                                         N->getValueType(0));173}]>;174 175def CSImm12MulBy4 : PatLeaf<(imm), [{176  if (!N->hasOneUse())177    return false;178  int64_t C = N->getSExtValue();179  // Skip if C is simm12, an lui, or can be optimized by the PatLeaf AddiPair.180  return !isInt<13>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 2>(C);181}], SimmShiftRightBy2XForm>;182 183def CSImm12MulBy8 : PatLeaf<(imm), [{184  if (!N->hasOneUse())185    return false;186  int64_t C = N->getSExtValue();187  // Skip if C is simm12, an lui or can be optimized by the PatLeaf AddiPair or188  // CSImm12MulBy4.189  return !isInt<14>(C) && !isShiftedInt<20, 12>(C) && isShiftedInt<12, 3>(C);190}], SimmShiftRightBy3XForm>;191 192// Pattern to exclude simm12 immediates from matching, namely `non_imm12`.193// GISel currently doesn't support PatFrag for leaf nodes, so `non_imm12`194// cannot be implemented in that way. To reuse patterns between the two195// ISels, we instead create PatFrag on operators that use `non_imm12`.196class binop_with_non_imm12<SDPatternOperator binop>197  : PatFrag<(ops node:$x, node:$y), (binop node:$x, node:$y), [{198  auto *C = dyn_cast<ConstantSDNode>(Operands[1]);199  return !C || !isInt<12>(C->getSExtValue());200}]> {201  let PredicateCodeUsesOperands = 1;202  let GISelPredicateCode = [{203    const MachineOperand &ImmOp = *Operands[1];204 205    if (ImmOp.isReg() && ImmOp.getReg())206      if (auto Val = getIConstantVRegValWithLookThrough(ImmOp.getReg(), MRI)) {207        // We do NOT want immediates that fit in 12 bits.208        return !isInt<12>(Val->Value.getSExtValue());209      }210 211    return true;212  }];213}214def add_non_imm12       : binop_with_non_imm12<add>;215def add_like_non_imm12 : binop_with_non_imm12<add_like>;216 217def Shifted32OnesMask : IntImmLeaf<XLenVT, [{218  if (!Imm.isShiftedMask())219    return false;220 221  unsigned TrailingZeros = Imm.countr_zero();222  return TrailingZeros > 0 && TrailingZeros < 32 &&223         Imm == UINT64_C(0xFFFFFFFF) << TrailingZeros;224}], TrailingZeros>;225 226def sh1add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<1>", [], [], 6>;227def sh2add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<2>", [], [], 6>;228def sh3add_op : ComplexPattern<XLenVT, 1, "selectSHXADDOp<3>", [], [], 6>;229def gi_sh1add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<1>">,230                   GIComplexPatternEquiv<sh1add_op>;231def gi_sh2add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<2>">,232                   GIComplexPatternEquiv<sh2add_op>;233def gi_sh3add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<3>">,234                   GIComplexPatternEquiv<sh3add_op>;235 236 237def sh1add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<1>", [], [], 6>;238def sh2add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<2>", [], [], 6>;239def sh3add_uw_op : ComplexPattern<XLenVT, 1, "selectSHXADD_UWOp<3>", [], [], 6>;240def gi_sh1add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<1>">,241                      GIComplexPatternEquiv<sh1add_uw_op>;242def gi_sh2add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<2>">,243                      GIComplexPatternEquiv<sh2add_uw_op>;244def gi_sh3add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<3>">,245                      GIComplexPatternEquiv<sh3add_uw_op>;246 247//===----------------------------------------------------------------------===//248// Instruction class templates249//===----------------------------------------------------------------------===//250 251let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in252class RVBUnaryR<bits<7> funct7, bits<3> funct3,253                RISCVOpcode opcode, string opcodestr>254    : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),255              opcodestr, "$rd, $rs1"> {256  let rs2 = 0;257}258 259let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in260class RVBShift_ri<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,261                  string opcodestr>262    : RVInstIShift<imm11_7, funct3, opcode, (outs GPR:$rd),263                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,264                   "$rd, $rs1, $shamt">;265 266//===----------------------------------------------------------------------===//267// Instructions268//===----------------------------------------------------------------------===//269 270let Predicates = [HasStdExtZbbOrZbkb] in {271def ANDN  : ALU_rr<0b0100000, 0b111, "andn">,272            Sched<[WriteIALU, ReadIALU, ReadIALU]>;273def ORN   : ALU_rr<0b0100000, 0b110, "orn">,274            Sched<[WriteIALU, ReadIALU, ReadIALU]>;275def XNOR  : ALU_rr<0b0100000, 0b100, "xnor", Commutable=1>,276            Sched<[WriteIALU, ReadIALU, ReadIALU]>;277} // Predicates = [HasStdExtZbbOrZbkb]278 279let Predicates = [HasStdExtZbaOrP] in280def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,281             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;282let Predicates = [HasStdExtZba] in {283def SH2ADD : ALU_rr<0b0010000, 0b100, "sh2add">,284             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;285def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,286             Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;287} // Predicates = [HasStdExtZba]288 289let Predicates = [HasStdExtZba, IsRV64] in {290def SLLI_UW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,291              Sched<[WriteShiftImm32, ReadShiftImm32]>;292def ADD_UW : ALUW_rr<0b0000100, 0b000, "add.uw">,293             Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;294def SH1ADD_UW : ALUW_rr<0b0010000, 0b010, "sh1add.uw">,295                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;296def SH2ADD_UW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,297                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;298def SH3ADD_UW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,299                Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;300} // Predicates = [HasStdExtZba, IsRV64]301 302let Predicates = [HasStdExtZbbOrZbkb] in {303def ROL   : ALU_rr<0b0110000, 0b001, "rol">,304            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;305def ROR   : ALU_rr<0b0110000, 0b101, "ror">,306            Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;307 308def RORI  : Shift_ri<0b01100, 0b101, "rori">,309            Sched<[WriteRotateImm, ReadRotateImm]>;310} // Predicates = [HasStdExtZbbOrZbkb]311 312let Predicates = [HasStdExtZbbOrZbkb, IsRV64], IsSignExtendingOpW = 1 in {313def ROLW  : ALUW_rr<0b0110000, 0b001, "rolw">,314            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;315def RORW  : ALUW_rr<0b0110000, 0b101, "rorw">,316            Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;317 318def RORIW : ShiftW_ri<0b0110000, 0b101, "roriw">,319            Sched<[WriteRotateImm32, ReadRotateImm32]>;320} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]321 322let Predicates = [HasStdExtZbs] in {323def BCLR : ALU_rr<0b0100100, 0b001, "bclr">,324           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;325def BSET : ALU_rr<0b0010100, 0b001, "bset">,326           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;327def BINV : ALU_rr<0b0110100, 0b001, "binv">,328           Sched<[WriteSingleBit, ReadSingleBit, ReadSingleBit]>;329let IsSignExtendingOpW = 1 in330def BEXT : ALU_rr<0b0100100, 0b101, "bext">,331           Sched<[WriteBEXT, ReadSingleBit, ReadSingleBit]>;332 333def BCLRI : Shift_ri<0b01001, 0b001, "bclri">,334            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;335def BSETI : Shift_ri<0b00101, 0b001, "bseti">,336            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;337def BINVI : Shift_ri<0b01101, 0b001, "binvi">,338            Sched<[WriteSingleBitImm, ReadSingleBitImm]>;339let IsSignExtendingOpW = 1 in340def BEXTI : Shift_ri<0b01001, 0b101, "bexti">,341            Sched<[WriteBEXTI, ReadSingleBitImm]>;342} // Predicates = [HasStdExtZbs]343 344// These instructions were named xperm.n and xperm.b in the last version of345// the draft bit manipulation specification they were included in. However, we346// use the mnemonics given to them in the ratified Zbkx extension.347let Predicates = [HasStdExtZbkx] in {348def XPERM4 : ALU_rr<0b0010100, 0b010, "xperm4">,349             Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;350def XPERM8 : ALU_rr<0b0010100, 0b100, "xperm8">,351             Sched<[WriteXPERM, ReadXPERM, ReadXPERM]>;352} // Predicates = [HasStdExtZbkx]353 354let Predicates = [HasStdExtZbbOrP], IsSignExtendingOpW = 1 in355def CLZ  : Unary_r<0b011000000000, 0b001, "clz">,356           Sched<[WriteCLZ, ReadCLZ]>;357let Predicates = [HasStdExtZbb], IsSignExtendingOpW = 1 in {358def CTZ  : Unary_r<0b011000000001, 0b001, "ctz">,359           Sched<[WriteCTZ, ReadCTZ]>;360def CPOP : Unary_r<0b011000000010, 0b001, "cpop">,361           Sched<[WriteCPOP, ReadCPOP]>;362} // Predicates = [HasStdExtZbb]363 364let Predicates = [HasStdExtZbbOrP, IsRV64], IsSignExtendingOpW = 1 in365def CLZW  : UnaryW_r<0b011000000000, 0b001, "clzw">,366            Sched<[WriteCLZ32, ReadCLZ32]>;367let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {368def CTZW  : UnaryW_r<0b011000000001, 0b001, "ctzw">,369            Sched<[WriteCTZ32, ReadCTZ32]>;370def CPOPW : UnaryW_r<0b011000000010, 0b001, "cpopw">,371            Sched<[WriteCPOP32, ReadCPOP32]>;372} // Predicates = [HasStdExtZbb, IsRV64]373 374let Predicates = [HasStdExtZbbOrP], IsSignExtendingOpW = 1 in {375def SEXT_B : Unary_r<0b011000000100, 0b001, "sext.b">,376             Sched<[WriteIALU, ReadIALU]>;377def SEXT_H : Unary_r<0b011000000101, 0b001, "sext.h">,378             Sched<[WriteIALU, ReadIALU]>;379} // Predicates = [HasStdExtZbbOrP]380 381let Predicates = [HasStdExtZbc] in {382def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr", Commutable=1>,383             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;384} // Predicates = [HasStdExtZbc]385 386let Predicates = [HasStdExtZbcOrZbkc] in {387def CLMUL  : ALU_rr<0b0000101, 0b001, "clmul", Commutable=1>,388             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;389def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh", Commutable=1>,390             Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>;391} // Predicates = [HasStdExtZbcOrZbkc]392 393let Predicates = [HasStdExtZbbOrP] in {394def MIN  : ALU_rr<0b0000101, 0b100, "min", Commutable=1>,395           Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;396def MINU : ALU_rr<0b0000101, 0b101, "minu", Commutable=1>,397           Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;398def MAX  : ALU_rr<0b0000101, 0b110, "max", Commutable=1>,399           Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;400def MAXU : ALU_rr<0b0000101, 0b111, "maxu", Commutable=1>,401           Sched<[WriteIMinMax, ReadIMinMax, ReadIMinMax]>;402} // Predicates = [HasStdExtZbbOrP]403 404let Predicates = [HasStdExtZbkbOrP] in405def PACK  : ALU_rr<0b0000100, 0b100, "pack">,406            Sched<[WritePACK, ReadPACK, ReadPACK]>;407let Predicates = [HasStdExtZbkb] in {408let IsSignExtendingOpW = 1 in409def PACKH : ALU_rr<0b0000100, 0b111, "packh">,410            Sched<[WritePACK, ReadPACK, ReadPACK]>;411} // Predicates = [HasStdExtZbkb]412 413let Predicates = [HasStdExtZbkb, IsRV64], IsSignExtendingOpW = 1 in414def PACKW  : ALUW_rr<0b0000100, 0b100, "packw">,415             Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;416 417let Predicates = [HasStdExtZbb, IsRV32] in {418def ZEXT_H_RV32 : RVBUnaryR<0b0000100, 0b100, OPC_OP, "zext.h">,419                  Sched<[WriteIALU, ReadIALU]>;420} // Predicates = [HasStdExtZbb, IsRV32]421 422let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {423def ZEXT_H_RV64 : RVBUnaryR<0b0000100, 0b100, OPC_OP_32, "zext.h">,424                  Sched<[WriteIALU, ReadIALU]>;425} // Predicates = [HasStdExtZbb, IsRV64]426 427let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV32] in {428def REV8_RV32 : Unary_r<0b011010011000, 0b101, "rev8">,429                Sched<[WriteREV8, ReadREV8]>;430} // Predicates = [HasStdExtZbbOrZbkbOrP, IsRV32]431 432let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV64] in {433def REV8_RV64 : Unary_r<0b011010111000, 0b101, "rev8">,434                Sched<[WriteREV8, ReadREV8]>;435} // Predicates = [HasStdExtZbbOrZbkbOrP, IsRV64]436 437let Predicates = [HasStdExtZbb] in {438def ORC_B : Unary_r<0b001010000111, 0b101, "orc.b">,439            Sched<[WriteORCB, ReadORCB]>;440} // Predicates = [HasStdExtZbb]441 442let Predicates = [HasStdExtZbkb] in443def BREV8 : Unary_r<0b011010000111, 0b101, "brev8">,444            Sched<[WriteBREV8, ReadBREV8]>;445 446let Predicates = [HasStdExtZbkb, IsRV32] in {447def ZIP_RV32   : Unary_r<0b000010001111, 0b001, "zip">,448                 Sched<[WriteZIP, ReadZIP]>;449def UNZIP_RV32 : Unary_r<0b000010001111, 0b101, "unzip">,450                 Sched<[WriteZIP, ReadZIP]>;451} // Predicates = [HasStdExtZbkb, IsRV32]452 453 454//===----------------------------------------------------------------------===//455// Pseudo Instructions456//===----------------------------------------------------------------------===//457 458let Predicates = [HasStdExtZba, IsRV64] in {459def : InstAlias<"zext.w $rd, $rs", (ADD_UW GPR:$rd, GPR:$rs, X0)>;460} // Predicates = [HasStdExtZba, IsRV64]461 462let Predicates = [HasStdExtZbbOrZbkb] in {463def : InstAlias<"ror $rd, $rs1, $shamt",464                (RORI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;465} // Predicates = [HasStdExtZbbOrZbkb]466 467let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {468def : InstAlias<"rorw $rd, $rs1, $shamt",469                (RORIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;470} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]471 472let Predicates = [HasStdExtZbs] in {473def : InstAlias<"bset $rd, $rs1, $shamt",474                (BSETI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;475def : InstAlias<"bclr $rd, $rs1, $shamt",476                (BCLRI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;477def : InstAlias<"binv $rd, $rs1, $shamt",478                (BINVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;479def : InstAlias<"bext $rd, $rs1, $shamt",480                (BEXTI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;481} // Predicates = [HasStdExtZbs]482 483let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in {484def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;485} // Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32]486 487let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in {488def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;489} // Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64]490 491//===----------------------------------------------------------------------===//492// Codegen patterns493//===----------------------------------------------------------------------===//494 495def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;496 497let Predicates = [HasStdExtZbbOrZbkb] in {498def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;499def : Pat<(XLenVT (or  GPR:$rs1, (not GPR:$rs2))), (ORN  GPR:$rs1, GPR:$rs2)>;500def : Pat<(XLenVT (not (riscv_xor_like GPR:$rs1, GPR:$rs2))),501          (XNOR GPR:$rs1, GPR:$rs2)>;502 503def : Pat<(XLenVT (and GPR:$rs1, invLogicImm:$rs2)), (ANDN GPR:$rs1, invLogicImm:$rs2)>;504def : Pat<(XLenVT (or  GPR:$rs1, invLogicImm:$rs2)), (ORN  GPR:$rs1, invLogicImm:$rs2)>;505def : Pat<(XLenVT (xor GPR:$rs1, invLogicImm:$rs2)), (XNOR GPR:$rs1, invLogicImm:$rs2)>;506} // Predicates = [HasStdExtZbbOrZbkb]507 508let Predicates = [HasStdExtZbbOrZbkb] in {509def : PatGprShiftMaskXLen<rotl, ROL>;510def : PatGprShiftMaskXLen<rotr, ROR>;511 512def : PatGprImm<rotr, RORI, uimmlog2xlen>;513// There's no encoding for roli in the the 'B' extension as it can be514// implemented with rori by negating the immediate.515def : Pat<(XLenVT (rotl GPR:$rs1, uimmlog2xlen:$shamt)),516          (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;517} // Predicates = [HasStdExtZbbOrZbkb]518 519let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {520def : PatGprShiftMask32<riscv_rolw, ROLW>;521def : PatGprShiftMask32<riscv_rorw, RORW>;522def : PatGprImm<riscv_rorw, RORIW, uimm5>;523def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),524          (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;525} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]526 527let Predicates = [HasStdExtZbs] in {528def : Pat<(XLenVT (and (not (shl 1, shiftMaskXLen:$rs2)), GPR:$rs1)),529          (BCLR GPR:$rs1, shiftMaskXLen:$rs2)>;530def : Pat<(XLenVT (and (rotl -2, shiftMaskXLen:$rs2), GPR:$rs1)),531          (BCLR GPR:$rs1, shiftMaskXLen:$rs2)>;532def : Pat<(XLenVT (or (shl 1, shiftMaskXLen:$rs2), GPR:$rs1)),533          (BSET GPR:$rs1, shiftMaskXLen:$rs2)>;534def : Pat<(XLenVT (xor (shl 1, shiftMaskXLen:$rs2), GPR:$rs1)),535          (BINV GPR:$rs1, shiftMaskXLen:$rs2)>;536def : Pat<(XLenVT (and (srl GPR:$rs1, shiftMaskXLen:$rs2), 1)),537          (BEXT GPR:$rs1, shiftMaskXLen:$rs2)>;538 539def : Pat<(XLenVT (shl 1, shiftMaskXLen:$rs2)),540          (BSET (XLenVT X0), shiftMaskXLen:$rs2)>;541def : Pat<(XLenVT (not (shl -1, shiftMaskXLen:$rs2))),542          (ADDI (XLenVT (BSET (XLenVT X0), shiftMaskXLen:$rs2)), -1)>;543 544def : Pat<(XLenVT (and GPR:$rs1, BCLRMask:$mask)),545          (BCLRI GPR:$rs1, BCLRMask:$mask)>;546def : Pat<(XLenVT (or GPR:$rs1, SingleBitSetMask:$mask)),547          (BSETI GPR:$rs1, SingleBitSetMask:$mask)>;548def : Pat<(XLenVT (xor GPR:$rs1, SingleBitSetMask:$mask)),549          (BINVI GPR:$rs1, SingleBitSetMask:$mask)>;550 551def : Pat<(XLenVT (and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1))),552          (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;553 554def : Pat<(XLenVT (seteq (XLenVT (and GPR:$rs1, SingleBitSetMask:$mask)), 0)),555          (BEXTI (XLenVT (XORI GPR:$rs1, -1)), SingleBitSetMask:$mask)>;556 557def : Pat<(XLenVT (or GPR:$r, BSETINVTwoBitsMask:$i)),558          (BSETI (XLenVT (BSETI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i))),559                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;560def : Pat<(XLenVT (xor GPR:$r, BSETINVTwoBitsMask:$i)),561          (BINVI (XLenVT (BINVI GPR:$r, (TrailingZeros BSETINVTwoBitsMask:$i))),562                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;563def : Pat<(XLenVT (or GPR:$r, BSETINVORIMask:$i)),564          (BSETI (XLenVT (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i))),565                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;566def : Pat<(XLenVT (xor GPR:$r, BSETINVORIMask:$i)),567          (BINVI (XLenVT (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i))),568                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;569def : Pat<(XLenVT (and GPR:$r, BCLRITwoBitsMask:$i)),570          (BCLRI (XLenVT (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i))),571                 (BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;572def : Pat<(XLenVT (and GPR:$r, BCLRIANDIMask:$i)),573          (BCLRI (XLenVT (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i))),574                 (BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;575} // Predicates = [HasStdExtZbs]576 577let Predicates = [HasStdExtZbs, IsRV64] in {578// If the original code was setting, clearing, or inverting bit 31 of an i32,579// type legalization might have sign extended the constant so it doesn't have a580// single 0 or 1 bit. If the upper 32 bits aren't used by later instructions we581// can still use bseti/bclri.582def : Pat<(binop_allwusers<and> GPR:$rs1, (XLenVT 2147483647)),583          (BCLRI GPR:$rs1, 31)>;584def : Pat<(binop_allwusers<or> GPR:$rs1, (XLenVT -2147483648)),585          (BSETI GPR:$rs1, 31)>;586def : Pat<(binop_allwusers<xor> GPR:$rs1, (XLenVT -2147483648)),587          (BINVI GPR:$rs1, 31)>;588}589 590let Predicates = [HasStdExtZbb] in591def : PatGpr<riscv_orc_b, ORC_B>;592 593let Predicates = [HasStdExtZbkb] in594def : PatGpr<riscv_brev8, BREV8>;595 596let Predicates = [HasStdExtZbkb, IsRV32] in {597// We treat zip and unzip as separate instructions, so match it directly.598def : PatGpr<riscv_zip, ZIP_RV32, i32>;599def : PatGpr<riscv_unzip, UNZIP_RV32, i32>;600} // Predicates = [HasStdExtZbkb, IsRV32]601 602let Predicates = [HasStdExtZbbOrP] in {603def : PatGpr<ctlz, CLZ>;604}605 606let Predicates = [HasStdExtZbb] in {607def : PatGpr<cttz, CTZ>;608def : PatGpr<ctpop, CPOP>;609} // Predicates = [HasStdExtZbb]610 611let Predicates = [HasStdExtZbbOrP, IsRV64] in {612def : PatGpr<riscv_clzw, CLZW>;613}614 615let Predicates = [HasStdExtZbb, IsRV64] in {616def : PatGpr<riscv_ctzw, CTZW>;617def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;618 619def : Pat<(i64 (riscv_negw_max GPR:$rs1)),620          (MAX GPR:$rs1, (XLenVT (SUBW (XLenVT X0), GPR:$rs1)))>;621} // Predicates = [HasStdExtZbb, IsRV64]622 623let Predicates = [HasStdExtZbbOrP] in {624def : Pat<(XLenVT (sext_inreg GPR:$rs1, i8)), (SEXT_B GPR:$rs1)>;625def : Pat<(XLenVT (sext_inreg GPR:$rs1, i16)), (SEXT_H GPR:$rs1)>;626} // Predicates = [HasStdExtZbb]627 628let Predicates = [HasStdExtZbbOrP] in {629def : PatGprGpr<smin, MIN>;630def : PatGprGpr<smax, MAX>;631def : PatGprGpr<umin, MINU>;632def : PatGprGpr<umax, MAXU>;633} // Predicates = [HasStdExtZbb]634 635let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV32] in636def : PatGpr<bswap, REV8_RV32, i32>;637 638let Predicates = [HasStdExtZbbOrZbkbOrP, IsRV64] in639def : PatGpr<bswap, REV8_RV64, i64>;640 641let Predicates = [HasStdExtZbkb] in {642def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),643              zexti8:$rs1),644          (PACKH zexti8:$rs1, GPR:$rs2)>;645def : Pat<(or (shl zexti8:$rs2, (XLenVT 8)),646              zexti8:$rs1),647          (PACKH zexti8:$rs1, zexti8:$rs2)>;648def : Pat<(and (or (shl GPR:$rs2, (XLenVT 8)),649                   zexti8:$rs1), 0xFFFF),650          (PACKH zexti8:$rs1, GPR:$rs2)>;651 652def : Pat<(binop_allhusers<or> (shl GPR:$rs2, (XLenVT 8)),653                               zexti8:$rs1),654          (PACKH zexti8:$rs1, GPR:$rs2)>;655} // Predicates = [HasStdExtZbkb]656 657let Predicates = [HasStdExtZbkb, IsRV32] in {658def : Pat<(i32 (or zexti16:$rs1, (shl GPR:$rs2, (i32 16)))),659          (PACK zexti16:$rs1, GPR:$rs2)>;660 661def : Pat<(i32 (or (shl GPR:$rs2, (XLenVT 24)),662                   (shl zexti8:$rs1, (XLenVT 16)))),663          (SLLI (XLenVT (PACKH zexti8:$rs1, GPR:$rs2)), (XLenVT 16))>;664 665// Match a pattern of 2 bytes being inserted into bits [31:16], with bits666// bits [15:0] coming from a zero extended value. We can use pack with packh for667// bits [31:16]. If bits [15:0] can also be a packh, it can be matched668// separately.669def : Pat<(i32 (or (or (shl GPR:$op1rs2, (XLenVT 24)),670                       (shl zexti8:$op1rs1, (XLenVT 16))),671                   zexti16:$rs1)),672          (PACK zexti16:$rs1,673                (XLenVT (PACKH zexti8:$op1rs1, GPR:$op1rs2)))>;674}675 676let Predicates = [HasStdExtZbkb, IsRV64] in {677def : Pat<(i64 (or zexti32:$rs1, (shl GPR:$rs2, (i64 32)))),678          (PACK zexti32:$rs1, GPR:$rs2)>;679 680def : Pat<(i64 (or (shl zexti8:$rs2, (XLenVT 24)),681                   (shl zexti8:$rs1, (XLenVT 16)))),682          (SLLI (XLenVT (PACKH zexti8:$rs1, zexti8:$rs2)), (XLenVT 16))>;683def : Pat<(binop_allwusers<or> (shl GPR:$rs2, (XLenVT 24)),684                               (shl zexti8:$rs1, (XLenVT 16))),685          (SLLI (XLenVT (PACKH zexti8:$rs1, GPR:$rs2)), (XLenVT 16))>;686 687def : Pat<(binop_allwusers<or> (shl GPR:$rs2, (i64 16)),688                               zexti16:$rs1),689          (PACKW zexti16:$rs1, GPR:$rs2)>;690def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),691                   zexti16:$rs1)),692          (PACKW zexti16:$rs1, GPR:$rs2)>;693 694// Match a pattern of 2 bytes being inserted into bits [31:16], with bits695// bits [15:0] coming from a zero extended value, and bits [63:32] being696// ignored. We can use packw with packh for bits [31:16]. If bits [15:0] can697// also be a packh, it can be matched separately.698def : Pat<(binop_allwusers<or>699               (or (shl GPR:$op1rs2, (XLenVT 24)),700                   (shl zexti8:$op1rs1, (XLenVT 16))),701               zexti16:$rs1),702          (PACKW zexti16:$rs1, (XLenVT (PACKH zexti8:$op1rs1, GPR:$op1rs2)))>;703// We need to manually reassociate the patterns because of the binop_allwusers.704def : Pat<(binop_allwusers<or>705               (or zexti16:$rs1,706                   (shl zexti8:$op1rs1, (XLenVT 16))),707               (shl GPR:$op1rs2, (XLenVT 24))),708          (PACKW zexti16:$rs1, (XLenVT (PACKH zexti8:$op1rs1, GPR:$op1rs2)))>;709def : Pat<(binop_allwusers<or>710               (or zexti16:$rs1,711                   (shl GPR:$op1rs2, (XLenVT 24))),712               (shl zexti8:$op1rs1, (XLenVT 16))),713          (PACKW zexti16:$rs1, (XLenVT (PACKH zexti8:$op1rs1, GPR:$op1rs2)))>;714 715def : Pat<(i64 (or (or (zexti16 (XLenVT GPR:$rs1)),716                       (shl zexti8:$op1rs1, (XLenVT 16))),717                   (sext_inreg (shl GPR:$op1rs2, (XLenVT 24)), i32))),718          (PACKW GPR:$rs1, (XLenVT (PACKH zexti8:$op1rs1, GPR:$op1rs2)))>;719 720// Match a pattern of 2 halfwords being inserted into bits [63:32], with bits721// bits [31:0] coming from a zero extended value. We can use pack with packw for722// bits [63:32]. If bits [63:31] can also be a packw, it can be matched723// separately.724def : Pat<(or (or (shl GPR:$op1rs2, (i64 48)),725                  (shl zexti16:$op1rs1, (i64 32))),726              zexti32:$rs1),727          (PACK zexti32:$rs1,728                (XLenVT (PACKW zexti16:$op1rs1, GPR:$op1rs2)))>;729} // Predicates = [HasStdExtZbkb, IsRV64]730 731let Predicates = [HasStdExtZbb, IsRV32] in732def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;733let Predicates = [HasStdExtZbb, IsRV64] in734def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;735 736let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in737def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (PACK GPR:$rs, (XLenVT X0))>;738let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in739def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (PACKW GPR:$rs, (XLenVT X0))>;740 741multiclass ShxAddPat<int i, Instruction shxadd> {742  def : Pat<(XLenVT (add_like_non_imm12 (shl GPR:$rs1, (XLenVT i)), GPR:$rs2)),743            (shxadd GPR:$rs1, GPR:$rs2)>;744  def : Pat<(XLenVT (riscv_shl_add GPR:$rs1, (XLenVT i), GPR:$rs2)),745            (shxadd GPR:$rs1, GPR:$rs2)>;746 747  defvar pat = !cast<ComplexPattern>("sh"#i#"add_op");748  // More complex cases use a ComplexPattern.749  def : Pat<(XLenVT (add_like_non_imm12 pat:$rs1, GPR:$rs2)),750            (shxadd pat:$rs1, GPR:$rs2)>;751}752 753class CSImm12MulBy4Pat<Instruction sh2add>754    : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),755          (sh2add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),756                  GPR:$r)>;757 758class CSImm12MulBy8Pat<Instruction sh3add>759    : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),760          (sh3add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),761                  GPR:$r)>;762 763let Predicates = [HasStdExtZba] in {764foreach i = {1,2,3} in {765  defvar shxadd = !cast<Instruction>("SH"#i#"ADD");766  defm : ShxAddPat<i, shxadd>;767}768 769def : CSImm12MulBy4Pat<SH2ADD>;770def : CSImm12MulBy8Pat<SH3ADD>;771} // Predicates = [HasStdExtZba]772 773def zExtImm32 : ComplexPattern<i64, 1, "selectZExtImm32", [], [], 0>;774 775multiclass ADD_UWPat<Instruction add_uw> {776  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),777            (add_uw GPR:$rs1, GPR:$rs2)>;778  def : Pat<(i64 (add_like zExtImm32:$rs1, GPR:$rs2)),779            (add_uw zExtImm32:$rs1, GPR:$rs2)>;780  def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (add_uw GPR:$rs, (XLenVT X0))>;781}782 783multiclass ShxAdd_UWPat<int i, Instruction shxadd_uw> {784  def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)),785                                     (XLenVT GPR:$rs2))),786            (shxadd_uw GPR:$rs1, GPR:$rs2)>;787  def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),788            (shxadd_uw GPR:$rs1, GPR:$rs2)>;789 790  defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");791  // More complex cases use a ComplexPattern.792  def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),793            (shxadd_uw pat:$rs1, GPR:$rs2)>;794}795 796multiclass Sh1Add_UWPat<Instruction sh1add_uw> {797  def : Pat<(add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), (i64 0x1FFFFFFFF)),798                                     (XLenVT GPR:$rs2)),799            (sh1add_uw GPR:$rs1, GPR:$rs2)>;800  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.801  def : Pat<(add_like_non_imm12 (and GPR:$rs1, (i64 0x1FFFFFFFE)),802                                (XLenVT GPR:$rs2)),803            (sh1add_uw (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;804}805 806multiclass Sh2Add_UWPat<Instruction sh2add_uw> {807  def : Pat<(add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), (i64 0x3FFFFFFFF)),808                                (XLenVT GPR:$rs2)),809            (sh2add_uw GPR:$rs1, GPR:$rs2)>;810  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.811  def : Pat<(add_like_non_imm12 (and GPR:$rs1, (i64 0x3FFFFFFFC)),812                                (XLenVT GPR:$rs2)),813            (sh2add_uw (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;814}815 816multiclass Sh3Add_UWPat<Instruction sh3add_uw> {817  def : Pat<(add_like_non_imm12 (and (shl GPR:$rs1, (i64 3)), (i64 0x7FFFFFFFF)),818                                (XLenVT GPR:$rs2)),819            (sh3add_uw GPR:$rs1, GPR:$rs2)>;820  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.821  def : Pat<(add_like_non_imm12 (and GPR:$rs1, (i64 0x7FFFFFFF8)),822                                (XLenVT GPR:$rs2)),823            (sh3add_uw (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;824}825 826class Sh1AddPat<Instruction sh1add>827    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE),828                                   (XLenVT GPR:$rs2))),829          (sh1add (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;830 831class Sh2AddPat<Instruction sh2add>832    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC),833                                   (XLenVT GPR:$rs2))),834          (sh2add (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;835 836class Sh3AddPat<Instruction sh3add>837    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),838                                   (XLenVT GPR:$rs2))),839          (sh3add (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;840 841let Predicates = [HasStdExtZba, IsRV64] in {842def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),843          (SLLI_UW GPR:$rs1, uimm5:$shamt)>;844// Match a shifted 0xffffffff mask. Use SRLI to clear the LSBs and SLLI_UW to845// mask and shift.846def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),847          (SLLI_UW (XLenVT (SRLI GPR:$rs1, Shifted32OnesMask:$mask)),848                   Shifted32OnesMask:$mask)>;849 850defm : ADD_UWPat<ADD_UW>;851 852foreach i = {1,2,3} in {853  defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");854  defm : ShxAdd_UWPat<i, shxadd_uw>;855}856 857defm : Sh1Add_UWPat<SH1ADD_UW>;858defm : Sh2Add_UWPat<SH2ADD_UW>;859defm : Sh3Add_UWPat<SH3ADD_UW>;860 861def : Sh1AddPat<SH1ADD>;862def : Sh2AddPat<SH2ADD>;863def : Sh3AddPat<SH3ADD>;864} // Predicates = [HasStdExtZba, IsRV64]865 866let Predicates = [HasStdExtZbcOrZbkc] in {867def : PatGprGpr<riscv_clmul, CLMUL>;868def : PatGprGpr<riscv_clmulh, CLMULH>;869} // Predicates = [HasStdExtZbcOrZbkc]870 871let Predicates = [HasStdExtZbc] in872def : PatGprGpr<riscv_clmulr, CLMULR>;873 874let Predicates = [HasStdExtZbkx] in {875def : PatGprGpr<int_riscv_xperm4, XPERM4>;876def : PatGprGpr<int_riscv_xperm8, XPERM8>;877} // Predicates = [HasStdExtZbkx]878