brintos

brintos / llvm-project-archived public Read only

0
0
Text · 78.1 KiB · 13ceead Raw
1926 lines · plain
1//===---------------- RISCVInstrInfoXQci.td ----------------*- 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 vendor extensions defined by QUALCOMM.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// Operand and SDNode transformation definitions.15//===----------------------------------------------------------------------===//16 17def SDT_SetMultiple : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,18                                           SDTCisSameAs<1, 3>,19                                           SDTCisPtrTy<2>,20                                           SDTCisVT<3, XLenVT>]>;21 22def qc_setwmi : RVSDNode<"QC_SETWMI", SDT_SetMultiple,23                         [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;24 25def qc_insb : RVSDNode<"QC_INSB", SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,26                                                       SDTCisSameAs<0, 2>,27                                                       SDTCisVT<0, i32>,28                                                       SDTCisInt<3>,29                                                       SDTCisInt<4>]>,30                       []>;31 32def qc_e_li : RVSDNode<"QC_E_LI", SDTIntUnaryOp>;33 34def uimm5nonzero : RISCVOp<XLenVT>,35                   ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {36  let ParserMatchClass = UImmAsmOperand<5, "NonZero">;37  let DecoderMethod = "decodeUImmNonZeroOperand<5>";38  let OperandType = "OPERAND_UIMM5_NONZERO";39  let MCOperandPredicate = [{40    int64_t Imm;41    if (!MCOp.evaluateAsConstantImm(Imm))42      return false;43    return (Imm != 0) && isUInt<5>(Imm);;44  }];45}46 47def tuimm5nonzero : TImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]>;48 49def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,50  [{return (Imm > 3) && isUInt<5>(Imm);}]> {51  let ParserMatchClass = UImmAsmOperand<5, "GT3">;52  let DecoderMethod = "decodeUImmOperandGE<5, 4>";53  let OperandType = "OPERAND_UIMM5_GT3";54}55 56def tuimm5gt3 : TImmLeaf<XLenVT, [{return (Imm > 3) && isUInt<5>(Imm);}]>;57 58def UImm5Plus1AsmOperand : AsmOperandClass {59  let Name = "UImm5Plus1";60  let RenderMethod = "addImmOperands";61  let DiagnosticType = "InvalidUImm5Plus1";62}63 64def uimm5_plus1 : RISCVOp, ImmLeaf<XLenVT,65  [{return (isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32);}]> {66  let ParserMatchClass = UImm5Plus1AsmOperand;67  let EncoderMethod = "getImmOpValueMinus1";68  let DecoderMethod = "decodeUImmPlus1Operand<5>";69  let OperandType = "OPERAND_UIMM5_PLUS1";70  let MCOperandPredicate = [{71    int64_t Imm;72    if (!MCOp.evaluateAsConstantImm(Imm))73      return false;74    return (isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32);75  }];76}77 78def uimm5ge6_plus1 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,79  [{return (Imm >= 6) && (isUInt<5>(Imm) || (Imm == 32));}]> {80  let ParserMatchClass = UImmAsmOperand<5, "GE6Plus1">;81  let EncoderMethod = "getImmOpValueMinus1";82  let DecoderMethod = "decodeUImmPlus1OperandGE<5,6>";83  let OperandType = "OPERAND_UIMM5_GE6_PLUS1";84  let MCOperandPredicate = [{85    int64_t Imm;86    if (!MCOp.evaluateAsConstantImm(Imm))87      return false;88    return (Imm >= 6) && (isUInt<5>(Imm) || (Imm == 32));89  }];90}91 92def uimm5slist : RISCVOp<XLenVT>, ImmLeaf<XLenVT,93  [{return ((Imm == 0)  ||94            (Imm == 1)  ||95            (Imm == 2)  ||96            (Imm == 4)  ||97            (Imm == 8)  ||98            (Imm == 16) ||99            (Imm == 15) ||100            (Imm == 31));}]> {101  let ParserMatchClass = UImmAsmOperand<5, "Slist">;102  let EncoderMethod = "getImmOpValueSlist";103  let DecoderMethod = "decodeUImmSlistOperand";104  let OperandType = "OPERAND_UIMM5_SLIST";105  let MCOperandPredicate = [{106    int64_t Imm;107    if (!MCOp.evaluateAsConstantImm(Imm))108      return false;109    return ((Imm == 0)  || (Imm == 1)  ||110            (Imm == 2)  || (Imm == 4)  ||111            (Imm == 8)  || (Imm == 16) ||112            (Imm == 15) || (Imm == 31));113  }];114}115 116def tuimm7_lsb00 : TImmLeaf<XLenVT,[{return isShiftedUInt<5, 2>(Imm);}]>;117 118def uimm10 : RISCVUImmLeafOp<10>;119 120def uimm11 : RISCVUImmLeafOp<11>;121 122// A 14-bit unsigned immediate where the least significant two bits are zero.123def uimm14lsb00 : RISCVOp,124                  ImmLeaf<XLenVT, [{return isShiftedUInt<12, 2>(Imm);}]> {125  let ParserMatchClass = UImmAsmOperand<14, "Lsb00">;126  let EncoderMethod = "getImmOpValue";127  let DecoderMethod = "decodeUImmOperand<14>";128  let OperandType = "OPERAND_UIMM14_LSB00";129}130 131def uimm16nonzero : RISCVOp<XLenVT>,132                    ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<16>(Imm);}]> {133  let ParserMatchClass = UImmAsmOperand<16, "NonZero">;134  let DecoderMethod = "decodeUImmNonZeroOperand<16>";135  let OperandType = "OPERAND_UIMM16_NONZERO";136}137 138def simm5nonzero : RISCVOp<XLenVT>,139                   ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<5>(Imm);}]> {140  let ParserMatchClass = SImmAsmOperand<5, "NonZero">;141  let DecoderMethod = "decodeSImmNonZeroOperand<5>";142  let OperandType = "OPERAND_SIMM5_NONZERO";143  let MCOperandPredicate = [{144    int64_t Imm;145    if (!MCOp.evaluateAsConstantImm(Imm))146      return false;147    return (Imm != 0) && isInt<5>(Imm);148  }];149}150 151def simm11 : RISCVSImmLeafOp<11>;152 153def simm16 : RISCVSImmOp<16>;154 155def simm16nonzero : RISCVOp<XLenVT>,156                    ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<16>(Imm);}]> {157  let ParserMatchClass = SImmAsmOperand<16, "NonZero">;158  let DecoderMethod = "decodeSImmNonZeroOperand<16>";159  let OperandType = "OPERAND_SIMM16_NONZERO";160}161 162def simm20_li : RISCVOp<XLenVT>,163                ImmLeaf<XLenVT, [{return isInt<20>(Imm);}]>{164  let ParserMatchClass = SImmAsmOperand<20, "LI">;165  let EncoderMethod = "getImmOpValue";166  let DecoderMethod = "decodeSImmOperand<20>";167  let OperandType = "OPERAND_SIMM20_LI";168  let MCOperandPredicate = [{169    int64_t Imm;170    if (MCOp.evaluateAsConstantImm(Imm))171      return isInt<20>(Imm);172    return MCOp.isBareSymbolRef();173  }];174}175 176def simm26 : RISCVSImmLeafOp<26>;177 178def simm26_nosimm12 : ImmLeaf<XLenVT, [{179  return isInt<26>(Imm) && !isInt<12>(Imm);}]>;180 181def simm32_nosimm26 : ImmLeaf<XLenVT, [{182  return isInt<32>(Imm) && !isInt<26>(Imm);}]>;183 184class BareSImmNAsmOperand<int width>185    : ImmAsmOperand<"BareS", width, ""> {186  let PredicateMethod = "isBareSimmN<" # width # ">";187}188 189// 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no190// sign-/zero-extension. This is represented internally as a signed 32-bit value.191def bare_simm32 : RISCVOp<XLenVT> {192  let ParserMatchClass = BareSImmNAsmOperand<32>;193  let EncoderMethod = "getImmOpValue";194  let DecoderMethod = "decodeSImmOperand<32>";195  let OperandType = "OPERAND_BARE_SIMM32";196  let MCOperandPredicate = [{197    int64_t Imm;198    if (MCOp.evaluateAsConstantImm(Imm))199      return isInt<32>(Imm);200    return MCOp.isBareSymbolRef();201  }];202}203 204// A 32-bit signed immediate where the least significant bit is zero.205def bare_simm32_lsb0 : Operand<OtherVT> {206  let ParserMatchClass = BareSImmNLsb0AsmOperand<32>;207  let PrintMethod = "printBranchOperand";208  let EncoderMethod = "getImmOpValueAsrN<1>";209  let DecoderMethod = "decodeSImmOperandAndLslN<32, 1>";210  let MCOperandPredicate = [{211    int64_t Imm;212    if (MCOp.evaluateAsConstantImm(Imm))213      return isShiftedInt<31, 1>(Imm);214    return MCOp.isBareSymbolRef();215  }];216  let OperandType = "OPERAND_PCREL";217}218 219def AddLike: PatFrags<(ops node:$A, node:$B),220                      [(add node:$A, node:$B), (or node:$A, node:$B)], [{221    return CurDAG->isBaseWithConstantOffset(SDValue(N, 0));222}]>;223 224//===----------------------------------------------------------------------===//225// Instruction Formats226//===----------------------------------------------------------------------===//227 228 229class DirectiveInsnQC_EAI<dag outs, dag ins, string argstr>230  : RVInst48<outs, ins, "", "", [], InstFormatQC_EAI> {231  bits<7> opcode;232  bits<3> func3;233  bits<1> func1;234 235  bits<5> rd;236  bits<32> imm32;237 238  let Inst{47-16} = imm32;239  let Inst{15}    = func1;240  let Inst{14-12} = func3;241  let Inst{11-7}  = rd;242  let Inst{6-0}   = opcode;243 244  let AsmString = ".insn qc.eai " # argstr;245}246 247class DirectiveInsnQC_EI<dag outs, dag ins, string argstr>248  : RVInst48<outs, ins, "", "", [], InstFormatQC_EI> {249  bits<7> opcode;250  bits<3> func3;251  bits<2> func2;252 253  bits<5> rd;254  bits<5> rs1;255  bits<26> imm26;256 257  let Inst{47-32} = imm26{25-10};258  let Inst{31-30} = func2;259  let Inst{29-20} = imm26{9-0};260  let Inst{19-15} = rs1;261  let Inst{14-12} = func3;262  let Inst{11-7}  = rd;263  let Inst{6-0}   = opcode;264 265  let AsmString = ".insn qc.ei " # argstr;266}267 268class DirectiveInsnQC_EB<dag outs, dag ins, string argstr>269  : RVInst48<outs, ins, "", "", [], InstFormatQC_EB> {270  bits<7> opcode;271  bits<3> func3;272  bits<5> func5;273 274  bits<5> rs1;275  bits<12> imm12; // This one is the PC-relative offset276  bits<16> imm16;277 278  let Inst{47-32} = imm16;279  let Inst{31}    = imm12{11};280  let Inst{30-25} = imm12{9-4};281  let Inst{24-20} = func5;282  let Inst{19-15} = rs1;283  let Inst{14-12} = func3;284  let Inst{11-8}  = imm12{3-0};285  let Inst{7}     = imm12{10};286  let Inst{6-0}   = opcode;287 288  let AsmString = ".insn qc.eb " # argstr;289}290 291class DirectiveInsnQC_EJ<dag outs, dag ins, string argstr>292  : RVInst48<outs, ins, "", "", [], InstFormatQC_EJ> {293  bits<7> opcode;294  bits<3> func3;295  bits<2> func2;296  bits<5> func5;297 298  bits<31> imm31;299 300  let Inst{47-32} = imm31{30-15};301  let Inst{31}    = imm31{11};302  let Inst{30-25} = imm31{9-4};303  let Inst{24-20} = func5;304  let Inst{19-17} = imm31{14-12};305  let Inst{16-15} = func2;306  let Inst{14-12} = func3;307  let Inst{11-8}  = imm31{3-0};308  let Inst{7}     = imm31{10};309  let Inst{6-0}   = opcode;310 311  let AsmString = ".insn qc.ej " # argstr;312}313 314class DirectiveInsnQC_ES<dag outs, dag ins, string argstr>315  : RVInst48<outs, ins, "", "", [], InstFormatQC_ES> {316  bits<7> opcode;317  bits<3> func3;318  bits<2> func2;319 320  bits<5> rs1;321  bits<5> rs2;322  bits<26> imm26;323 324  let Inst{47-32} = imm26{25-10};325  let Inst{31-30} = func2;326  let Inst{29-25} = imm26{9-5};327  let Inst{24-20} = rs2;328  let Inst{19-15} = rs1;329  let Inst{14-12} = func3;330  let Inst{11-7}  = imm26{4-0};331  let Inst{6-0}   = opcode;332 333  let AsmString = ".insn qc.es " # argstr;334}335 336 337let isCodeGenOnly = true, hasSideEffects = true, mayLoad = true,338    mayStore = true, hasNoSchedulingInfo = true, Predicates=[IsRV32] in {339def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd),340                                     (ins uimm7_opcode:$opcode,341                                          uimm3:$func3,342                                          uimm1:$func1,343                                          bare_simm32:$imm32),344                                     "$opcode, $func3, $func1, $rd, $imm32">;345def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd),346                                   (ins uimm7_opcode:$opcode,347                                        uimm3:$func3,348                                        uimm2:$func2,349                                        AnyReg:$rs1,350                                        simm26:$imm26),351                                   "$opcode, $func3, $func2, $rd, $rs1, $imm26">;352def InsnQC_EI_Mem : DirectiveInsnQC_EI<(outs AnyReg:$rd),353                                       (ins uimm7_opcode:$opcode,354                                            uimm3:$func3,355                                            uimm2:$func2,356                                            AnyReg:$rs1,357                                            simm26:$imm26),358                                       "$opcode, $func3, $func2, $rd, ${imm26}(${rs1})">;359def InsnQC_EB : DirectiveInsnQC_EB<(outs),360                                   (ins uimm7_opcode:$opcode,361                                        uimm3:$func3,362                                        uimm5:$func5,363                                        AnyReg:$rs1,364                                        simm16:$imm16,365                                        bare_simm13_lsb0:$imm12),366                                   "$opcode, $func3, $func5, $rs1, $imm16, $imm12">;367def InsnQC_EJ : DirectiveInsnQC_EJ<(outs),368                                   (ins uimm7_opcode:$opcode,369                                        uimm3:$func3,370                                        uimm2:$func2,371                                        uimm5:$func5,372                                        bare_simm32_lsb0:$imm31),373                                   "$opcode, $func3, $func2, $func5, $imm31">;374def InsnQC_ES : DirectiveInsnQC_ES<(outs),375                                   (ins uimm7_opcode:$opcode,376                                        uimm3:$func3,377                                        uimm2:$func2,378                                        AnyReg:$rs2,379                                        AnyReg:$rs1,380                                        simm26:$imm26),381                                   "$opcode, $func3, $func2, $rs2, ${imm26}(${rs1})">;382} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo, Predicates383 384let EmitPriority = 0, Predicates = [IsRV32] in {385def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32",386                (InsnQC_EAI AnyReg:$rd,387                            uimm7_opcode:$opcode,388                            uimm3:$func3,389                            uimm1:$func1,390                            bare_simm32:$imm32)>;391def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26",392                (InsnQC_EI AnyReg:$rd,393                           uimm7_opcode:$opcode,394                           uimm3:$func3,395                           uimm2:$func2,396                           AnyReg:$rs1,397                           simm26:$imm26)>;398def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, ${imm26}(${rs1})",399                (InsnQC_EI_Mem AnyReg:$rd,400                               uimm7_opcode:$opcode,401                               uimm3:$func3,402                               uimm2:$func2,403                               AnyReg:$rs1,404                               simm26:$imm26)>;405def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, (${rs1})",406                (InsnQC_EI_Mem AnyReg:$rd,407                               uimm7_opcode:$opcode,408                               uimm3:$func3,409                               uimm2:$func2,410                               AnyReg:$rs1,411                               0)>;412def : InstAlias<".insn_qc.eb $opcode, $func3, $func5, $rs1, $imm16, $imm12",413                 (InsnQC_EB uimm7_opcode:$opcode,414                            uimm3:$func3,415                            uimm5:$func5,416                            AnyReg:$rs1,417                            simm16:$imm16,418                            bare_simm13_lsb0:$imm12)>;419def : InstAlias<".insn_qc.ej $opcode, $func3, $func2, $func5, $imm31",420                 (InsnQC_EJ uimm7_opcode:$opcode,421                            uimm3:$func3,422                            uimm2:$func2,423                            uimm5:$func5,424                            bare_simm32_lsb0:$imm31)>;425def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, ${imm26}(${rs1})",426                 (InsnQC_ES uimm7_opcode:$opcode,427                            uimm3:$func3,428                            uimm2:$func2,429                            AnyReg:$rs2,430                            AnyReg:$rs1,431                            simm26:$imm26)>;432def : InstAlias<".insn_qc.es $opcode, $func3, $func2, $rs2, (${rs1})",433                 (InsnQC_ES uimm7_opcode:$opcode,434                            uimm3:$func3,435                            uimm2:$func2,436                            AnyReg:$rs2,437                            AnyReg:$rs1,438                            0)>;439} // EmitPriority = 0, Predicates = [IsRV32]440 441//===----------------------------------------------------------------------===//442// Instruction Class Templates443//===----------------------------------------------------------------------===//444 445let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {446class QCILoad_ScaleIdx<bits<4> funct4, string opcodestr>447    : RVInstRBase<0b111, OPC_CUSTOM_0,448                  (outs GPR:$rd), (ins GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),449                  opcodestr, "$rd, $rs1, $rs2, $shamt"> {450  bits<3> shamt;451  let Inst{31-28} = funct4;452  let Inst{27-25} = shamt;453}454}455 456let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {457// rd corresponds to the source for the store 'rs3' described in the spec.458class QCIStore_ScaleIdx<bits<4> funct4, string opcodestr>459    : RVInstRBase<0b110, OPC_CUSTOM_1, (outs),460                  (ins GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),461                  opcodestr, "$rd, $rs1, $rs2, $shamt"> {462  bits<3> shamt;463  let Inst{31-28} = funct4;464  let Inst{27-25} = shamt;465}466}467 468class QCIRVInstI<bits<4> funct4, string opcodestr>469    : RVInstIUnary<{0b000, funct4, 0b00000}, 0b011, OPC_CUSTOM_0,470                   (outs GPRNoX0:$rd), (ins GPRNoX0:$rs1), opcodestr,471                   "$rd, $rs1">;472 473class QCIRVInstR<bits<4> funct4, string opcodestr>474    : RVInstR<{0b000, funct4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),475              (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {476  let rs2 = 0;477}478 479class QCIRVInstRR<bits<5> funct5, DAGOperand InTyRs1, string opcodestr>480    : RVInstR<{0b00, funct5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),481              (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;482 483class QCIRVInstRRTied<bits<5> funct5, DAGOperand InTyRs1, string opcodestr>484    : RVInstR<{0b00, funct5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb),485              (ins GPRNoX0:$rd, InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr,486              "$rd, $rs1, $rs2"> {487  let Constraints = "$rd = $rd_wb";488}489 490class QCIBitManipRII<bits<3> funct3, bits<2> funct2,491                     DAGOperand InTyRs1, string opcodestr>492    : RVInstIBase<funct3, OPC_CUSTOM_0, (outs GPRNoX0:$rd),493                  (ins InTyRs1:$rs1, uimm5_plus1:$width, uimm5:$shamt),494                  opcodestr, "$rd, $rs1, $width, $shamt"> {495  bits<5> shamt;496  bits<5> width;497 498  let Inst{31-30} = funct2;499  let Inst{29-25} = width;500  let Inst{24-20} = shamt;501}502 503class QCIBitManipRIITied<bits<3> funct3, bits<2> funct2,504                         DAGOperand InTyRs1, string opcodestr>505    : RVInstIBase<funct3, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd,506                  InTyRs1:$rs1, uimm5_plus1:$width, uimm5:$shamt),507                  opcodestr, "$rd, $rs1, $width, $shamt"> {508  let Constraints = "$rd = $rd_wb";509  bits<5> shamt;510  bits<5> width;511 512  let Inst{31-30} = funct2;513  let Inst{29-25} = width;514  let Inst{24-20} = shamt;515}516 517class QCIRVInstRI<bits<1> funct1, DAGOperand InTyImm11,518                             string opcodestr>519    : RVInstIBase<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb),520                  (ins GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm11:$imm11), opcodestr,521                  "$rd, $rs1, $imm11"> {522  let Constraints = "$rd = $rd_wb";523  bits<11> imm11;524 525  let Inst{31-31} = funct1;526  let Inst{30-20} = imm11;527}528 529let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in530class QCISELECTIICC<bits<3> funct3, string opcodestr>531    : RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),532               (ins GPRNoX0:$rd, GPRNoX0:$rs1, simm5:$simm1, simm5:$simm2),533               opcodestr, "$rd, $rs1, $simm1, $simm2"> {534  let Constraints = "$rd = $rd_wb";535  bits<5> simm1;536  bits<5> simm2;537 538  let rs3 = simm2;539  let rs2 = simm1;540}541 542let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in543class QCISELECTICC<bits<3> funct3, string opcodestr>544    : RVInstR4<0b01, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),545               (ins GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm2),546               opcodestr, "$rd, $rs1, $rs2, $simm2"> {547  let Constraints = "$rd = $rd_wb";548  bits<5> simm2;549 550  let rs3 = simm2;551}552 553let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in554class QCISELECTCCI<bits<3> funct3, string opcodestr>555    : RVInstR4<0b10, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),556               (ins GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, GPRNoX0:$rs3),557               opcodestr, "$rd, $imm, $rs2, $rs3"> {558  let Constraints = "$rd = $rd_wb";559  bits<5> imm;560 561  let rs1 = imm;562}563 564let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in565class QCISELECTICCI<bits<3> funct3, string opcodestr>566    : RVInstR4<0b11, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),567               (ins GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, simm5:$simm2),568               opcodestr, "$rd, $imm, $rs2, $simm2"> {569  let Constraints = "$rd = $rd_wb";570  bits<5> imm;571  bits<5> simm2;572 573  let rs3 = simm2;574  let rs1 = imm;575}576 577let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in578class QCILoadMultiple<bits<2> funct2, DAGOperand InTyRs2, string opcodestr>579    : RVInstRBase<0b111, OPC_CUSTOM_0, (outs GPRNoX0:$rd),580                  (ins GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),581                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {582  bits<7> imm;583  let Inst{31-25} = {funct2, imm{6-2}};584}585 586 587// rd corresponds to the source for the store 'rs3' described in the spec.588let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in589class QCIStoreMultiple<bits<2> funct2, DAGOperand InTyRd, DAGOperand InTyRs2,590                       string opcodestr>591    : RVInstRBase<0b111, OPC_CUSTOM_1, (outs),592                  (ins InTyRd:$rd, GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),593                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {594  bits<7> imm;595  let Inst{31-25} = {funct2, imm{6-2}};596}597 598let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in599class QCILICC<bits<3> funct3, bits<2> funct2, DAGOperand InTyRs2, string opcodestr>600    : RVInstRBase<funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),601                  (ins GPRNoX0:$rd, GPRNoX0:$rs1, InTyRs2:$rs2, simm5:$simm),602                  opcodestr, "$rd, $rs1, $rs2, $simm"> {603  let Constraints = "$rd = $rd_wb";604  bits<5> simm;605 606  let Inst{31-25} = {simm, funct2};607}608 609let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in610class QCIMVCC<bits<3> funct3, string opcodestr>611    : RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),612               (ins GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3),613               opcodestr, "$rd, $rs1, $rs2, $rs3"> {614  let Constraints = "$rd = $rd_wb";615}616 617let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in618class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>619    : RVInstR4<0b10, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),620               (ins GPRNoX0:$rd, GPRNoX0:$rs1, immType:$imm, GPRNoX0:$rs3),621               opcodestr, "$rd, $rs1, $imm, $rs3"> {622  bits<5> imm;623  624  let Constraints = "$rd = $rd_wb";625  let rs2 = imm;626}627 628class QCI_RVInst16CB_BM<bits<2> funct2, string opcodestr>629    : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),630                 (ins GPRC:$rs1, uimmlog2xlennonzero:$shamt),631                 opcodestr, "$rs1, $shamt"> {632  bits<5> shamt;633  let Constraints = "$rs1 = $rd";634  let Inst{12} = 0b1;635  let Inst{11-10} = funct2;636  let Inst{6-2} = shamt{4-0};637}638 639let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in640class QCIRVInst16CI_RS1<bits<5> funct5, string OpcodeStr>641    : RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {642  bits<5> rs1;643 644  let Inst{12} = 0b1;645  let Inst{11-7} = rs1;646  let Inst{6-2} = funct5{4-0};647}648 649class QCIBranchInst_rii<bits<3> funct3, DAGOperand InTyImm5, string opcodestr>650    : RVInstB<funct3, OPC_CUSTOM_3, (outs),651              (ins GPRNoX0:$rs1, InTyImm5:$rs2, bare_simm13_lsb0:$imm12),652              opcodestr, "$rs1, $rs2, $imm12"> {653  let isBranch = 1;654  let isTerminator = 1;655  let hasSideEffects = 0;656  let mayLoad = 0;657  let mayStore = 0;658}659 660class QCIBranchInst48_rii<bits<5> funct5, DAGOperand InTyImm16, string opcodestr>661    : RVInst48<(outs),662               (ins GPRNoX0:$rs1, InTyImm16:$imm16, bare_simm13_lsb0:$imm12),663               opcodestr, "$rs1, $imm16, $imm12", [], InstFormatQC_EB> {664  bits<5> rs1;665  bits<16> imm16;666  bits<12> imm12;667 668  let Inst{47-32} = imm16;669  let Inst{31} = imm12{11};670  let Inst{30-25} = imm12{9-4};671  let Inst{24-20} = funct5;672  let Inst{19-15} = rs1;673  let Inst{14-12} = 0b100;674  let Inst{11-8} = imm12{3-0};675  let Inst{7} = imm12{10};676  let Inst{6-0} = 0b0011111;677  let isBranch = 1;678  let isTerminator = 1;679  let hasSideEffects = 0;680  let mayLoad = 0;681  let mayStore = 0;682}683 684let hasSideEffects = 1 in685class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>686    : RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {687  let Inst{12} = 0b1;688  let Inst{11-7} = funct5;689  let Inst{6-2} = 0b00100;690}691 692let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in693class QCIInt_IMM<bits<1> funct1, string opcodestr>694    : RVInstIBase<0b000, OPC_SYSTEM, (outs), (ins uimm10:$imm10), opcodestr,695                  "$imm10"> {696  bits<10> imm10;697 698  let rd = 0;699  let rs1 = imm10{4-0};700  let Inst{31-25} = {0b110011, funct1};701  let Inst{24-20} = imm10{9-5};702}703 704class QCISim_NONE<bits<4> imm11_8, string opcodestr>705    : RVInstI<0b010, OPC_OP_IMM, (outs), (ins), opcodestr, ""> {706  let rs1 = 0;707  let rd = 0;708  let imm12 = {imm11_8, 0b00000000};709}710 711class QCISim_RS1<bits<4> imm11_8, string opcodestr>712    : RVInstI<0b010, OPC_OP_IMM, (outs), (ins GPR:$rs1), opcodestr, "$rs1"> {713  let rd = 0;714  let imm12 = {imm11_8, 0b00000000};715}716 717let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in718class QCISync_UIMM5<bits<4> imm11_8, string opcodestr>719    : RVInstI<0b011, OPC_OP_IMM, (outs), (ins uimm5:$imm5), opcodestr, "$imm5">720{721  bits<5> imm5;722 723  let rs1 = 0;724  let rd = 0;725  let imm12 = {imm11_8, 0b000, imm5};726}727 728let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in729class QCIRVInst16CBSYNC<bits<3> imm5_func2, string OpcodeStr>730    : RVInst16CB<0b100, 0b01, (outs), (ins uimm5slist:$slist), OpcodeStr, "$slist"> {731    bits<3> slist;732 733    let Inst{6-2} = 0;734    let Inst{9-7} = slist;735    let Inst{12-10} = imm5_func2;736}737 738class QCIRVInstEIBase<bits<3> funct3, bits<2> funct2, dag outs,739                      dag ins, string opcodestr, string argstr>740    : RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {741  bits<5> rd;742  bits<5> rs1;743  bits<26> imm;744 745  let Inst{47-32} = imm{25-10};746  let Inst{31-30} = funct2;747  let Inst{29-20} = imm{9-0};748  let Inst{19-15} = rs1;749  let Inst{14-12} = funct3;750  let Inst{11-7} = rd;751  let Inst{6-0} = 0b0011111;752}753 754let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in755class QCIRVInstEILoad<bits<3> funct3, bits<2> funct2, string opcodestr>756    : QCIRVInstEIBase<funct3, funct2, (outs GPR:$rd),757                      (ins GPRMem:$rs1, simm26:$imm), opcodestr,758                      "$rd, ${imm}(${rs1})">;759 760class QCIRVInstESBase<bits<3> funct3, bits<2> funct2, dag outs,761                      dag ins, string opcodestr, string argstr>762    : RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {763  bits<5> rs1;764  bits<5> rs2;765  bits<26> imm;766 767  let Inst{47-32} = imm{25-10};768  let Inst{31-30} = funct2;769  let Inst{29-25} = imm{9-5};770  let Inst{24-20} = rs2;771  let Inst{19-15} = rs1;772  let Inst{14-12} = funct3;773  let Inst{11-7} = imm{4-0};774  let Inst{6-0} = 0b0011111;775}776 777let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in778class QCIRVInstESStore<bits<3> funct3, bits<2> funct2, string opcodestr>779    : QCIRVInstESBase<funct3, funct2, (outs),780                      (ins GPR:$rs2, GPRMem:$rs1, simm26:$imm),781                      opcodestr, "$rs2, ${imm}(${rs1})">;782 783class QCIRVInstEAI<bits<3> funct3, bits<1> funct1, string opcodestr>784    : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, bare_simm32:$imm),785               opcodestr, "$rd, $imm", [], InstFormatOther> {786  bits<5> rd;787  bits<32> imm;788 789  let Constraints = "$rd = $rd_wb";790  let Inst{47-16} = imm{31-0};791  let Inst{15} = funct1;792  let Inst{14-12} = funct3;793  let Inst{11-7} = rd;794  let Inst{6-0} = 0b0011111;795}796 797class QCIRVInstEI<bits<3> funct3, bits<2> funct2, string opcodestr>798    : QCIRVInstEIBase<funct3, funct2, (outs GPRNoX0:$rd),799                      (ins GPRNoX0:$rs1, simm26:$imm), opcodestr,800                      "$rd, $rs1, $imm">;801 802let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in803class QCIRVInst48EJ<bits<2> func2, string opcodestr>804    : RVInst48<(outs), (ins bare_simm32_lsb0:$imm31),805               opcodestr, "$imm31", [], InstFormatQC_EJ> {806  bits<31> imm31;807 808  let Inst{47-32} = imm31{30-15};809  let Inst{31} = imm31{11};810  let Inst{30-25} = imm31{9-4};811  let Inst{24-20} = 0b00000;812  let Inst{19-17} = imm31{14-12};813  let Inst{16-15} = func2;814  let Inst{14-12} = 0b100;815  let Inst{11-8} = imm31{3-0};816  let Inst{7} = imm31{10};817  let Inst{6-0} = 0b0011111;818}819 820class SFBQC_LI821    : Pseudo<(outs GPR:$dst),822             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev,823                  simm20_li:$imm), []> {824  let hasSideEffects = 0;825  let mayLoad = 0;826  let mayStore = 0;827  let Size = 8;828  let Constraints = "$dst = $falsev";829}830 831class SFBQC_E_LI832    : Pseudo<(outs GPR:$dst),833             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev,834                  bare_simm32:$imm), []> {835  let hasSideEffects = 0;836  let mayLoad = 0;837  let mayStore = 0;838  let Size = 10;839  let Constraints = "$dst = $falsev";840}841 842//===----------------------------------------------------------------------===//843// Instructions844//===----------------------------------------------------------------------===//845 846let DecoderNamespace = "Xqci" in {847 848let Predicates = [HasVendorXqcicsr, IsRV32] in {849let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {850  def QC_CSRRWR : RVInstR<0b1000110, 0b000, OPC_SYSTEM, (outs GPR:$rd),851                          (ins GPR:$rs1, GPRNoX0:$rs2), "qc.csrrwr",852                          "$rd, $rs1, $rs2">;853 854  def QC_CSRRWRI : RVInstR<0b1000111, 0b000, OPC_SYSTEM, (outs GPR:$rd),855                           (ins uimm5:$rs1, GPRNoX0:$rs2), "qc.csrrwri",856                           "$rd, $rs1, $rs2">;857} // hasSideEffects = 1, mayLoad = 0, mayStore = 0858} // Predicates = [HasVendorXqcicsr, IsRV32]859 860let Predicates = [HasVendorXqcisls, IsRV32] in {861  def  QC_LRB  : QCILoad_ScaleIdx<0b1000, "qc.lrb">;862  def  QC_LRH  : QCILoad_ScaleIdx<0b1001, "qc.lrh">;863  def  QC_LRW  : QCILoad_ScaleIdx<0b1010, "qc.lrw">;864  def  QC_LRBU : QCILoad_ScaleIdx<0b1011, "qc.lrbu">;865  def  QC_LRHU : QCILoad_ScaleIdx<0b1100, "qc.lrhu">;866 867  def  QC_SRB  : QCIStore_ScaleIdx<0b1101, "qc.srb">;868  def  QC_SRH  : QCIStore_ScaleIdx<0b1110, "qc.srh">;869  def  QC_SRW  : QCIStore_ScaleIdx<0b1111, "qc.srw">;870} // Predicates = [HasVendorXqcisls, IsRV32]871 872let Predicates = [HasVendorXqcia, IsRV32] in {873let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {874  def QC_SHLSAT : QCIRVInstRR<0b01010, GPRNoX0, "qc.shlsat">;875  def QC_SHLUSAT : QCIRVInstRR<0b01100, GPRNoX0, "qc.shlusat">;876  def QC_ADDSAT : QCIRVInstRR<0b01110, GPRNoX0, "qc.addsat">;877  def QC_ADDUSAT : QCIRVInstRR<0b01111, GPRNoX0, "qc.addusat">;878  def QC_SUBSAT : QCIRVInstRR<0b10000, GPRNoX0, "qc.subsat">;879  def QC_SUBUSAT : QCIRVInstRR<0b10001, GPRNoX0, "qc.subusat">;880 881  def QC_WRAP : QCIRVInstRR<0b10010, GPR, "qc.wrap">;882  def QC_WRAPI : RVInstI<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),883                         (ins GPRNoX0:$rs1, uimm11:$imm11), "qc.wrapi",884                         "$rd, $rs1, $imm11"> {885    bits<11> imm11;886 887    let imm12 = {0b0, imm11};888  }889 890  def QC_NORM : QCIRVInstR<0b0111, "qc.norm">;891  def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">;892  def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;893} // hasSideEffects = 0, mayLoad = 0, mayStore = 0894} // Predicates = [HasVendorXqcia, IsRV32]895 896let Predicates = [HasVendorXqcibi, IsRV32] in {897  def QC_BEQI  : QCIBranchInst_rii<0b000, simm5nonzero, "qc.beqi">;898  def QC_BNEI  : QCIBranchInst_rii<0b001, simm5nonzero, "qc.bnei">;899  def QC_BLTI  : QCIBranchInst_rii<0b100, simm5nonzero, "qc.blti">;900  def QC_BGEI  : QCIBranchInst_rii<0b101, simm5nonzero, "qc.bgei">;901  def QC_BLTUI : QCIBranchInst_rii<0b110, uimm5nonzero, "qc.bltui">;902  def QC_BGEUI : QCIBranchInst_rii<0b111, uimm5nonzero, "qc.bgeui">;903 904  def QC_E_BEQI  : QCIBranchInst48_rii<0b11000, simm16nonzero, "qc.e.beqi">;905  def QC_E_BNEI  : QCIBranchInst48_rii<0b11001, simm16nonzero, "qc.e.bnei">;906  def QC_E_BLTI  : QCIBranchInst48_rii<0b11100, simm16nonzero, "qc.e.blti">;907  def QC_E_BGEI  : QCIBranchInst48_rii<0b11101, simm16nonzero, "qc.e.bgei">;908  def QC_E_BLTUI : QCIBranchInst48_rii<0b11110, uimm16nonzero, "qc.e.bltui">;909  def QC_E_BGEUI : QCIBranchInst48_rii<0b11111, uimm16nonzero, "qc.e.bgeui">;910} // Predicates = [HasVendorXqcibi, IsRV32]911 912let Predicates = [HasVendorXqcibm, IsRV32] in {913let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {914  def QC_INSBRI : QCIRVInstRI<0b1, simm11, "qc.insbri">;915  def QC_INSBI : RVInstIBase<0b001, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb),916                             (ins GPRNoX0:$rd, simm5:$imm5, uimm5_plus1:$width,917                             uimm5:$shamt), "qc.insbi",918                             "$rd, $imm5, $width, $shamt"> {919    let Constraints = "$rd = $rd_wb";920    bits<5> imm5;921    bits<5> shamt;922    bits<5> width;923    let rs1 = imm5;924    let Inst{31-30} = 0b00;925    let Inst{29-25} = width;926    let Inst{24-20} = shamt;927  }928  def QC_INSB : QCIBitManipRIITied<0b001, 0b01, GPR, "qc.insb">;929  def QC_INSBH : QCIBitManipRIITied<0b001, 0b10, GPR, "qc.insbh">;930  def QC_INSBR : QCIRVInstRRTied<0b00000, GPR, "qc.insbr">;931  def QC_INSBHR : QCIRVInstRRTied<0b00001, GPR, "qc.insbhr">;932  def QC_INSBPR : QCIRVInstRRTied<0b00010, GPR, "qc.insbpr">;933  def QC_INSBPRH : QCIRVInstRRTied<0b00011, GPR, "qc.insbprh">;934  def QC_EXTU : QCIBitManipRII<0b010, 0b00, GPRNoX0, "qc.extu">;935  def QC_EXTDU : QCIBitManipRII<0b010, 0b10, GPRNoX31, "qc.extdu">;936  def QC_EXTDUR : QCIRVInstRR<0b00100, GPRNoX31, "qc.extdur">;937  def QC_EXTDUPR : QCIRVInstRR<0b00110, GPRNoX31, "qc.extdupr">;938  def QC_EXTDUPRH : QCIRVInstRR<0b00111, GPRNoX31, "qc.extduprh">;939  def QC_EXT : QCIBitManipRII<0b010, 0b01, GPRNoX0, "qc.ext">;940  def QC_EXTD : QCIBitManipRII<0b010, 0b11, GPRNoX31, "qc.extd">;941  def QC_EXTDR : QCIRVInstRR<0b00101, GPRNoX31, "qc.extdr">;942  def QC_EXTDPR : QCIRVInstRR<0b01000, GPRNoX31, "qc.extdpr">;943  def QC_EXTDPRH : QCIRVInstRR<0b01001, GPRNoX31, "qc.extdprh">;944  def QC_COMPRESS2 : QCIRVInstI<0b0000, "qc.compress2">;945  def QC_COMPRESS3 : QCIRVInstI<0b0001, "qc.compress3">;946  def QC_EXPAND2 : QCIRVInstI<0b0010, "qc.expand2">;947  def QC_EXPAND3 : QCIRVInstI<0b0011, "qc.expand3">;948  def QC_CLO : QCIRVInstI<0b0100, "qc.clo">;949  def QC_CTO : QCIRVInstI<0b0101, "qc.cto">;950  def QC_BREV32 : QCIRVInstI<0b0110, "qc.brev32">;951  def QC_C_BEXTI  : QCI_RVInst16CB_BM<0b00, "qc.c.bexti">;952  def QC_C_BSETI  : QCI_RVInst16CB_BM<0b01, "qc.c.bseti">;953  def QC_C_EXTU : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),954                             (ins GPRNoX0:$rd, uimm5ge6_plus1:$width),955                             "qc.c.extu", "$rd, $width"> {956    bits<5> rd;957    bits<5> width;958    let Constraints = "$rd = $rd_wb";959    let Inst{6-2} = width;960    let Inst{11-7} = rd;961    let Inst{12} = 0b1;962  }963} // hasSideEffects = 0, mayLoad = 0, mayStore = 0964} // Predicates = [HasVendorXqcibm, IsRV32]965 966let Predicates = [HasVendorXqciac, IsRV32] in {967let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {968  def QC_C_MULIADD : RVInst16CL<0b001, 0b10, (outs GPRC:$rd_wb),969                               (ins GPRC:$rd, GPRC:$rs1, uimm5:$uimm),970                               "qc.c.muliadd", "$rd, $rs1, $uimm"> {971    let Constraints = "$rd = $rd_wb";972    bits<5> uimm;973 974    let Inst{12-10} = uimm{3-1};975    let Inst{6} = uimm{0};976    let Inst{5} = uimm{4};977  }978 979  def QC_MULIADD : RVInstI<0b110, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb),980                           (ins GPRNoX0:$rd, GPRNoX0:$rs1, simm12_lo:$imm12),981                           "qc.muliadd", "$rd, $rs1, $imm12"> {982    let Constraints = "$rd = $rd_wb";983  }984 985  def QC_SHLADD : RVInstRBase<0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),986                              (ins GPRNoX0:$rs1, GPRNoX0:$rs2, uimm5gt3:$shamt),987                              "qc.shladd", "$rd, $rs1, $rs2, $shamt"> {988    bits<5> shamt;989 990    let Inst{31-30} = 0b01;991    let Inst{29-25} = shamt;992  }993 994} // hasSideEffects = 0, mayLoad = 0, mayStore = 0995} // Predicates = [HasVendorXqciac, IsRV32]996 997let Predicates = [HasVendorXqcics, IsRV32] in {998  def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">;999  def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">;1000  def QC_SELECTIEQ  : QCISELECTICC  <0b010, "qc.selectieq">;1001  def QC_SELECTINE  : QCISELECTICC  <0b011, "qc.selectine">;1002  def QC_SELECTEQI  : QCISELECTCCI  <0b010, "qc.selecteqi">;1003  def QC_SELECTNEI  : QCISELECTCCI  <0b011, "qc.selectnei">;1004  def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;1005  def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;1006} // Predicates = [HasVendorXqcics, IsRV32]1007 1008let Predicates = [HasVendorXqcilsm, IsRV32] in {1009    def QC_SWM : QCIStoreMultiple<0b00, GPRNoX0, GPRNoX0, "qc.swm">;1010    def QC_SWMI : QCIStoreMultiple<0b01, GPRNoX0, uimm5nonzero, "qc.swmi">;1011    def QC_SETWM : QCIStoreMultiple<0b10, GPR, GPRNoX0, "qc.setwm">;1012    def QC_SETWMI : QCIStoreMultiple<0b11, GPR, uimm5nonzero, "qc.setwmi">;1013 1014    def QC_LWM : QCILoadMultiple<0b00, GPRNoX0, "qc.lwm">;1015    def QC_LWMI : QCILoadMultiple<0b01, uimm5nonzero, "qc.lwmi">;1016} // Predicates = [HasVendorXqcilsm, IsRV32]1017 1018let Predicates = [HasVendorXqcicli, IsRV32] in {1019  def QC_LIEQ    : QCILICC<0b000, 0b01, GPRNoX0, "qc.lieq">;1020  def QC_LINE    : QCILICC<0b001, 0b01, GPRNoX0, "qc.line">;1021  def QC_LILT    : QCILICC<0b100, 0b01, GPRNoX0, "qc.lilt">;1022  def QC_LIGE    : QCILICC<0b101, 0b01, GPRNoX0, "qc.lige">;1023  def QC_LILTU   : QCILICC<0b110, 0b01, GPRNoX0, "qc.liltu">;1024  def QC_LIGEU   : QCILICC<0b111, 0b01, GPRNoX0, "qc.ligeu">;1025 1026  def QC_LIEQI   : QCILICC<0b000, 0b11, simm5, "qc.lieqi">;1027  def QC_LINEI   : QCILICC<0b001, 0b11, simm5, "qc.linei">;1028  def QC_LILTI   : QCILICC<0b100, 0b11, simm5, "qc.lilti">;1029  def QC_LIGEI   : QCILICC<0b101, 0b11, simm5, "qc.ligei">;1030  def QC_LILTUI  : QCILICC<0b110, 0b11, uimm5, "qc.liltui">;1031  def QC_LIGEUI  : QCILICC<0b111, 0b11, uimm5, "qc.ligeui">;1032} // Predicates = [HasVendorXqcicli, IsRV32]1033 1034let Predicates = [HasVendorXqcicm, IsRV32] in {1035let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in1036  def QC_C_MVEQZ   : RVInst16CL<0b101, 0b10, (outs GPRC:$rd_wb),1037                              (ins GPRC:$rd, GPRC:$rs1),1038                              "qc.c.mveqz", "$rd, $rs1"> {1039    let Constraints = "$rd = $rd_wb";1040 1041    let Inst{12-10} = 0b011;1042    let Inst{6-5} = 0b00;1043  }1044 1045  def QC_MVEQ    : QCIMVCC<0b000, "qc.mveq">;1046  def QC_MVNE    : QCIMVCC<0b001, "qc.mvne">;1047  def QC_MVLT    : QCIMVCC<0b100, "qc.mvlt">;1048  def QC_MVGE    : QCIMVCC<0b101, "qc.mvge">;1049  def QC_MVLTU   : QCIMVCC<0b110, "qc.mvltu">;1050  def QC_MVGEU   : QCIMVCC<0b111, "qc.mvgeu">;1051 1052  def QC_MVEQI   : QCIMVCCI<0b000, "qc.mveqi", simm5>;1053  def QC_MVNEI   : QCIMVCCI<0b001, "qc.mvnei", simm5>;1054  def QC_MVLTI   : QCIMVCCI<0b100, "qc.mvlti", simm5>;1055  def QC_MVGEI   : QCIMVCCI<0b101, "qc.mvgei", simm5>;1056  def QC_MVLTUI  : QCIMVCCI<0b110, "qc.mvltui", uimm5>;1057  def QC_MVGEUI  : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;1058} // Predicates = [HasVendorXqcicm, IsRV32]1059 1060let Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 1 in {1061 1062let mayLoad = 0, mayStore = 0 in {1063def QC_C_DIR : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd), (ins),1064                          "qc.c.dir", "$rd"> {1065  bits<5> rd;1066 1067  let Inst{12} = 0b1;1068  let Inst{11-7} = rd;1069  let Inst{6-2} = 0b00000;1070}1071 1072def QC_SETINTI : QCIInt_IMM<0b0, "qc.setinti">;1073def QC_CLRINTI : QCIInt_IMM<0b1, "qc.clrinti">;1074 1075def QC_C_EIR    : QCIRVInst16CI_RS1<0b00001, "qc.c.eir">;1076def QC_C_SETINT : QCIRVInst16CI_RS1<0b00010, "qc.c.setint">;1077def QC_C_CLRINT : QCIRVInst16CI_RS1<0b00011, "qc.c.clrint">;1078 1079def QC_C_DI     : QCIRVInst16CI_NONE<0b10110, "qc.c.di">;1080def QC_C_EI     : QCIRVInst16CI_NONE<0b10111, "qc.c.ei">;1081 1082let isBarrier = 1, isReturn = 1, isTerminator = 1 in {1083def QC_C_MRET   : QCIRVInst16CI_NONE<0b10010, "qc.c.mret">;1084def QC_C_MNRET  : QCIRVInst16CI_NONE<0b10011, "qc.c.mnret">;1085} // isBarrier = 1, isReturn = 1, isTerminator = 11086} // mayLoad = 0, mayStore = 01087 1088let mayLoad = 0, mayStore = 1,1089  Uses = [X1, X2, X5, X6, X7, X8, X10, X11, X12, X13, X14, X15, X16, X17, X28, X29, X30, X31],1090  Defs = [X2, X8] in {1091def QC_C_MIENTER      : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;1092def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;1093} // mayLoad = 1, mayStore = 1, Uses = [...], Defs = [...]1094 1095let mayLoad = 1, mayStore = 0, isBarrier = 1, isReturn = 1, isTerminator = 1,1096  Uses = [X2],1097  Defs = [X1, X2, X5, X6, X7, X8, X10, X11, X12, X13, X14, X15, X16, X17, X28, X29, X30, X31] in1098def QC_C_MILEAVERET   : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;1099 1100} // Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 11101 1102let Predicates = [HasVendorXqciio, IsRV32] in {1103let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {1104  def QC_OUTW : RVInstI<0b100, OPC_CUSTOM_0, (outs),1105                        (ins GPR:$rs2, GPR:$rs1, uimm14lsb00:$imm14),1106                        "qc.outw", "$rs2, ${imm14}(${rs1})"> {1107    bits<5> rs2;1108    bits<14> imm14;1109 1110    let rd = rs2;1111    let imm12 = imm14{13-2};1112  }1113 1114  def QC_INW : RVInstI<0b101, OPC_CUSTOM_0, (outs GPRNoX0:$rd),1115                       (ins GPR:$rs1, uimm14lsb00:$imm14),1116                       "qc.inw", "$rd, ${imm14}(${rs1})"> {1117    bits<14> imm14;1118 1119    let imm12 = imm14{13-2};1120  }1121} // hasSideEffects = 1, mayLoad = 0, mayStore = 01122} // Predicates = [HasVendorXqciio, IsRV32]1123 1124let Predicates = [HasVendorXqcilo, IsRV32] in {1125  def QC_E_LB    : QCIRVInstEILoad<0b101, 0b00, "qc.e.lb">;1126  def QC_E_LBU   : QCIRVInstEILoad<0b101, 0b01, "qc.e.lbu">;1127  def QC_E_LH    : QCIRVInstEILoad<0b101, 0b10, "qc.e.lh">;1128  def QC_E_LHU   : QCIRVInstEILoad<0b101, 0b11, "qc.e.lhu">;1129  def QC_E_LW    : QCIRVInstEILoad<0b110, 0b00, "qc.e.lw">;1130 1131  def QC_E_SB    : QCIRVInstESStore<0b110, 0b01, "qc.e.sb">;1132  def QC_E_SH    : QCIRVInstESStore<0b110, 0b10, "qc.e.sh">;1133  def QC_E_SW    : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">;1134} // Predicates = [HasVendorXqcilo, IsRV32]1135 1136let Predicates = [HasVendorXqcilb, IsRV32] in {1137  let isCall = 1, Defs = [X1] in1138  def QC_E_JAL   : QCIRVInst48EJ<0b01, "qc.e.jal">;1139  let isBranch = 1, isTerminator = 1, isBarrier = 1 in1140  def QC_E_J     : QCIRVInst48EJ<0b00, "qc.e.j">;1141} // Predicates = [HasVendorXqcilb, IsRV32]1142 1143let Predicates = [HasVendorXqcili, IsRV32] in {1144let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {1145  def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20_li:$imm20),1146                      "qc.li", "$rd, $imm20"> {1147    let Inst{31} = imm20{19};1148    let Inst{30-16} = imm20{14-0};1149    let Inst{15-12} = imm20{18-15};1150  }1151 1152  def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins bare_simm32:$imm),1153                         "qc.e.li", "$rd, $imm", [], InstFormatQC_EAI> {1154    bits<5> rd;1155    bits<32> imm;1156 1157    let Inst{47-16} = imm;1158    let Inst{15-12} = 0b0000;1159    let Inst{11-7} = rd;1160    let Inst{6-0} = 0b0011111;1161  }1162} // hasSideEffects = 0, mayLoad = 0, mayStore = 01163} // Predicates = [HasVendorXqcili, IsRV32]1164 1165let Predicates = [HasVendorXqcilia, IsRV32] in {1166let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {1167  def QC_E_XORAI : QCIRVInstEAI<0b001, 0b0, "qc.e.xorai">;1168  def QC_E_ORAI  : QCIRVInstEAI<0b001, 0b1, "qc.e.orai" >;1169  def QC_E_ADDAI : QCIRVInstEAI<0b010, 0b0, "qc.e.addai">;1170  def QC_E_ANDAI : QCIRVInstEAI<0b010, 0b1, "qc.e.andai">;1171 1172  def QC_E_XORI  : QCIRVInstEI<0b011, 0b00, "qc.e.xori">;1173  def QC_E_ORI   : QCIRVInstEI<0b011, 0b01, "qc.e.ori" >;1174  def QC_E_ADDI  : QCIRVInstEI<0b011, 0b10, "qc.e.addi">;1175  def QC_E_ANDI  : QCIRVInstEI<0b011, 0b11, "qc.e.andi">;1176} // hasSideEffects = 0, mayLoad = 0, mayStore = 01177} // Predicates = [HasVendorXqcilia, IsRV32]1178 1179let Predicates = [HasVendorXqcisync, IsRV32] in {1180  def QC_SYNC : QCISync_UIMM5<0b0001, "qc.sync">;1181  def QC_SYNCR : QCISync_UIMM5<0b0010, "qc.syncr">;1182  def QC_SYNCWF : QCISync_UIMM5<0b0100, "qc.syncwf">;1183  def QC_SYNCWL : QCISync_UIMM5<0b1000, "qc.syncwl">;1184 1185  def QC_C_SYNC   : QCIRVInst16CBSYNC<0b000, "qc.c.sync">;1186  def QC_C_SYNCR  : QCIRVInst16CBSYNC<0b001, "qc.c.syncr">;1187  def QC_C_SYNCWF : QCIRVInst16CBSYNC<0b100, "qc.c.syncwf">;1188  def QC_C_SYNCWL : QCIRVInst16CBSYNC<0b101, "qc.c.syncwl">;1189 1190  // qc.c.delay implemented as an alias, below1191} // Predicates = [HasVendorXqcisync, IsRV32]1192 1193let Predicates = [HasVendorXqcisim, IsRV32] in {1194let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {1195  def QC_PPUTCI : RVInstI<0b010, OPC_OP_IMM, (outs), (ins uimm8:$imm8),1196                          "qc.pputci", "$imm8"> {1197    bits<8> imm8;1198 1199    let rs1 = 0;1200    let rd = 0;1201    let imm12 = {0b0100, imm8};1202  }1203 1204  // The other instructions are all implemented as aliases, below1205} // mayLoad = 0, mayStore = 0, hasSideEffects = 11206} // Predicates = [HasVendorXqcisim, IsRV32]1207 1208} // DecoderNamespace = "Xqci"1209 1210//===----------------------------------------------------------------------===//1211// Aliases1212//===----------------------------------------------------------------------===//1213 1214let Predicates = [HasVendorXqciio, IsRV32] in {1215let EmitPriority = 0 in {1216  def : InstAlias<"qc.outw $rs2, (${rs1})",1217                  (QC_OUTW GPR:$rs2, GPR:$rs1, 0)>;1218  def : InstAlias<"qc.inw $rd, (${rs1})",1219                  (QC_INW GPRNoX0:$rd, GPR:$rs1, 0)>;1220} // EmitPriority = 01221} // Predicates = [HasVendorXqciio, IsRV32]1222 1223let Predicates = [HasVendorXqcilsm, IsRV32] in {1224let EmitPriority = 0 in {1225  def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",1226                  (QC_SWM GPRNoX0:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;1227  def : InstAlias<"qc.swmi $rs3, $length, (${rs1})",1228                  (QC_SWMI GPRNoX0:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;1229  def : InstAlias<"qc.setwm $rs3, $rs2, (${rs1})",1230                  (QC_SETWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;1231  def : InstAlias<"qc.setwmi $rs3, $length, (${rs1})",1232                  (QC_SETWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;1233  def : InstAlias<"qc.lwm $rd, $rs2, (${rs1})",1234                  (QC_LWM GPRNoX0:$rd, GPR:$rs1, GPRNoX0:$rs2, 0)>;1235  def : InstAlias<"qc.lwmi $rd, $length, (${rs1})",1236                  (QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;1237} // EmitPriority = 01238} // Predicates = [HasVendorXqcilsm, IsRV32]1239 1240let Predicates = [HasVendorXqcilo, IsRV32] in {1241let EmitPriority = 0 in {1242  def  : InstAlias<"qc.e.lb  $rd, (${rs1})",1243                   (QC_E_LB  GPR:$rd, GPR:$rs1, 0)>;1244  def  : InstAlias<"qc.e.lbu $rd, (${rs1})",1245                   (QC_E_LBU GPR:$rd, GPR:$rs1, 0)>;1246  def  : InstAlias<"qc.e.lh  $rd, (${rs1})",1247                   (QC_E_LH  GPR:$rd, GPR:$rs1, 0)>;1248  def  : InstAlias<"qc.e.lhu $rd, (${rs1})",1249                   (QC_E_LHU GPR:$rd, GPR:$rs1, 0)>;1250  def  : InstAlias<"qc.e.lw  $rd, (${rs1})",1251                   (QC_E_LW  GPR:$rd, GPR:$rs1, 0)>;1252  def  : InstAlias<"qc.e.sb  $rs2, (${rs1})",1253                   (QC_E_SB GPR:$rs2, GPR:$rs1, 0)>;1254  def  : InstAlias<"qc.e.sh  $rs2, (${rs1})",1255                   (QC_E_SH GPR:$rs2, GPR:$rs1, 0)>;1256  def  : InstAlias<"qc.e.sw  $rs2, (${rs1})",1257                   (QC_E_SW GPR:$rs2, GPR:$rs1, 0)>;1258} // EmitPriority = 01259} // Predicates = [HasVendorXqcilo, IsRV32]1260 1261let Predicates = [HasVendorXqcisim, IsRV32] in {1262let EmitPriority = 1 in {1263  def : InstAlias<"qc.c.ptrace", (C_SLLI X0, 0)>;1264 1265  def : InstAlias<"qc.psyscalli $imm", (SLTI X0, X0, uimm10:$imm)>;1266  def : InstAlias<"qc.pcoredump", (SLTI X0, X0, 1536)>;1267  def : InstAlias<"qc.ppregs", (SLTI X0, X0, 1792)>;1268  def : InstAlias<"qc.ppreg $rs1", (SLTI X0, GPR:$rs1, -2048)>;1269  def : InstAlias<"qc.pputc $rs1", (SLTI X0, GPR:$rs1, -1792)>;1270  def : InstAlias<"qc.pputs $rs1", (SLTI X0, GPR:$rs1, -1536)>;1271  def : InstAlias<"qc.pexit $rs1", (SLTI X0, GPR:$rs1, -1280)>;1272  def : InstAlias<"qc.psyscall $rs1", (SLTI X0, GPR:$rs1, -1024)>;1273} // EmitPriority = 11274} // Predicates = [HasVendorXqcisim, IsRV32]1275 1276let Predicates = [HasVendorXqcisync, IsRV32] in {1277let EmitPriority = 1 in {1278  def : InstAlias<"qc.c.delay $imm", (C_SLLI X0, uimm5nonzero:$imm)>;1279}1280} // Predicates = [HasVendorXqcisync, IsRV32]1281 1282//===----------------------------------------------------------------------===//1283// Pseudo-instructions1284//===----------------------------------------------------------------------===//1285 1286class LongBcciPseudo<DAGOperand InTyImm, int size>1287    : Pseudo<(outs), (ins GPR:$rs1, InTyImm:$imm, simm21_lsb0_jal:$imm20), []>1288{1289  let Size = size;1290  let isBarrier = 1;1291  let isBranch = 1;1292  let hasSideEffects = 0;1293  let mayStore = 0;1294  let mayLoad = 0;1295  let isAsmParserOnly = 1;1296  let hasNoSchedulingInfo = 1;1297}1298 1299// This will be expanded into either:1300// QC.BXXX(4 bytes) + JAL(4 bytes)1301// or1302// QC.E.BXXX(6 bytes) + JAL(4 bytes)1303def PseudoLongQC_BEQI : LongBcciPseudo<simm5nonzero, 8>;1304def PseudoLongQC_BNEI : LongBcciPseudo<simm5nonzero, 8>;1305def PseudoLongQC_BLTI : LongBcciPseudo<simm5nonzero, 8>;1306def PseudoLongQC_BGEI : LongBcciPseudo<simm5nonzero, 8>;1307def PseudoLongQC_BLTUI : LongBcciPseudo<uimm5nonzero, 8>;1308def PseudoLongQC_BGEUI : LongBcciPseudo<uimm5nonzero, 8>;1309def PseudoLongQC_E_BEQI : LongBcciPseudo<simm16nonzero, 10>;1310def PseudoLongQC_E_BNEI : LongBcciPseudo<simm16nonzero, 10>;1311def PseudoLongQC_E_BLTI : LongBcciPseudo<simm16nonzero, 10>;1312def PseudoLongQC_E_BGEI : LongBcciPseudo<simm16nonzero, 10>;1313def PseudoLongQC_E_BLTUI : LongBcciPseudo<uimm16nonzero, 10>;1314def PseudoLongQC_E_BGEUI : LongBcciPseudo<uimm16nonzero, 10>;1315 1316// Load/Store pseudos with QC.E.* Mnemonics. These expand to an AUIPC +1317// (Standard) Load/Store sequence, as this can materialize all 32-bit addresses,1318// and is shorter than e.g. an AUIPC + Xqcilo Load/Store sequence. These1319// sequences can be turned back into a single Xqcilo instruction using linker1320// relaxation.1321let Predicates = [HasVendorXqcilo, IsRV32] in {1322def PseudoQC_E_LB : PseudoLoad<"qc.e.lb">;1323def PseudoQC_E_LBU : PseudoLoad<"qc.e.lbu">;1324def PseudoQC_E_LH : PseudoLoad<"qc.e.lh">;1325def PseudoQC_E_LHU : PseudoLoad<"qc.e.lhu">;1326def PseudoQC_E_LW : PseudoLoad<"qc.e.lw">;1327 1328def PseudoQC_E_SB : PseudoStore<"qc.e.sb">;1329def PseudoQC_E_SH : PseudoStore<"qc.e.sh">;1330def PseudoQC_E_SW : PseudoStore<"qc.e.sw">;1331} // Predicates = [HasVendorXqcilo, IsRV32]1332 1333let Predicates = [HasShortForwardBranchIALU] in {1334def PseudoCCQC_LI : SFBQC_LI;1335def PseudoCCQC_E_LI : SFBQC_E_LI;1336}1337 1338//===----------------------------------------------------------------------===//1339// Code Gen Patterns1340//===----------------------------------------------------------------------===//1341 1342/// Generic pattern classes1343 1344class PatGprNoX0Simm26NoSimm12<SDPatternOperator OpNode, RVInst48 Inst>1345    : Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), simm26_nosimm12:$imm)),1346          (Inst GPRNoX0:$rs1, simm26_nosimm12:$imm)>;1347 1348class PatGprNoX0Simm32NoSimm26<SDPatternOperator OpNode, RVInst48 Inst>1349    : Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), simm32_nosimm26:$imm)),1350          (Inst GPRNoX0:$rs1, simm32_nosimm26:$imm)>;1351 1352class PatGprNoX0GprNoX0<SDPatternOperator OpNode, RVInstR Inst>1353    : Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2))),1354          (Inst GPRNoX0:$rs1, GPRNoX0:$rs2)>;1355 1356class QC48LdPat<PatFrag LoadOp, RVInst48 Inst>1357    : Pat<(i32 (LoadOp (AddLike (i32 GPR:$rs1), simm26_nosimm12:$imm26))),1358          (Inst GPR:$rs1, simm26_nosimm12:$imm26)>;1359 1360class QC48StPat<PatFrag StoreOp, RVInst48 Inst>1361    : Pat<(StoreOp (i32 GPR:$rs2), (AddLike (i32 GPR:$rs1), simm26_nosimm12:$imm26)),1362          (Inst GPR:$rs2, GPR:$rs1, simm26_nosimm12:$imm26)>;1363 1364def AddrRegRegScale7 : AddrRegRegScale<7>;1365 1366class QCScaledLdPat<PatFrag LoadOp, RVInst Inst>1367    : Pat<(i32 (LoadOp (AddrRegRegScale7 (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt))),1368          (Inst GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;1369 1370class QCScaledStPat<PatFrag StoreOp, RVInst Inst>1371    : Pat<(StoreOp (i32 GPR:$rd), (AddrRegRegScale7 (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)),1372          (Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;1373 1374class QCIMVCCPat<CondCode Cond, QCIMVCC Inst>1375    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),1376          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3)>;1377 1378class QCIMVCCIPat<CondCode Cond, QCIMVCCI Inst, DAGOperand InTyImm>1379    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),1380          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, GPRNoX0:$rs3)>;1381 1382class QCIMVCCIZeroPat<CondCode Cond, QCIMVCCI Inst>1383    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),1384          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;1385 1386class QCISELECTCCIPat<CondCode Cond, QCISELECTCCI Inst>1387    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),1388          (Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, GPRNoX0:$rs3)>;1389 1390class QCISELECTICCIPat<CondCode Cond, QCISELECTICCI Inst>1391    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), simm5:$simm2)),1392          (Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, simm5:$simm2)>;1393 1394class QCISELECTICCIPatInv<CondCode Cond, QCISELECTICCI Inst>1395    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, simm5:$simm2, (i32 GPRNoX0:$rs2))),1396          (Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, simm5:$simm2)>;1397 1398class QCISELECTICCPat<CondCode Cond, QCISELECTICC Inst>1399    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, (i32 GPRNoX0:$rs2), simm5:$simm2)),1400          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm2)>;1401 1402class QCISELECTICCPatInv<CondCode Cond, QCISELECTICC Inst>1403    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, simm5:$simm2, (i32 GPRNoX0:$rs2))),1404          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm2)>;1405 1406class QCISELECTIICCPat<CondCode Cond, QCISELECTIICC Inst>1407    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, simm5:$simm1, simm5:$simm2)),1408          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, simm5:$simm1, simm5:$simm2)>;1409 1410class QCILICCPat<CondCode Cond, QCILICC Inst>1411    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, simm5:$simm, (i32 GPRNoX0:$rd))),1412          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;1413 1414class QCILICCPatInv<CondCode Cond, QCILICC Inst>1415    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, (i32 GPRNoX0:$rd), simm5:$simm)),1416          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;1417 1418class QCILICCIPat<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>1419    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, simm5:$simm, (i32 GPRNoX0:$rd))),1420          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;1421 1422class QCILICCIPatInv<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>1423    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rd), simm5:$simm)),1424          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;1425 1426// Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction.1427class BcciPat<CondCode Cond, QCIBranchInst_rii Inst, DAGOperand InTyImm>1428    : Pat<(riscv_brcc (i32 GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),1429          (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0_bb:$imm12)>;1430 1431class Bcci48Pat<CondCode Cond, QCIBranchInst48_rii Inst, DAGOperand InTyImm>1432    : Pat<(riscv_brcc (i32 GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),1433          (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0_bb:$imm12)>;1434 1435defm CC_SImm5NonZero_QC  : SelectCC_GPR_riirr<GPRNoX0, simm5nonzero>;1436defm CC_UImm5NonZero_QC  : SelectCC_GPR_riirr<GPRNoX0, uimm5nonzero>;1437defm CC_SImm16NonZero_QC : SelectCC_GPR_riirr<GPRNoX0, simm16nonzero>;1438defm CC_UImm16NonZero_QC : SelectCC_GPR_riirr<GPRNoX0, uimm16nonzero>;1439 1440class SelectQCbi<CondCode Cond, DAGOperand InTyImm, Pseudo OpNode >1441    : Pat<(riscv_selectcc_frag:$cc (i32 GPRNoX0:$lhs), InTyImm:$Constant, Cond,1442                                   (i32 GPRNoX0:$truev), GPRNoX0:$falsev),1443          (OpNode GPRNoX0:$lhs, InTyImm:$Constant,1444           (IntCCtoRISCVCC $cc), GPRNoX0:$truev, GPRNoX0:$falsev)>;1445 1446let Predicates = [HasVendorXqciac, IsRV32] in {1447def : Pat<(i32 (add GPRNoX0:$rd, (mul GPRNoX0:$rs1, simm12_lo:$imm12))),1448          (QC_MULIADD GPRNoX0:$rd, GPRNoX0:$rs1, simm12_lo:$imm12)>;1449def : Pat<(i32 (add_like_non_imm12 (shl GPRNoX0:$rs1, (i32 uimm5gt3:$imm)), GPRNoX0:$rs2)),1450          (QC_SHLADD GPRNoX0:$rs1, GPRNoX0:$rs2, uimm5gt3:$imm)>;1451def : Pat<(i32 (riscv_shl_add GPRNoX0:$rs1, (i32 tuimm5gt3:$imm), GPRNoX0:$rs2)),1452          (QC_SHLADD GPRNoX0:$rs1, GPRNoX0:$rs2, tuimm5gt3:$imm)>;1453} // Predicates = [HasVendorXqciac, IsRV32]1454 1455/// Simple arithmetic operations1456 1457let Predicates = [HasVendorXqcilia, IsRV32] in {1458def : PatGprNoX0Simm32NoSimm26<add, QC_E_ADDAI>;1459def : PatGprNoX0Simm32NoSimm26<and, QC_E_ANDAI>;1460def : PatGprNoX0Simm32NoSimm26<or, QC_E_ORAI>;1461def : PatGprNoX0Simm32NoSimm26<xor, QC_E_XORAI>;1462 1463def : PatGprNoX0Simm26NoSimm12<add, QC_E_ADDI>;1464def : PatGprNoX0Simm26NoSimm12<and, QC_E_ANDI>;1465def : PatGprNoX0Simm26NoSimm12<or, QC_E_ORI>;1466def : PatGprNoX0Simm26NoSimm12<xor, QC_E_XORI>;1467} // Predicates = [HasVendorXqcilia, IsRV32]1468 1469/// Load/Store operations1470 1471let Predicates = [HasVendorXqcilo, IsRV32], AddedComplexity = 2 in {1472  def : QC48LdPat<sextloadi8, QC_E_LB>;1473  def : QC48LdPat<extloadi8, QC_E_LBU>; // Prefer unsigned due to no c.lb in Zcb.1474  def : QC48LdPat<sextloadi16, QC_E_LH>;1475  def : QC48LdPat<extloadi16, QC_E_LH>;1476  def : QC48LdPat<load, QC_E_LW>;1477  def : QC48LdPat<zextloadi8, QC_E_LBU>;1478  def : QC48LdPat<zextloadi16, QC_E_LHU>;1479 1480  def : QC48StPat<truncstorei8, QC_E_SB>;1481  def : QC48StPat<truncstorei16, QC_E_SH>;1482  def : QC48StPat<store, QC_E_SW>;1483} // Predicates = [HasVendorXqcilo, IsRV32], AddedComplexity = 21484 1485 1486let Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 1 in {1487  def : QCScaledLdPat<sextloadi8, QC_LRB>;1488  def : QCScaledLdPat<extloadi8, QC_LRBU>;1489  def : QCScaledLdPat<sextloadi16, QC_LRH>;1490  def : QCScaledLdPat<extloadi16, QC_LRH>;1491  def : QCScaledLdPat<load, QC_LRW>;1492  def : QCScaledLdPat<zextloadi8, QC_LRBU>;1493  def : QCScaledLdPat<zextloadi16, QC_LRHU>;1494 1495  def : QCScaledStPat<truncstorei8, QC_SRB>;1496  def : QCScaledStPat<truncstorei16, QC_SRH>;1497  def : QCScaledStPat<store, QC_SRW>;1498} // Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 11499 1500let Predicates = [HasVendorXqcia, IsRV32] in {1501def : PatGprNoX0GprNoX0<saddsat, QC_ADDSAT>;1502def : PatGprNoX0GprNoX0<uaddsat, QC_ADDUSAT>;1503def : PatGprNoX0GprNoX0<ssubsat, QC_SUBSAT>;1504def : PatGprNoX0GprNoX0<usubsat, QC_SUBUSAT>;1505def : PatGprNoX0GprNoX0<ushlsat, QC_SHLUSAT>;1506def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;1507} // Predicates = [HasVendorXqcia, IsRV32]1508 1509/// Branches1510 1511let Predicates = [HasVendorXqcibi, IsRV32] in {1512def : BcciPat<SETEQ, QC_BEQI, simm5nonzero>;1513def : BcciPat<SETNE, QC_BNEI, simm5nonzero>;1514def : BcciPat<SETLT, QC_BLTI, simm5nonzero>;1515def : BcciPat<SETGE, QC_BGEI, simm5nonzero>;1516def : BcciPat<SETULT, QC_BLTUI, uimm5nonzero>;1517def : BcciPat<SETUGE, QC_BGEUI, uimm5nonzero>;1518 1519def : Bcci48Pat<SETEQ, QC_E_BEQI, simm16nonzero>;1520def : Bcci48Pat<SETNE, QC_E_BNEI, simm16nonzero>;1521def : Bcci48Pat<SETLT, QC_E_BLTI, simm16nonzero>;1522def : Bcci48Pat<SETGE, QC_E_BGEI, simm16nonzero>;1523def : Bcci48Pat<SETULT, QC_E_BLTUI, uimm16nonzero>;1524def : Bcci48Pat<SETUGE, QC_E_BGEUI, uimm16nonzero>;1525 1526def : SelectQCbi<SETEQ, simm5nonzero, Select_GPRNoX0_Using_CC_SImm5NonZero_QC>;1527def : SelectQCbi<SETNE, simm5nonzero, Select_GPRNoX0_Using_CC_SImm5NonZero_QC>;1528def : SelectQCbi<SETLT, simm5nonzero, Select_GPRNoX0_Using_CC_SImm5NonZero_QC>;1529def : SelectQCbi<SETGE, simm5nonzero, Select_GPRNoX0_Using_CC_SImm5NonZero_QC>;1530def : SelectQCbi<SETULT, uimm5nonzero, Select_GPRNoX0_Using_CC_UImm5NonZero_QC>;1531def : SelectQCbi<SETUGE, uimm5nonzero, Select_GPRNoX0_Using_CC_UImm5NonZero_QC>;1532 1533def : SelectQCbi<SETEQ, simm16nonzero, Select_GPRNoX0_Using_CC_SImm16NonZero_QC>;1534def : SelectQCbi<SETNE, simm16nonzero, Select_GPRNoX0_Using_CC_SImm16NonZero_QC>;1535def : SelectQCbi<SETLT, simm16nonzero, Select_GPRNoX0_Using_CC_SImm16NonZero_QC>;1536def : SelectQCbi<SETGE, simm16nonzero, Select_GPRNoX0_Using_CC_SImm16NonZero_QC>;1537def : SelectQCbi<SETULT, uimm16nonzero, Select_GPRNoX0_Using_CC_UImm16NonZero_QC>;1538def : SelectQCbi<SETUGE, uimm16nonzero, Select_GPRNoX0_Using_CC_UImm16NonZero_QC>;1539} // let Predicates = [HasVendorXqcibi, IsRV32]1540 1541let Predicates = [HasVendorXqcibm, IsRV32] in {1542def : Pat<(sext_inreg (i32 GPR:$rs1), i1), (QC_EXT GPR:$rs1, 1, 0)>;1543 1544// Prefer qc.extu to andi for the following cases since the former can be compressed1545def : Pat<(i32 (and GPRNoX0:$rs, 63)), (QC_EXTU GPRNoX0:$rs, 6, 0)>;1546def : Pat<(i32 (and GPRNoX0:$rs, 127)), (QC_EXTU GPRNoX0:$rs, 7, 0)>;1547def : Pat<(i32 (and GPRNoX0:$rs, 255)), (QC_EXTU GPRNoX0:$rs, 8, 0)>;1548def : Pat<(i32 (and GPRNoX0:$rs, 511)), (QC_EXTU GPRNoX0:$rs, 9, 0)>;1549def : Pat<(i32 (and GPRNoX0:$rs, 1023)), (QC_EXTU GPRNoX0:$rs, 10, 0)>;1550def : Pat<(i32 (and GPRNoX0:$rs, 2047)), (QC_EXTU GPRNoX0:$rs, 11, 0)>;1551 1552def : Pat<(i32 (bitreverse GPRNoX0:$rs1)), (QC_BREV32 GPRNoX0:$rs1)>;1553 1554def : Pat<(qc_insb GPRNoX0:$rd, simm5:$imm5, uimm5_plus1:$width, uimm5:$shamt),1555          (QC_INSBI GPRNoX0:$rd, simm5:$imm5, uimm5_plus1:$width, uimm5:$shamt)>;1556def : Pat<(qc_insb GPRNoX0:$rd, GPR:$rs1, uimm5_plus1:$width, uimm5:$shamt),1557          (QC_INSB GPRNoX0:$rd, GPR:$rs1, uimm5_plus1:$width, uimm5:$shamt)>;1558} // Predicates = [HasVendorXqcibm, IsRV32]1559 1560// If Zbb is enabled sext.b/h is preferred since they are compressible1561let Predicates = [HasVendorXqcibm, NoStdExtZbb, IsRV32] in {1562def : Pat<(sext_inreg (i32 GPR:$rs1), i16), (QC_EXT GPR:$rs1, 16, 0)>;1563def : Pat<(sext_inreg (i32 GPR:$rs1), i8), (QC_EXT GPR:$rs1, 8, 0)>;1564} // Predicates = [HasVendorXqcibm, NoStdExtZbb, IsRV32]1565 1566let Predicates = [HasVendorXqcibm, HasStdExtZbb, IsRV32] in {1567def: Pat<(i32 (cttz (not (i32 GPR:$rs1)))), (QC_CTO GPR:$rs1)>;1568def: Pat<(i32 (ctlz (not (i32 GPR:$rs1)))), (QC_CLO GPR:$rs1)>;1569} // Predicates = [HasVendorXqcibm, HasStdExtZbb, IsRV32]1570 1571let Predicates = [HasVendorXqciint, IsRV32] in1572def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;1573 1574let Predicates = [HasVendorXqcicm, NoShortForwardBranch, IsRV32] in {1575def : QCIMVCCPat<SETEQ,  QC_MVEQ>;1576def : QCIMVCCPat<SETNE,  QC_MVNE>;1577def : QCIMVCCPat<SETLT,  QC_MVLT>;1578def : QCIMVCCPat<SETULT, QC_MVLTU>;1579def : QCIMVCCPat<SETGE,  QC_MVGE>;1580def : QCIMVCCPat<SETUGE, QC_MVGEU>;1581 1582// These exist to prioritise over the `Select_GPR_Using_CC_GPR` pattern for X0.1583def : QCIMVCCIZeroPat<SETEQ,  QC_MVEQI>;1584def : QCIMVCCIZeroPat<SETNE,  QC_MVNEI>;1585def : QCIMVCCIZeroPat<SETLT,  QC_MVLTI>;1586def : QCIMVCCIZeroPat<SETULT, QC_MVLTUI>;1587def : QCIMVCCIZeroPat<SETGE,  QC_MVGEI>;1588def : QCIMVCCIZeroPat<SETUGE, QC_MVGEUI>;1589}1590 1591let Predicates = [HasVendorXqcicm, IsRV32] in {1592// These all use *imm5nonzero because we want to use PseudoCCMOVGPR with X0 when SFB is enabled.1593// When SFB is not enabled, the `QCIMVCCIZeroPat`s above will be used if RHS=0.1594def : QCIMVCCIPat<SETEQ,  QC_MVEQI,  simm5nonzero>;1595def : QCIMVCCIPat<SETNE,  QC_MVNEI,  simm5nonzero>;1596def : QCIMVCCIPat<SETLT,  QC_MVLTI,  simm5nonzero>;1597def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5nonzero>;1598def : QCIMVCCIPat<SETGE,  QC_MVGEI,  simm5nonzero>;1599def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5nonzero>;1600}1601 1602let Predicates = [HasVendorXqcicli, IsRV32] in {1603def : QCILICCPat<SETLT,  QC_LILT>;1604def : QCILICCPat<SETGE,  QC_LIGE>;1605def : QCILICCPat<SETULT, QC_LILTU>;1606def : QCILICCPat<SETUGE, QC_LIGEU>;1607 1608def : QCILICCIPat<SETLT,  QC_LILTI, simm5>;1609def : QCILICCIPat<SETGE,  QC_LIGEI, simm5>;1610def : QCILICCIPat<SETULT, QC_LILTUI, uimm5>;1611def : QCILICCIPat<SETUGE, QC_LIGEUI, uimm5>;1612 1613def : QCILICCPatInv<SETGE,  QC_LILT>;1614def : QCILICCPatInv<SETLT,  QC_LIGE>;1615def : QCILICCPatInv<SETUGE, QC_LILTU>;1616def : QCILICCPatInv<SETULT, QC_LIGEU>;1617 1618def : QCILICCIPatInv<SETGE,  QC_LILTI, simm5>;1619def : QCILICCIPatInv<SETLT,  QC_LIGEI, simm5>;1620def : QCILICCIPatInv<SETUGE, QC_LILTUI, uimm5>;1621def : QCILICCIPatInv<SETULT, QC_LIGEUI, uimm5>;1622} // Predicates = [HasVendorXqcicli, IsRV32]1623 1624// Prioritize Xqcics over these patterns.1625let Predicates = [HasVendorXqcicli, NoVendorXqcics, IsRV32] in {1626def : QCILICCPat<SETEQ,  QC_LIEQ>;1627def : QCILICCPat<SETNE,  QC_LINE>;1628 1629def : QCILICCIPat<SETEQ,  QC_LIEQI, simm5>;1630def : QCILICCIPat<SETNE,  QC_LINEI, simm5>;1631 1632def : QCILICCPatInv<SETNE,  QC_LIEQ>;1633def : QCILICCPatInv<SETEQ,  QC_LINE>;1634 1635def : QCILICCIPatInv<SETNE,  QC_LIEQI, simm5>;1636def : QCILICCIPatInv<SETEQ,  QC_LINEI, simm5>;1637} // Predicates = [HasVendorXqcicli, NoVendorXqcics, IsRV32]1638 1639let Predicates = [HasVendorXqcics, IsRV32] in {1640// (SELECT X, Y, Z) is canonicalised to `(riscv_selectcc x, 0, NE, y, z)`.1641// These exist to prioritise over the `Select_GPR_Using_CC_GPR` pattern.1642def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, (i32 GPRNoX0:$rs2), simm5:$simm2)),1643          (QC_SELECTINEI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, simm5:$simm2)>;1644def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, simm5:$simm2, (i32 GPRNoX0:$rs2))),1645          (QC_SELECTIEQI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, simm5:$simm2)>;1646 1647def : QCISELECTICCIPat<SETEQ,  QC_SELECTIEQI>;1648def : QCISELECTICCIPat<SETNE,  QC_SELECTINEI>;1649 1650def : QCISELECTICCIPatInv<SETEQ,  QC_SELECTINEI>;1651def : QCISELECTICCIPatInv<SETNE,  QC_SELECTIEQI>;1652 1653def : QCISELECTICCPat<SETEQ,  QC_SELECTIEQ>;1654def : QCISELECTICCPat<SETNE,  QC_SELECTINE>;1655 1656def : QCISELECTICCPatInv<SETEQ,  QC_SELECTINE>;1657def : QCISELECTICCPatInv<SETNE,  QC_SELECTIEQ>;1658 1659def : QCISELECTIICCPat<SETEQ,  QC_SELECTIIEQ>;1660def : QCISELECTIICCPat<SETNE,  QC_SELECTIINE>;1661} // Predicates = [HasVendorXqcics, IsRV32]1662 1663// Prioritize Xqcicm over these patterns, because Xqcicm is compressible.1664let Predicates = [HasVendorXqcics, NoVendorXqcicm, IsRV32] in {1665def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),1666          (QC_SELECTNEI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;1667def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETEQ, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),1668          (QC_SELECTEQI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;1669 1670def : QCISELECTCCIPat<SETEQ,  QC_SELECTEQI>;1671def : QCISELECTCCIPat<SETNE,  QC_SELECTNEI>;1672}1673 1674let Predicates = [HasVendorXqcilsm, IsRV32] in {1675def : Pat<(qc_setwmi (i32 GPR:$rs3), GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7),1676          (QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>;1677} // Predicates = [HasVendorXqcilsm, IsRV32]1678 1679let Predicates = [HasVendorXqcili, IsRV32] in {1680def: Pat<(i32 (qc_e_li tglobaladdr:$A)), (QC_E_LI bare_simm32:$A)>;1681def: Pat<(i32 (qc_e_li tblockaddress:$A)), (QC_E_LI bare_simm32:$A)>;1682def: Pat<(i32 (qc_e_li tjumptable:$A)), (QC_E_LI bare_simm32:$A)>;1683def: Pat<(i32 (qc_e_li tconstpool:$A)), (QC_E_LI bare_simm32:$A)>;1684} // Predicates = [HasVendorXqcili, IsRV32]1685 1686//===----------------------------------------------------------------------===/i1687// Compress Instruction tablegen backend.1688//===----------------------------------------------------------------------===//1689 1690let Predicates = [HasVendorXqcisync, IsRV32] in {1691def : CompressPat<(QC_SYNC uimm5slist:$imm5), (QC_C_SYNC uimm5slist:$imm5)>;1692def : CompressPat<(QC_SYNCR uimm5slist:$imm5), (QC_C_SYNCR uimm5slist:$imm5)>;1693def : CompressPat<(QC_SYNCWL uimm5slist:$imm5), (QC_C_SYNCWL uimm5slist:$imm5)>;1694def : CompressPat<(QC_SYNCWF uimm5slist:$imm5), (QC_C_SYNCWF uimm5slist:$imm5)>;1695} // Predicates = [HasVendorXqcisync, IsRV32]1696 1697let isCompressOnly = true, Predicates = [HasVendorXqcilo, HasStdExtZcb, IsRV32] in {1698def : CompressPat<(QC_E_LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm),1699                  (C_LBU GPRC:$rd, GPRCMem:$rs1, uimm2:$imm)>;1700def : CompressPat<(QC_E_LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm),1701                  (C_LHU GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>;1702def : CompressPat<(QC_E_LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm),1703                  (C_LH GPRC:$rd, GPRCMem:$rs1, uimm2_lsb0:$imm)>;1704def : CompressPat<(QC_E_SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm),1705                  (C_SB GPRC:$rs2, GPRCMem:$rs1, uimm2:$imm)>;1706def : CompressPat<(QC_E_SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm),1707                  (C_SH GPRC:$rs2, GPRCMem:$rs1, uimm2_lsb0:$imm)>;1708} // isCompressOnly = true, Predicates = [HasVendorXqcilo, HasStdExtZcb, IsRV32]1709 1710let isCompressOnly = true, Predicates = [HasVendorXqcilo, IsRV32] in {1711def : CompressPat<(QC_E_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),1712                  (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;1713def : CompressPat<(QC_E_LW GPRNoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),1714                  (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;1715def : CompressPat<(QC_E_LB GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12),1716                  (LB GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12)>;1717def : CompressPat<(QC_E_LBU GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12),1718                  (LBU GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12)>;1719def : CompressPat<(QC_E_LH GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12),1720                  (LH GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12)>;1721def : CompressPat<(QC_E_LHU GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12),1722                  (LHU GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12)>;1723def : CompressPat<(QC_E_LW GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12),1724                  (LW GPR:$rd, GPRMem:$rs1, simm12_lo:$imm12)>;1725 1726def : CompressPat<(QC_E_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),1727                  (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;1728def : CompressPat<(QC_E_SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),1729                  (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;1730def : CompressPat<(QC_E_SB GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12),1731                  (SB GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12)>;1732def : CompressPat<(QC_E_SH GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12),1733                  (SH GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12)>;1734def : CompressPat<(QC_E_SW GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12),1735                  (SW GPR:$rs2, GPRMem:$rs1, simm12_lo:$imm12)>;1736} // isCompressOnly = true, Predicates = [HasVendorXqcilo, IsRV32]1737 1738let Predicates = [HasVendorXqcicm, IsRV32] in {1739def : CompressPat<(QC_MVEQI GPRC:$rd, GPRC:$rd, 0, GPRC:$rs1),1740                  (QC_C_MVEQZ GPRC:$rd, GPRC:$rs1)>;1741let isCompressOnly = true in1742def : CompressPat<(QC_MVLTUI GPRC:$rd, GPRC:$rd, 1, GPRC:$rs1),1743                  (QC_C_MVEQZ GPRC:$rd, GPRC:$rs1)>;1744}1745 1746let Predicates = [HasVendorXqcibm, IsRV32] in {1747def : CompressPat<(QC_EXTU GPRNoX0:$rd, GPRNoX0:$rd, uimm5ge6_plus1:$width, 0),1748                  (QC_C_EXTU GPRNoX0:$rd, uimm5ge6_plus1:$width)>;1749}1750 1751let Predicates = [HasVendorXqcibm, HasStdExtZbs, IsRV32] in {1752def : CompressPat<(BSETI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$shamt),1753                  (QC_C_BSETI GPRC:$rs1, uimmlog2xlennonzero:$shamt)>;1754def : CompressPat<(BEXTI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$shamt),1755                  (QC_C_BEXTI GPRC:$rs1, uimmlog2xlennonzero:$shamt)>;1756let isCompressOnly = true in1757def : CompressPat<(QC_EXTU GPRC:$rd, GPRC:$rd, 1, uimmlog2xlennonzero:$shamt),1758                  (QC_C_BEXTI GPRC:$rd, uimmlog2xlennonzero:$shamt)>;1759} // Predicates = [HasVendorXqcibm, HasStdExtZbs, IsRV32]1760 1761let isCompressOnly = true, Predicates = [HasVendorXqcilb, IsRV32] in {1762def : CompressPat<(QC_E_J bare_simm12_lsb0:$offset),1763                  (C_J bare_simm12_lsb0:$offset)>;1764def : CompressPat<(QC_E_JAL bare_simm12_lsb0:$offset),1765                  (C_JAL bare_simm12_lsb0:$offset)>;1766def : CompressPat<(QC_E_JAL simm21_lsb0_jal:$offset),1767                  (JAL X1, simm21_lsb0_jal:$offset)>;1768def : CompressPat<(QC_E_J simm21_lsb0_jal:$offset),1769                  (JAL X0, simm21_lsb0_jal:$offset)>;1770} // isCompressOnly = true, Predicates = [HasVendorXqcilb, IsRV32]1771 1772let Predicates = [HasVendorXqcili, IsRV32] in {1773def : CompressPat<(QC_LI GPRNoX0:$rd, simm6:$imm),1774                  (C_LI GPRNoX0:$rd, simm6:$imm)>;1775 1776let isCompressOnly = true in {1777def : CompressPat<(QC_E_LI GPRNoX0:$rd, simm6:$imm),1778                  (C_LI GPRNoX0:$rd, simm6:$imm)>;1779def : CompressPat<(QC_E_LI GPRNoX0:$rd, simm20_li:$imm),1780                  (QC_LI GPRNoX0:$rd, simm20_li:$imm)>;1781} // isCompressOnly = true1782} // Predicates = [HasVendorXqcili, IsRV32]1783 1784let isCompressOnly = true, Predicates = [HasVendorXqcilia, IsRV32] in {1785def : CompressPat<(QC_E_ADDAI GPRNoX0:$rd, simm6nonzero:$imm),1786                  (C_ADDI GPRNoX0:$rd, simm6nonzero:$imm)>;1787def : CompressPat<(QC_E_ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),1788                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;1789def : CompressPat<(QC_E_ANDAI GPRC:$rd, simm6:$imm),1790                  (C_ANDI GPRC:$rd, simm6:$imm)>;1791def : CompressPat<(QC_E_ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),1792                  (C_ANDI GPRC:$rs1, simm6:$imm)>;1793def : CompressPat<(QC_E_ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),1794                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;1795def : CompressPat<(QC_E_ADDAI X2, simm10_lsb0000nonzero:$imm),1796                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;1797def : CompressPat<(QC_E_ADDI X2, X2, simm10_lsb0000nonzero:$imm),1798                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;1799 1800def : CompressPat<(QC_E_ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm),1801                  (ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm)>;1802def : CompressPat<(QC_E_ANDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm),1803                  (ANDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm)>;1804def : CompressPat<(QC_E_ORI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm),1805                  (ORI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm)>;1806def : CompressPat<(QC_E_XORI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm),1807                  (XORI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm)>;1808 1809def : CompressPat<(QC_E_ADDAI GPRNoX0:$rd, simm12_lo:$imm),1810                  (ADDI GPRNoX0:$rd, GPRNoX0:$rd, simm12_lo:$imm)>;1811def : CompressPat<(QC_E_ANDAI GPRNoX0:$rd, simm12_lo:$imm),1812                  (ANDI GPRNoX0:$rd, GPRNoX0:$rd, simm12_lo:$imm)>;1813def : CompressPat<(QC_E_ORAI GPRNoX0:$rd, simm12_lo:$imm),1814                  (ORI GPRNoX0:$rd, GPRNoX0:$rd, simm12_lo:$imm)>;1815def : CompressPat<(QC_E_XORAI GPRNoX0:$rd, simm12_lo:$imm),1816                  (XORI GPRNoX0:$rd, GPRNoX0:$rd, simm12_lo:$imm)>;1817} // let isCompressOnly = true, Predicates = [HasVendorXqcilia, IsRV32]1818 1819let isCompressOnly = true, Predicates = [HasVendorXqciac, IsRV32] in {1820def : CompressPat<(QC_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5),1821                  (QC_C_MULIADD GPRC:$rd, GPRC:$rs1, uimm5:$imm5)>;1822} // isCompressOnly = true, Predicates = [HasVendorXqciac, IsRV32]1823 1824let isCompressOnly = true, Predicates = [HasVendorXqciac, HasStdExtZba, IsRV32] in {1825def : CompressPat<(SH1ADD GPRC:$rd, GPRC:$rs1, GPRC:$rd),1826                  (QC_C_MULIADD GPRC:$rd, GPRC:$rs1, 2)>;1827def : CompressPat<(SH2ADD GPRC:$rd, GPRC:$rs1, GPRC:$rd),1828                  (QC_C_MULIADD GPRC:$rd, GPRC:$rs1, 4)>;1829def : CompressPat<(SH3ADD GPRC:$rd, GPRC:$rs1, GPRC:$rd),1830                  (QC_C_MULIADD GPRC:$rd, GPRC:$rs1, 8)>;1831} // isCompressOnly = true, Predicates = [HasVendorXqciac, HasStdExtZba, IsRV32]1832 1833let isCompressOnly = true, Predicates = [HasVendorXqcibi, IsRV32] in {1834def : CompressPat<(QC_E_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1835                  (QC_BEQI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1836def : CompressPat<(QC_E_BNEI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1837                  (QC_BNEI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1838def : CompressPat<(QC_E_BGEI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1839                  (QC_BGEI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1840def : CompressPat<(QC_E_BLTI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1841                  (QC_BLTI GPRNoX0:$rs1, simm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1842def : CompressPat<(QC_E_BGEUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1843                  (QC_BGEUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1844def : CompressPat<(QC_E_BLTUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0:$imm12),1845                  (QC_BLTUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0:$imm12)>;1846} // let isCompressOnly = true, Predicates = [HasVendorXqcibi, IsRV32]1847 1848// HACKS1849// -----1850// The reasons for needing the definitions below are long and quite annoying. I'm writing1851// this so they are explained in-line, rather than anywhere else.1852//1853// Emitting an instruction to an object proceeds as:1854// - Compression (in emitInstruction)1855// - Emit to Binary Code + Fixups1856// - Assembler Relaxation1857//   - Fixup evaluation/application1858//   - If relaxed, re-emitted to Binary + Fixups1859// - Relocation generation from Fixups1860//1861// Unfortunately, the `QC.E.LI` -> `C.LI` compression pattern has an edge case that has1862// caused crashes in the past.1863//1864// How the bug happens is:1865// - QC.E.LI is parsed with a bare symbol, which is valid + expected, and can1866//   be handled by fixups/relocations.1867// - Compression turns this into a `C.LI` because the `simm6` 1868//   MCOperandPredicate accepts bare symbols.1869// - Binary Code emission didn't know how to create a fixup for a CI-type1870//   instruction containing a bare symbol.1871//1872// The solution to the last bullet is that we added the `fixup_riscv_rvc_imm`,1873// so that we could proceed past the last error, and then use Assembler Relaxation1874// to turn the `C.LI` with a bare symbol back into a `QC.E.LI`.1875//1876// This is good enough for emitting objects, but doesn't work for emitting1877// assembly. Emitting assembly is why we need the following Hacks.1878// 1879// Emitting an instruction to assembly proceeds as:1880// - Compression (in emitInstruction)1881// - Decompression (in RISCVInstPrinter::printInst)1882// - InstAliases are applied1883//1884// So in the case of `QC.E.LI` with a bare symbol, first it is compressed to1885// `C.LI` with a bare symbol, and then it is decompressed to `ADDI` with a bare1886// symbol for printing, which is printed via an alias as `li <reg>, <symbol>`.1887// Both the decompression and the alias use the MCOperandPredicate from 1888// `simm12`, which accepts bare symbols.1889//1890// The problem here is that `li <reg>, <symbol>` fails to parse, because the1891// parsers do not accept bare symbols, they only accept symbols with specifiers1892// or immediates.1893//1894// Our solution is to add another alias, which will be prioritised above the1895// `li` alias, but only when `qc.e.li` is available. We originally intended to1896// use the `bare_symbol` Operand type, but this had no MCOperandPredicate, and1897// adding one changed the error messages when parsing `qc.e.li` with a1898// too-large constant. So instead, we add a new `AsmOperand` and `Operand` type,1899// just for the alias, which parse just like a BareSymbol, but they1900// have both an MCOperandPredicate, and the error message that corresponds to1901// the existing one on `qc.e.li` for too-large immediates (which fail to parse1902// as both an immediate, and a bare symbol).1903//1904// This is fairly unpleasant, but it's the least disruptive thing we can do1905// and keeps all the hacks confined to the RISC-V backend code.1906 1907def BareSymbolQC_E_LI : AsmOperandClass {1908  let Name = "BareSymbolQC_E_LI";1909  let PredicateMethod = "isBareSymbol";1910  let RenderMethod = "addImmOperands";1911  let DiagnosticType = "InvalidBareSymbolQC_E_LI";1912  let ParserMethod = "parseBareSymbol";1913}1914 1915def hack_bare_symbol_qc_e_li : Operand<XLenVT> {1916  let ParserMatchClass = BareSymbolQC_E_LI;1917  let MCOperandPredicate = [{1918    return MCOp.isExpr() && MCOp.isBareSymbolRef();1919  }];1920}1921 1922let Predicates = [HasVendorXqcili, IsRV32] in {1923def : InstAlias<"qc.e.li $rd, $sym", (ADDI GPR:$rd, X0, hack_bare_symbol_qc_e_li:$sym), 3>;1924} // Predicates = [HasVendorXqcili, IsRV32]1925// END HACKS1926