brintos

brintos / llvm-project-archived public Read only

0
0
Text · 104.0 KiB · 2e6653e Raw
2600 lines · plain
1//== LoongArchInstrInfo.td - Target Description for LoongArch -*- 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 LoongArch instructions in TableGen format.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// LoongArch specific DAG Nodes.15//===----------------------------------------------------------------------===//16 17// Target-independent type requirements, but with target-specific formats.18def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,19                                       SDTCisVT<1, i32>]>;20def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,21                                   SDTCisVT<1, i32>]>;22 23// Target-dependent type requirements.24def SDT_LoongArchCall : SDTypeProfile<0, -1, [SDTCisVT<0, GRLenVT>]>;25def SDT_LoongArchIntBinOpW : SDTypeProfile<1, 2, [26  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>27]>;28 29def SDT_LoongArchSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,30                                                 SDTCisVT<3, OtherVT>,31                                                 SDTCisSameAs<0, 4>,32                                                 SDTCisSameAs<4, 5>]>;33 34def SDT_LoongArchBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,35                                             SDTCisVT<2, OtherVT>,36                                             SDTCisVT<3, OtherVT>]>;37 38def SDT_LoongArchBStrIns: SDTypeProfile<1, 4, [39  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>,40  SDTCisSameAs<3, 4>41]>;42 43def SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [44  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3>45]>;46 47// "VI" means no output and an integer input.48def SDT_LoongArchVI : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>;49 50def SDT_LoongArchCsrrd : SDTypeProfile<1, 1, [SDTCisInt<0>,51                                              SDTCisVT<1, GRLenVT>]>;52def SDT_LoongArchCsrwr : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,53                                              SDTCisVT<2, GRLenVT>]>;54def SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>,55                                                SDTCisSameAs<0, 1>,56                                                SDTCisSameAs<0, 2>,57                                                SDTCisVT<3, GRLenVT>]>;58def SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>,59                                                SDTCisSameAs<0, 1>]>;60def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>,61                                                   SDTCisSameAs<0, 1>]>;62def SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>,63                                                   SDTCisSameAs<0, 1>]>;64 65def SDT_LoongArchBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,66                                                     SDTCisVT<1, i32>,67                                                     SDTCisSameAs<1, 2>]>;68def SDT_LoongArchSplitPairF64 : SDTypeProfile<2, 1, [SDTCisVT<0, i32>,69                                                     SDTCisVT<1, i32>,70                                                     SDTCisVT<2, f64>]>;71 72// TODO: Add LoongArch specific DAG Nodes73// Target-independent nodes, but with target-specific formats.74def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,75                           [SDNPHasChain, SDNPOutGlue]>;76def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,77                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;78 79// Target-dependent nodes.80def loongarch_call : SDNode<"LoongArchISD::CALL", SDT_LoongArchCall,81                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,82                             SDNPVariadic]>;83def loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone,84                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;85def loongarch_tail : SDNode<"LoongArchISD::TAIL", SDT_LoongArchCall,86                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,87                             SDNPVariadic]>;88def loongarch_call_medium : SDNode<"LoongArchISD::CALL_MEDIUM", SDT_LoongArchCall,89                                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,90                                    SDNPVariadic]>;91def loongarch_tail_medium : SDNode<"LoongArchISD::TAIL_MEDIUM", SDT_LoongArchCall,92                                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,93                                    SDNPVariadic]>;94def loongarch_call_large : SDNode<"LoongArchISD::CALL_LARGE", SDT_LoongArchCall,95                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,96                                   SDNPVariadic]>;97def loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall,98                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,99                                   SDNPVariadic]>;100def loongarch_selectcc : SDNode<"LoongArchISD::SELECT_CC", SDT_LoongArchSelectCC>;101def loongarch_brcc : SDNode<"LoongArchISD::BR_CC", SDT_LoongArchBrCC,102                            [SDNPHasChain]>;103 104// 32-bit shifts, directly matching the semantics of the named LoongArch105// instructions.106def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;107def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;108def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;109 110def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;111 112// unsigned 32-bit integer division113def loongarch_div_w : SDNode<"LoongArchISD::DIV_W", SDT_LoongArchIntBinOpW>;114def loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>;115def loongarch_mod_w : SDNode<"LoongArchISD::MOD_W", SDT_LoongArchIntBinOpW>;116def loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>;117 118// CRC check operations119def loongarch_crc_w_b_w120    : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;121def loongarch_crc_w_h_w122    : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;123def loongarch_crc_w_w_w124    : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;125def loongarch_crc_w_d_w126    : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;127def loongarch_crcc_w_b_w : SDNode<"LoongArchISD::CRCC_W_B_W",128                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;129def loongarch_crcc_w_h_w : SDNode<"LoongArchISD::CRCC_W_H_W",130                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;131def loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W",132                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;133def loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W",134                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;135 136def loongarch_bstrins137    : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;138def loongarch_bstrpick139    : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>;140 141// Byte-swapping and bit-reversal142def loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>;143def loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>;144def loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>;145def loongarch_bitrev_8b : SDNode<"LoongArchISD::BITREV_8B", SDTUnaryOp>;146def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;147 148// Bit counting operations149def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;150def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;151 152def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI,153                             [SDNPHasChain, SDNPSideEffect]>;154def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,155                             [SDNPHasChain, SDNPSideEffect]>;156def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,157                              [SDNPHasChain, SDNPSideEffect]>;158 159// FPR<->GPR transfer operations160def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR",161                                  SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>;162def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR",163                                  SDT_LoongArchMovgr2fcsr,164                                  [SDNPHasChain, SDNPSideEffect]>;165 166def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,167                                [SDNPHasChain, SDNPSideEffect]>;168def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd,169                              [SDNPHasChain, SDNPSideEffect]>;170 171// Write new value to CSR and return old value.172// Operand 0: A chain pointer.173// Operand 1: The new value to write.174// Operand 2: The address of the required CSR.175// Result 0: The old value of the CSR.176// Result 1: The new chain pointer.177def loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr,178                              [SDNPHasChain, SDNPSideEffect]>;179 180// Similar to CSRWR but with a write mask.181// Operand 0: A chain pointer.182// Operand 1: The new value to write.183// Operand 2: The write mask.184// Operand 3: The address of the required CSR.185// Result 0: The old value of the CSR.186// Result 1: The new chain pointer.187def loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG",188                                SDT_LoongArchCsrxchg,189                                [SDNPHasChain, SDNPSideEffect]>;190 191// IOCSR access operations192def loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp,193                                  [SDNPHasChain, SDNPSideEffect]>;194def loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp,195                                  [SDNPHasChain, SDNPSideEffect]>;196def loongarch_iocsrrd_w : SDNode<"LoongArchISD::IOCSRRD_W", SDTUnaryOp,197                                  [SDNPHasChain, SDNPSideEffect]>;198def loongarch_iocsrrd_d : SDNode<"LoongArchISD::IOCSRRD_D", SDTUnaryOp,199                                  [SDNPHasChain, SDNPSideEffect]>;200def loongarch_iocsrwr_b : SDNode<"LoongArchISD::IOCSRWR_B",201                                  SDT_LoongArchIocsrwr,202                                  [SDNPHasChain, SDNPSideEffect]>;203def loongarch_iocsrwr_h : SDNode<"LoongArchISD::IOCSRWR_H",204                                  SDT_LoongArchIocsrwr,205                                  [SDNPHasChain, SDNPSideEffect]>;206def loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W",207                                  SDT_LoongArchIocsrwr,208                                  [SDNPHasChain, SDNPSideEffect]>;209def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D",210                                  SDT_LoongArchIocsrwr,211                                  [SDNPHasChain, SDNPSideEffect]>;212 213// Read CPU configuration information operation214def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp,215                               [SDNPHasChain]>;216 217// Build and split F64 pair218def loongarch_build_pair_f64 : SDNode<"LoongArchISD::BUILD_PAIR_F64",219                                      SDT_LoongArchBuildPairF64>;220def loongarch_split_pair_f64 : SDNode<"LoongArchISD::SPLIT_PAIR_F64",221                                      SDT_LoongArchSplitPairF64>;222 223def to_fclass_mask: SDNodeXForm<timm, [{224  uint64_t Check = N->getZExtValue();225  unsigned Mask = 0;226  if (Check & fcSNan)227    Mask |= LoongArch::FClassMaskSignalingNaN;228  if (Check & fcQNan)229    Mask |= LoongArch::FClassMaskQuietNaN;230  if (Check & fcPosInf)231    Mask |= LoongArch::FClassMaskPositiveInfinity;232  if (Check & fcNegInf)233    Mask |= LoongArch::FClassMaskNegativeInfinity;234  if (Check & fcPosNormal)235    Mask |= LoongArch::FClassMaskPositiveNormal;236  if (Check & fcNegNormal)237    Mask |= LoongArch::FClassMaskNegativeNormal;238  if (Check & fcPosSubnormal)239    Mask |= LoongArch::FClassMaskPositiveSubnormal;240  if (Check & fcNegSubnormal)241    Mask |= LoongArch::FClassMaskNegativeSubnormal;242  if (Check & fcPosZero)243    Mask |= LoongArch::FClassMaskPositiveZero;244  if (Check & fcNegZero)245    Mask |= LoongArch::FClassMaskNegativeZero;246  return CurDAG->getTargetConstant(Mask, SDLoc(N), Subtarget->getGRLenVT());247}]>;248 249//===----------------------------------------------------------------------===//250// Operand and SDNode transformation definitions.251//===----------------------------------------------------------------------===//252 253class ImmAsmOperand<string prefix, int width, string suffix>254    : AsmOperandClass {255  let Name = prefix # "Imm" # width # suffix;256  let DiagnosticType = !strconcat("Invalid", Name);257  let RenderMethod = "addImmOperands";258}259 260class SImmAsmOperand<int width, string suffix = "">261    : ImmAsmOperand<"S", width, suffix> {262}263 264class UImmAsmOperand<int width, string suffix = "">265    : ImmAsmOperand<"U", width, suffix> {266}267 268// A parse method for "$r*" or "$r*, 0", where the 0 is be silently ignored.269// Only used for "AM*" instructions, in order to be compatible with GAS.270def AtomicMemAsmOperand : AsmOperandClass {271  let Name = "AtomicMemAsmOperand";272  let RenderMethod = "addRegOperands";273  let PredicateMethod = "isGPR";274  let ParserMethod = "parseAtomicMemOp";275}276 277def GPRMemAtomic : RegisterOperand<GPR> {278  let ParserMatchClass = AtomicMemAsmOperand;279  let PrintMethod = "printAtomicMemOp";280}281 282// A parameterized register class alternative to i32imm/i64imm from Target.td.283def grlenimm : Operand<GRLenVT>;284def imm32 : Operand<GRLenVT> {285  let ParserMatchClass = ImmAsmOperand<"", 32, "">;286}287def imm64 : Operand<i64> {288  let ParserMatchClass = ImmAsmOperand<"", 64, "">;289}290 291def uimm1 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<1>(Imm);}]>{292  let ParserMatchClass = UImmAsmOperand<1>;293}294 295def uimm2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]> {296  let ParserMatchClass = UImmAsmOperand<2>;297}298 299def uimm2_plus1 : Operand<GRLenVT>,300    ImmLeaf<GRLenVT, [{return isUInt<2>(Imm - 1);}]> {301  let ParserMatchClass = UImmAsmOperand<2, "plus1">;302  let EncoderMethod = "getImmOpValueSub1";303  let DecoderMethod = "decodeUImmOperand<2, 1>";304}305 306def uimm3 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<3>(Imm);}]> {307  let ParserMatchClass = UImmAsmOperand<3>;308}309 310def uimm4 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<4>(Imm);}]> {311  let ParserMatchClass = UImmAsmOperand<4>;312}313 314def uimm5 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<5>(Imm);}]> {315  let ParserMatchClass = UImmAsmOperand<5>;316}317 318def uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> {319  let ParserMatchClass = UImmAsmOperand<6>;320}321 322def uimm7 : Operand<GRLenVT> {323  let ParserMatchClass = UImmAsmOperand<7>;324}325 326def uimm8 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<8>(Imm);}]> {327  let ParserMatchClass = UImmAsmOperand<8>;328}329 330class UImm12Operand : Operand<GRLenVT>,331                      ImmLeaf <GRLenVT, [{return isUInt<12>(Imm);}]> {332  let DecoderMethod = "decodeUImmOperand<12>";333}334 335def uimm12 : UImm12Operand {336  let ParserMatchClass = UImmAsmOperand<12>;337}338 339def uimm12_ori : UImm12Operand {340  let ParserMatchClass = UImmAsmOperand<12, "ori">;341}342 343def uimm14 : Operand<GRLenVT>,344             ImmLeaf <GRLenVT, [{return isUInt<14>(Imm);}]> {345  let ParserMatchClass = UImmAsmOperand<14>;346}347 348def uimm15 : Operand<GRLenVT>,349             ImmLeaf <GRLenVT, [{return isUInt<15>(Imm);}]> {350  let ParserMatchClass = UImmAsmOperand<15>;351}352 353def simm5 : Operand<GRLenVT> {354  let ParserMatchClass = SImmAsmOperand<5>;355  let DecoderMethod = "decodeSImmOperand<5>";356}357 358def simm8 : Operand<GRLenVT>,359                 ImmLeaf<GRLenVT, [{return isInt<8>(Imm);}]> {360  let ParserMatchClass = SImmAsmOperand<8>;361  let DecoderMethod = "decodeSImmOperand<8>";362}363 364def simm8_lsl1 : Operand<GRLenVT>,365                 ImmLeaf<GRLenVT, [{return isShiftedInt<8,1>(Imm);}]> {366  let ParserMatchClass = SImmAsmOperand<8, "lsl1">;367  let EncoderMethod = "getImmOpValueAsr<1>";368  let DecoderMethod = "decodeSImmOperand<8, 1>";369}370 371def simm8_lsl2 : Operand<GRLenVT>,372                 ImmLeaf<GRLenVT, [{return isShiftedInt<8,2>(Imm);}]> {373  let ParserMatchClass = SImmAsmOperand<8, "lsl2">;374  let EncoderMethod = "getImmOpValueAsr<2>";375  let DecoderMethod = "decodeSImmOperand<8, 2>";376}377 378def simm8_lsl3 : Operand<GRLenVT>,379                 ImmLeaf<GRLenVT, [{return isShiftedInt<8,3>(Imm);}]> {380  let ParserMatchClass = SImmAsmOperand<8, "lsl3">;381  let EncoderMethod = "getImmOpValueAsr<3>";382  let DecoderMethod = "decodeSImmOperand<8, 3>";383}384 385def simm9_lsl3 : Operand<GRLenVT>,386                 ImmLeaf<GRLenVT, [{return isShiftedInt<9,3>(Imm);}]> {387  let ParserMatchClass = SImmAsmOperand<9, "lsl3">;388  let EncoderMethod = "getImmOpValueAsr<3>";389  let DecoderMethod = "decodeSImmOperand<9, 3>";390}391 392def simm10 : Operand<GRLenVT> {393  let ParserMatchClass = SImmAsmOperand<10>;394}395 396def simm10_lsl2 : Operand<GRLenVT>,397                  ImmLeaf<GRLenVT, [{return isShiftedInt<10,2>(Imm);}]> {398  let ParserMatchClass = SImmAsmOperand<10, "lsl2">;399  let EncoderMethod = "getImmOpValueAsr<2>";400  let DecoderMethod = "decodeSImmOperand<10, 2>";401}402 403def simm11_lsl1 : Operand<GRLenVT>,404                  ImmLeaf<GRLenVT, [{return isShiftedInt<11,1>(Imm);}]> {405  let ParserMatchClass = SImmAsmOperand<11, "lsl1">;406  let EncoderMethod = "getImmOpValueAsr<1>";407  let DecoderMethod = "decodeSImmOperand<11, 1>";408}409 410class SImm12Operand : Operand<GRLenVT>,411                      ImmLeaf <GRLenVT, [{return isInt<12>(Imm);}]> {412  let DecoderMethod = "decodeSImmOperand<12>";413}414 415def simm12 : SImm12Operand {416  let ParserMatchClass = SImmAsmOperand<12>;417}418 419def simm12_addlike : SImm12Operand {420  let ParserMatchClass = SImmAsmOperand<12, "addlike">;421}422 423def simm12_lu52id : SImm12Operand {424  let ParserMatchClass = SImmAsmOperand<12, "lu52id">;425}426 427def simm13 : Operand<GRLenVT> {428  let ParserMatchClass = SImmAsmOperand<13>;429  let DecoderMethod = "decodeSImmOperand<13>";430}431 432def simm14_lsl2 : Operand<GRLenVT>,433    ImmLeaf<GRLenVT, [{return isShiftedInt<14,2>(Imm);}]> {434  let ParserMatchClass = SImmAsmOperand<14, "lsl2">;435  let EncoderMethod = "getImmOpValueAsr<2>";436  let DecoderMethod = "decodeSImmOperand<14, 2>";437}438 439def simm16 : Operand<GRLenVT> {440  let ParserMatchClass = SImmAsmOperand<16>;441  let DecoderMethod = "decodeSImmOperand<16>";442}443 444def simm16_lsl2 : Operand<GRLenVT>,445    ImmLeaf<GRLenVT, [{return isInt<16>(Imm>>2);}]> {446  let ParserMatchClass = SImmAsmOperand<16, "lsl2">;447  let EncoderMethod = "getImmOpValueAsr<2>";448  let DecoderMethod = "decodeSImmOperand<16, 2>";449}450 451def simm16_lsl2_br : Operand<OtherVT> {452  let ParserMatchClass = SImmAsmOperand<16, "lsl2">;453  let EncoderMethod = "getImmOpValueAsr<2>";454  let DecoderMethod = "decodeSImmOperand<16, 2>";455}456 457class SImm20Operand : Operand<GRLenVT> {458  let DecoderMethod = "decodeSImmOperand<20>";459}460 461def simm20 : SImm20Operand {462  let ParserMatchClass = SImmAsmOperand<20>;463}464 465def simm20_pcalau12i : SImm20Operand {466  let ParserMatchClass = SImmAsmOperand<20, "pcalau12i">;467}468 469def simm20_lu12iw : SImm20Operand {470  let ParserMatchClass = SImmAsmOperand<20, "lu12iw">;471}472 473def simm20_lu32id : SImm20Operand {474  let ParserMatchClass = SImmAsmOperand<20, "lu32id">;475}476 477def simm20_pcaddu18i : SImm20Operand {478  let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;479}480 481def simm20_pcaddi : SImm20Operand {482  let ParserMatchClass = SImmAsmOperand<20, "pcaddi">;483}484 485def simm21_lsl2 : Operand<OtherVT> {486  let ParserMatchClass = SImmAsmOperand<21, "lsl2">;487  let EncoderMethod = "getImmOpValueAsr<2>";488  let DecoderMethod = "decodeSImmOperand<21, 2>";489}490 491def SImm26OperandB: AsmOperandClass {492  let Name = "SImm26OperandB";493  let PredicateMethod = "isSImm26Operand";494  let RenderMethod = "addImmOperands";495  let DiagnosticType = "InvalidSImm26Operand";496  let ParserMethod = "parseImmediate";497}498 499// A symbol or an imm used in B/PseudoBR.500def simm26_b : Operand<OtherVT> {501  let ParserMatchClass = SImm26OperandB;502  let EncoderMethod = "getImmOpValueAsr<2>";503  let DecoderMethod = "decodeSImmOperand<26, 2>";504}505 506def SImm26OperandBL: AsmOperandClass {507  let Name = "SImm26OperandBL";508  let PredicateMethod = "isSImm26Operand";509  let RenderMethod = "addImmOperands";510  let DiagnosticType = "InvalidSImm26Operand";511  let ParserMethod = "parseSImm26Operand";512}513 514// A symbol or an imm used in BL/PseudoCALL/PseudoTAIL.515def simm26_symbol : Operand<GRLenVT> {516  let ParserMatchClass = SImm26OperandBL;517  let EncoderMethod = "getImmOpValueAsr<2>";518  let DecoderMethod = "decodeSImmOperand<26, 2>";519}520 521// A 32-bit signed immediate with the lowest 16 bits zeroed, suitable for522// direct use with `addu16i.d`.523def simm16_lsl16 : Operand<GRLenVT>,524    ImmLeaf<GRLenVT, [{return isShiftedInt<16, 16>(Imm);}]>;525 526// A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for527// use in additions.528def simm32_hi16_lo12: Operand<GRLenVT>, ImmLeaf<GRLenVT, [{529  return !isInt<12>(Imm) && isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm));530}]>;531 532def BareSymbol : AsmOperandClass {533  let Name = "BareSymbol";534  let RenderMethod = "addImmOperands";535  let DiagnosticType = "InvalidBareSymbol";536  let ParserMethod = "parseImmediate";537}538 539// A bare symbol used in "PseudoLA_*" instructions.540def bare_symbol : Operand<GRLenVT> {541  let ParserMatchClass = BareSymbol;542}543 544def TPRelAddSymbol : AsmOperandClass {545  let Name = "TPRelAddSymbol";546  let RenderMethod = "addImmOperands";547  let DiagnosticType = "InvalidTPRelAddSymbol";548  let ParserMethod = "parseOperandWithModifier";549}550 551// A bare symbol with the %le_add_r variant.552def tprel_add_symbol : Operand<GRLenVT> {553  let ParserMatchClass = TPRelAddSymbol;554}555 556 557// Standalone (codegen-only) immleaf patterns.558 559// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048].560def simm12_plus1 : ImmLeaf<GRLenVT,561  [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;562 563// Return the negation of an immediate value.564def NegImm : SDNodeXForm<imm, [{565  return CurDAG->getSignedTargetConstant(-N->getSExtValue(), SDLoc(N),566                                         N->getValueType(0));567}]>;568 569// FP immediate patterns.570def fpimm0    : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>;571def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;572def fpimm1    : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>;573 574// Return an immediate subtracted from 32.575def ImmSubFrom32 : SDNodeXForm<imm, [{576  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),577                                   N->getValueType(0));578}]>;579 580// Return the lowest 12 bits of the signed immediate.581def LO12: SDNodeXForm<imm, [{582  return CurDAG->getSignedTargetConstant(SignExtend64<12>(N->getSExtValue()),583                                         SDLoc(N), N->getValueType(0));584}]>;585 586// Return the higher 16 bits of the signed immediate.587def HI16 : SDNodeXForm<imm, [{588  return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 16, SDLoc(N),589                                         N->getValueType(0));590}]>;591 592// Return the higher 16 bits of the signed immediate, adjusted for use within an593// `addu16i.d + addi` pair.594def HI16ForAddu16idAddiPair: SDNodeXForm<imm, [{595  auto Imm = N->getSExtValue();596  return CurDAG->getSignedTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16,597                                          SDLoc(N), N->getValueType(0));598}]>;599 600def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;601def AddrConstant : ComplexPattern<iPTR, 2, "SelectAddrConstant">;602def NonFIBaseAddr : ComplexPattern<iPTR, 1, "selectNonFIBaseAddr">;603def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm12">;604 605def fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa),606                      (fma node:$fj, node:$fk, node:$fa), [{607  return N->getFlags().hasNoSignedZeros();608}]>;609 610// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),611// in which imm = imm0 + imm1, and both imm0 & imm1 are simm12.612def AddiPair : PatLeaf<(imm), [{613  if (!N->hasOneUse())614    return false;615  // The immediate operand must be in range [-4096,-2049] or [2048,4094].616  int64_t Imm = N->getSExtValue();617  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);618}]>;619 620// Return -2048 if immediate is negative or 2047 if positive.621def AddiPairImmLarge : SDNodeXForm<imm, [{622  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;623  return CurDAG->getSignedTargetConstant(Imm, SDLoc(N),624                                         N->getValueType(0));625}]>;626 627// Return imm - (imm < 0 ? -2048 : 2047).628def AddiPairImmSmall : SDNodeXForm<imm, [{629  int64_t Imm = N->getSExtValue();630  int64_t Adj = Imm < 0 ? -2048 : 2047;631  return CurDAG->getSignedTargetConstant(Imm - Adj, SDLoc(N),632                                         N->getValueType(0));633}]>;634 635// Check if (mul r, imm) can be optimized to (SLLI (ALSL r, r, i0), i1),636// in which imm = (1 + (1 << i0)) << i1.637def AlslSlliImm : PatLeaf<(imm), [{638  if (!N->hasOneUse())639    return false;640  uint64_t Imm = N->getZExtValue();641  unsigned I1 = llvm::countr_zero(Imm);642  uint64_t Rem = Imm >> I1;643  return Rem == 3 || Rem == 5 || Rem == 9 || Rem == 17;644}]>;645 646def AlslSlliImmI1 : SDNodeXForm<imm, [{647  uint64_t Imm = N->getZExtValue();648  unsigned I1 = llvm::countr_zero(Imm);649  return CurDAG->getTargetConstant(I1, SDLoc(N),650                                   N->getValueType(0));651}]>;652 653def AlslSlliImmI0 : SDNodeXForm<imm, [{654  uint64_t Imm = N->getZExtValue();655  unsigned I1 = llvm::countr_zero(Imm);656  uint64_t I0;657  switch (Imm >> I1) {658  case 3:  I0 = 1; break;659  case 5:  I0 = 2; break;660  case 9:  I0 = 3; break;661  default: I0 = 4; break;662  }663  return CurDAG->getTargetConstant(I0, SDLoc(N),664                                   N->getValueType(0));665}]>;666 667// Check if (and r, imm) can be optimized to (BSTRINS r, R0, msb, lsb),668// in which imm = ~((2^^(msb-lsb+1) - 1) << lsb).669def BstrinsImm : PatLeaf<(imm), [{670  if (!N->hasOneUse())671    return false;672  uint64_t Imm = N->getZExtValue();673  // andi can be used instead if Imm <= 0xfff.674  if (Imm <= 0xfff)675    return false;676  unsigned MaskIdx, MaskLen;677  return N->getValueType(0).getSizeInBits() == 32678             ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)679             : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);680}]>;681 682def BstrinsMsb: SDNodeXForm<imm, [{683  uint64_t Imm = N->getZExtValue();684  unsigned MaskIdx, MaskLen;685  N->getValueType(0).getSizeInBits() == 32686      ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)687      : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);688  return CurDAG->getTargetConstant(MaskIdx + MaskLen - 1, SDLoc(N),689                                   N->getValueType(0));690}]>;691 692def BstrinsLsb: SDNodeXForm<imm, [{693  uint64_t Imm = N->getZExtValue();694  unsigned MaskIdx, MaskLen;695  N->getValueType(0).getSizeInBits() == 32696      ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)697      : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);698  return CurDAG->getTargetConstant(MaskIdx, SDLoc(N), N->getValueType(0));699}]>;700 701//===----------------------------------------------------------------------===//702// Instruction Formats703//===----------------------------------------------------------------------===//704 705include "LoongArchInstrFormats.td"706include "LoongArchFloatInstrFormats.td"707include "LoongArchLSXInstrFormats.td"708include "LoongArchLASXInstrFormats.td"709include "LoongArchLBTInstrFormats.td"710 711//===----------------------------------------------------------------------===//712// Instruction Class Templates713//===----------------------------------------------------------------------===//714 715let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {716class ALU_3R<bits<32> op>717    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">;718class ALU_2R<bits<32> op>719    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;720 721class ALU_3RI2<bits<32> op, Operand ImmOpnd>722    : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2),723              "$rd, $rj, $rk, $imm2">;724class ALU_3RI3<bits<32> op, Operand ImmOpnd>725    : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3),726              "$rd, $rj, $rk, $imm3">;727class ALU_2RI5<bits<32> op, Operand ImmOpnd>728    : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5),729              "$rd, $rj, $imm5">;730class ALU_2RI6<bits<32> op, Operand ImmOpnd>731    : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6),732              "$rd, $rj, $imm6">;733class ALU_2RI12<bits<32> op, Operand ImmOpnd>734    : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12),735               "$rd, $rj, $imm12">;736class ALU_2RI16<bits<32> op, Operand ImmOpnd>737    : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16),738               "$rd, $rj, $imm16">;739class ALU_1RI20<bits<32> op, Operand ImmOpnd>740    : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), "$rd, $imm20">;741} // hasSideEffects = 0, mayLoad = 0, mayStore = 0742 743let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in744class MISC_I15<bits<32> op>745    : FmtI15<op, (outs), (ins uimm15:$imm15), "$imm15">;746 747let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in748class RDTIME_2R<bits<32> op>749    : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), "$rd, $rj">;750 751let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {752class BrCC_2RI16<bits<32> op>753    : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16),754               "$rj, $rd, $imm16"> {755  let isBranch = 1;756  let isTerminator = 1;757}758class BrCCZ_1RI21<bits<32> op>759    : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21),760               "$rj, $imm21"> {761  let isBranch = 1;762  let isTerminator = 1;763}764class Br_I26<bits<32> op>765    : FmtI26<op, (outs), (ins simm26_b:$imm26), "$imm26"> {766  let isBranch = 1;767  let isTerminator = 1;768  let isBarrier = 1;769}770} // hasSideEffects = 0, mayLoad = 0, mayStore = 0771 772let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {773class LOAD_3R<bits<32> op>774    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">;775class LOAD_2RI12<bits<32> op>776    : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12_addlike:$imm12),777               "$rd, $rj, $imm12">;778class LOAD_2RI14<bits<32> op>779    : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),780               "$rd, $rj, $imm14">;781} // hasSideEffects = 0, mayLoad = 1, mayStore = 0782 783let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {784class STORE_3R<bits<32> op>785    : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk),786            "$rd, $rj, $rk">;787class STORE_2RI12<bits<32> op>788    : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12_addlike:$imm12),789               "$rd, $rj, $imm12">;790class STORE_2RI14<bits<32> op>791    : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14),792               "$rd, $rj, $imm14">;793} // hasSideEffects = 0, mayLoad = 0, mayStore = 1794 795let hasSideEffects = 0, mayLoad = 1, mayStore = 1,796    IsSubjectToAMORdConstraint = 1 in {797class AM_3R<bits<32> op>798    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj),799            "$rd, $rk, $rj"> {800  let Constraints = "@earlyclobber $rd";801}802 803class AMCAS_3R<bits<32> op>804    : Fmt3R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rk, GPRMemAtomic:$rj),805            "$rd, $rk, $rj"> {806  let Constraints = "@earlyclobber $dst, $dst = $rd";807  let IsAMCAS = 1;808}809} // hasSideEffects = 0, mayLoad = 1, mayStore = 1,810  // IsSubjectToAMORdConstraint = 1811 812let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {813class LLBase<bits<32> op>814    : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),815               "$rd, $rj, $imm14">;816class LLBase_ACQ<bits<32> op>817    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;818}819 820let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in {821class SCBase<bits<32> op>822    : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14),823               "$rd, $rj, $imm14">;824class SCBase_128<bits<32> op>825    : Fmt3R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rk, GPR:$rj),826               "$rd, $rk, $rj">;827class SCBase_REL<bits<32> op>828    : Fmt2R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj), "$rd, $rj">;829}830 831let hasSideEffects = 1 in832class IOCSRRD<bits<32> op>833    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;834 835let hasSideEffects = 1 in836class IOCSRWR<bits<32> op>837    : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), "$rd, $rj">;838 839//===----------------------------------------------------------------------===//840// Basic Integer Instructions841//===----------------------------------------------------------------------===//842 843// Arithmetic Operation Instructions844def ADD_W : ALU_3R<0x00100000>;845def SUB_W : ALU_3R<0x00110000>;846def ADDI_W : ALU_2RI12<0x02800000, simm12_addlike>;847let isReMaterializable = 1 in {848def LU12I_W : ALU_1RI20<0x14000000, simm20_lu12iw>;849}850def SLT  : ALU_3R<0x00120000>;851def SLTU : ALU_3R<0x00128000>;852def SLTI  : ALU_2RI12<0x02000000, simm12>;853def SLTUI : ALU_2RI12<0x02400000, simm12>;854def PCADDU12I : ALU_1RI20<0x1c000000, simm20>;855def AND  : ALU_3R<0x00148000>;856def OR   : ALU_3R<0x00150000>;857def NOR  : ALU_3R<0x00140000>;858def XOR  : ALU_3R<0x00158000>;859def ANDI : ALU_2RI12<0x03400000, uimm12>;860// See LoongArchInstrInfo::isAsCheapAsAMove for more details.861let isReMaterializable = 1, isAsCheapAsAMove = 1 in {862def ORI  : ALU_2RI12<0x03800000, uimm12_ori>;863def XORI : ALU_2RI12<0x03c00000, uimm12>;864}865def MUL_W   : ALU_3R<0x001c0000>;866def MULH_W  : ALU_3R<0x001c8000>;867def MULH_WU : ALU_3R<0x001d0000>;868let usesCustomInserter = true in {869def DIV_W   : ALU_3R<0x00200000>;870def MOD_W   : ALU_3R<0x00208000>;871def DIV_WU  : ALU_3R<0x00210000>;872def MOD_WU  : ALU_3R<0x00218000>;873} // usesCustomInserter = true874 875// Bit-shift Instructions876def SLL_W  : ALU_3R<0x00170000>;877def SRL_W  : ALU_3R<0x00178000>;878def SRA_W  : ALU_3R<0x00180000>;879 880def SLLI_W  : ALU_2RI5<0x00408000, uimm5>;881def SRLI_W  : ALU_2RI5<0x00448000, uimm5>;882def SRAI_W  : ALU_2RI5<0x00488000, uimm5>;883 884// Branch Instructions885def BEQ  : BrCC_2RI16<0x58000000>;886def BNE  : BrCC_2RI16<0x5c000000>;887def BLT  : BrCC_2RI16<0x60000000>;888def BGE  : BrCC_2RI16<0x64000000>;889def BLTU : BrCC_2RI16<0x68000000>;890def BGEU : BrCC_2RI16<0x6c000000>;891def B : Br_I26<0x50000000>;892 893let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, Defs=[R1] in894def BL : FmtI26<0x54000000, (outs), (ins simm26_symbol:$imm26), "$imm26">;895let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in896def JIRL : Fmt2RI16<0x4c000000, (outs GPR:$rd),897                    (ins GPR:$rj, simm16_lsl2:$imm16), "$rd, $rj, $imm16">;898 899// Common Memory Access Instructions900def LD_B  : LOAD_2RI12<0x28000000>;901def LD_H  : LOAD_2RI12<0x28400000>;902def LD_W  : LOAD_2RI12<0x28800000>;903def LD_BU : LOAD_2RI12<0x2a000000>;904def LD_HU : LOAD_2RI12<0x2a400000>;905def ST_B : STORE_2RI12<0x29000000>;906def ST_H : STORE_2RI12<0x29400000>;907def ST_W : STORE_2RI12<0x29800000>;908let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in909def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12),910                     "$imm5, $rj, $imm12">;911 912// Atomic Memory Access Instructions913def LL_W : LLBase<0x20000000>;914def SC_W : SCBase<0x21000000>;915 916// Barrier Instructions917def DBAR : MISC_I15<0x38720000>;918def IBAR : MISC_I15<0x38728000>;919 920// Other Miscellaneous Instructions921def SYSCALL : MISC_I15<0x002b0000>;922def BREAK   : MISC_I15<0x002a0000>;923def RDTIMEL_W : RDTIME_2R<0x00006000>;924def RDTIMEH_W : RDTIME_2R<0x00006400>;925 926// The CPUCFG instruction offers a reliable way to probing CPU features.927// Although support is not guaranteed on LA32R, having compiler support928// nevertheless enables applications to rely on its presence, potentially929// via kernel emulation if not available natively.930def CPUCFG : ALU_2R<0x00006c00>;931 932// Cache Maintenance Instructions933def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12),934                     "$op, $rj, $imm12">;935 936let Predicates = [Has32S] in {937// Arithmetic Operation Instructions938def ALSL_W : ALU_3RI2<0x00040000, uimm2_plus1>;939def ANDN : ALU_3R<0x00168000>;940def ORN  : ALU_3R<0x00160000>;941def PCADDI    : ALU_1RI20<0x18000000, simm20_pcaddi>;942def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>;943 944// Bit-shift Instructions945def ROTR_W : ALU_3R<0x001b0000>;946def ROTRI_W : ALU_2RI5<0x004c8000, uimm5>;947 948// Bit-manipulation Instructions949def EXT_W_B : ALU_2R<0x00005c00>;950def EXT_W_H : ALU_2R<0x00005800>;951def CLO_W   : ALU_2R<0x00001000>;952def CLZ_W   : ALU_2R<0x00001400>;953def CTO_W   : ALU_2R<0x00001800>;954def CTZ_W   : ALU_2R<0x00001c00>;955def BYTEPICK_W : ALU_3RI2<0x00080000, uimm2>;956def REVB_2H   : ALU_2R<0x00003000>;957def BITREV_4B : ALU_2R<0x00004800>;958def BITREV_W  : ALU_2R<0x00005000>;959let Constraints = "$rd = $dst" in {960def BSTRINS_W  : FmtBSTR_W<0x00600000, (outs GPR:$dst),961                           (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw),962                           "$rd, $rj, $msbw, $lsbw">;963}964def BSTRPICK_W : FmtBSTR_W<0x00608000, (outs GPR:$rd),965                           (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw),966                           "$rd, $rj, $msbw, $lsbw">;967def MASKEQZ : ALU_3R<0x00130000>;968def MASKNEZ : ALU_3R<0x00138000>;969 970// Branch Instructions971def BEQZ : BrCCZ_1RI21<0x40000000>;972def BNEZ : BrCCZ_1RI21<0x44000000>;973} // Predicates = [Has32S]974 975/// LA64 instructions976 977let Predicates = [IsLA64] in {978 979// Arithmetic Operation Instructions for 64-bits980def ADD_D : ALU_3R<0x00108000>;981def SUB_D : ALU_3R<0x00118000>;982// ADDI_D isn't always rematerializable, but isReMaterializable will be used as983// a hint which is verified in isReMaterializableImpl.984// See LoongArchInstrInfo::isAsCheapAsAMove for more details.985let isReMaterializable = 1, isAsCheapAsAMove = 1 in {986def ADDI_D : ALU_2RI12<0x02c00000, simm12_addlike>;987}988def ADDU16I_D : ALU_2RI16<0x10000000, simm16>;989def ALSL_WU : ALU_3RI2<0x00060000, uimm2_plus1>;990def ALSL_D  : ALU_3RI2<0x002c0000, uimm2_plus1>;991let Constraints = "$rd = $dst" in {992let hasSideEffects = 0, mayLoad = 0, mayStore = 0,993    isReMaterializable = 1 in994def LU32I_D : Fmt1RI20<0x16000000, (outs GPR:$dst),995                       (ins GPR:$rd, simm20_lu32id:$imm20),996                       "$rd, $imm20">;997}998let isReMaterializable = 1 in {999def LU52I_D : ALU_2RI12<0x03000000, simm12_lu52id>;1000}1001def PCADDU18I : ALU_1RI20<0x1e000000, simm20_pcaddu18i>;1002def MUL_D     : ALU_3R<0x001d8000>;1003def MULH_D    : ALU_3R<0x001e0000>;1004def MULH_DU   : ALU_3R<0x001e8000>;1005def MULW_D_W  : ALU_3R<0x001f0000>;1006def MULW_D_WU : ALU_3R<0x001f8000>;1007let usesCustomInserter = true in {1008def DIV_D     : ALU_3R<0x00220000>;1009def MOD_D     : ALU_3R<0x00228000>;1010def DIV_DU    : ALU_3R<0x00230000>;1011def MOD_DU    : ALU_3R<0x00238000>;1012} // usesCustomInserter = true1013 1014// Bit-shift Instructions for 64-bits1015def SLL_D  : ALU_3R<0x00188000>;1016def SRL_D  : ALU_3R<0x00190000>;1017def SRA_D  : ALU_3R<0x00198000>;1018def ROTR_D : ALU_3R<0x001b8000>;1019def SLLI_D  : ALU_2RI6<0x00410000, uimm6>;1020def SRLI_D  : ALU_2RI6<0x00450000, uimm6>;1021def SRAI_D  : ALU_2RI6<0x00490000, uimm6>;1022def ROTRI_D : ALU_2RI6<0x004d0000, uimm6>;1023 1024// Bit-manipulation Instructions for 64-bits1025def CLO_D : ALU_2R<0x00002000>;1026def CLZ_D : ALU_2R<0x00002400>;1027def CTO_D : ALU_2R<0x00002800>;1028def CTZ_D : ALU_2R<0x00002c00>;1029def BYTEPICK_D : ALU_3RI3<0x000c0000, uimm3>;1030def REVB_4H   : ALU_2R<0x00003400>;1031def REVB_2W   : ALU_2R<0x00003800>;1032def REVB_D    : ALU_2R<0x00003c00>;1033def REVH_2W   : ALU_2R<0x00004000>;1034def REVH_D    : ALU_2R<0x00004400>;1035def BITREV_8B : ALU_2R<0x00004c00>;1036def BITREV_D  : ALU_2R<0x00005400>;1037let Constraints = "$rd = $dst" in {1038def BSTRINS_D  : FmtBSTR_D<0x00800000, (outs GPR:$dst),1039                           (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd),1040                           "$rd, $rj, $msbd, $lsbd">;1041}1042def BSTRPICK_D : FmtBSTR_D<0x00c00000, (outs GPR:$rd),1043                           (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd),1044                           "$rd, $rj, $msbd, $lsbd">;1045 1046// Common Memory Access Instructions for 64-bits1047def LD_WU : LOAD_2RI12<0x2a800000>;1048def LD_D  : LOAD_2RI12<0x28c00000>;1049def ST_D : STORE_2RI12<0x29c00000>;1050def LDX_B  : LOAD_3R<0x38000000>;1051def LDX_H  : LOAD_3R<0x38040000>;1052def LDX_W  : LOAD_3R<0x38080000>;1053def LDX_D  : LOAD_3R<0x380c0000>;1054def LDX_BU : LOAD_3R<0x38200000>;1055def LDX_HU : LOAD_3R<0x38240000>;1056def LDX_WU : LOAD_3R<0x38280000>;1057def STX_B : STORE_3R<0x38100000>;1058def STX_H : STORE_3R<0x38140000>;1059def STX_W : STORE_3R<0x38180000>;1060def STX_D : STORE_3R<0x381c0000>;1061def LDPTR_W : LOAD_2RI14<0x24000000>;1062def LDPTR_D : LOAD_2RI14<0x26000000>;1063def STPTR_W : STORE_2RI14<0x25000000>;1064def STPTR_D : STORE_2RI14<0x27000000>;1065let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in1066def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk),1067                       "$imm5, $rj, $rk">;1068 1069// Bound Check Memory Access Instructions1070def LDGT_B : LOAD_3R<0x38780000>;1071def LDGT_H : LOAD_3R<0x38788000>;1072def LDGT_W : LOAD_3R<0x38790000>;1073def LDGT_D : LOAD_3R<0x38798000>;1074def LDLE_B : LOAD_3R<0x387a0000>;1075def LDLE_H : LOAD_3R<0x387a8000>;1076def LDLE_W : LOAD_3R<0x387b0000>;1077def LDLE_D : LOAD_3R<0x387b8000>;1078def STGT_B : STORE_3R<0x387c0000>;1079def STGT_H : STORE_3R<0x387c8000>;1080def STGT_W : STORE_3R<0x387d0000>;1081def STGT_D : STORE_3R<0x387d8000>;1082def STLE_B : STORE_3R<0x387e0000>;1083def STLE_H : STORE_3R<0x387e8000>;1084def STLE_W : STORE_3R<0x387f0000>;1085def STLE_D : STORE_3R<0x387f8000>;1086 1087// Atomic Memory Access Instructions for 64-bits1088def AMSWAP_B     : AM_3R<0x385c0000>;1089def AMSWAP_H     : AM_3R<0x385c8000>;1090def AMSWAP_W     : AM_3R<0x38600000>;1091def AMSWAP_D     : AM_3R<0x38608000>;1092def AMADD_B      : AM_3R<0x385d0000>;1093def AMADD_H      : AM_3R<0x385d8000>;1094def AMADD_W      : AM_3R<0x38610000>;1095def AMADD_D      : AM_3R<0x38618000>;1096def AMAND_W      : AM_3R<0x38620000>;1097def AMAND_D      : AM_3R<0x38628000>;1098def AMOR_W       : AM_3R<0x38630000>;1099def AMOR_D       : AM_3R<0x38638000>;1100def AMXOR_W      : AM_3R<0x38640000>;1101def AMXOR_D      : AM_3R<0x38648000>;1102def AMMAX_W      : AM_3R<0x38650000>;1103def AMMAX_D      : AM_3R<0x38658000>;1104def AMMIN_W      : AM_3R<0x38660000>;1105def AMMIN_D      : AM_3R<0x38668000>;1106def AMMAX_WU     : AM_3R<0x38670000>;1107def AMMAX_DU     : AM_3R<0x38678000>;1108def AMMIN_WU     : AM_3R<0x38680000>;1109def AMMIN_DU     : AM_3R<0x38688000>;1110def AMSWAP__DB_B : AM_3R<0x385e0000>;1111def AMSWAP__DB_H : AM_3R<0x385e8000>;1112def AMSWAP__DB_W : AM_3R<0x38690000>;1113def AMSWAP__DB_D : AM_3R<0x38698000>;1114def AMADD__DB_B  : AM_3R<0x385f0000>;1115def AMADD__DB_H  : AM_3R<0x385f8000>;1116def AMADD__DB_W  : AM_3R<0x386a0000>;1117def AMADD__DB_D  : AM_3R<0x386a8000>;1118def AMAND__DB_W  : AM_3R<0x386b0000>;1119def AMAND__DB_D  : AM_3R<0x386b8000>;1120def AMOR__DB_W   : AM_3R<0x386c0000>;1121def AMOR__DB_D   : AM_3R<0x386c8000>;1122def AMXOR__DB_W  : AM_3R<0x386d0000>;1123def AMXOR__DB_D  : AM_3R<0x386d8000>;1124def AMMAX__DB_W  : AM_3R<0x386e0000>;1125def AMMAX__DB_D  : AM_3R<0x386e8000>;1126def AMMIN__DB_W  : AM_3R<0x386f0000>;1127def AMMIN__DB_D  : AM_3R<0x386f8000>;1128def AMMAX__DB_WU : AM_3R<0x38700000>;1129def AMMAX__DB_DU : AM_3R<0x38708000>;1130def AMMIN__DB_WU : AM_3R<0x38710000>;1131def AMMIN__DB_DU : AM_3R<0x38718000>;1132def AMCAS_B      : AMCAS_3R<0x38580000>;1133def AMCAS_H      : AMCAS_3R<0x38588000>;1134def AMCAS_W      : AMCAS_3R<0x38590000>;1135def AMCAS_D      : AMCAS_3R<0x38598000>;1136def AMCAS__DB_B  : AMCAS_3R<0x385a0000>;1137def AMCAS__DB_H  : AMCAS_3R<0x385a8000>;1138def AMCAS__DB_W  : AMCAS_3R<0x385b0000>;1139def AMCAS__DB_D  : AMCAS_3R<0x385b8000>;1140def LL_D : LLBase<0x22000000>;1141def SC_D : SCBase<0x23000000>;1142def SC_Q : SCBase_128<0x38570000>;1143def LLACQ_W : LLBase_ACQ<0x38578000>;1144def SCREL_W : SCBase_REL<0x38578400>;1145def LLACQ_D : LLBase_ACQ<0x38578800>;1146def SCREL_D : SCBase_REL<0x38578C00>;1147 1148// CRC Check Instructions1149def CRC_W_B_W  : ALU_3R<0x00240000>;1150def CRC_W_H_W  : ALU_3R<0x00248000>;1151def CRC_W_W_W  : ALU_3R<0x00250000>;1152def CRC_W_D_W  : ALU_3R<0x00258000>;1153def CRCC_W_B_W : ALU_3R<0x00260000>;1154def CRCC_W_H_W : ALU_3R<0x00268000>;1155def CRCC_W_W_W : ALU_3R<0x00270000>;1156def CRCC_W_D_W : ALU_3R<0x00278000>;1157 1158// Other Miscellaneous Instructions for 64-bits1159def ASRTLE_D : FmtASRT<0x00010000, (outs), (ins GPR:$rj, GPR:$rk),1160                       "$rj, $rk">;1161def ASRTGT_D : FmtASRT<0x00018000, (outs), (ins GPR:$rj, GPR:$rk),1162                       "$rj, $rk">;1163def RDTIME_D : RDTIME_2R<0x00006800>;1164} // Predicates = [IsLA64]1165 1166//===----------------------------------------------------------------------===//1167// Pseudo-instructions and codegen patterns1168//1169// Naming convention: For 'generic' pattern classes, we use the naming1170// convention PatTy1Ty2.1171//===----------------------------------------------------------------------===//1172 1173/// Generic pattern classes1174 1175def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{1176  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);1177}]>;1178class PatGprGpr<SDPatternOperator OpNode, LAInst Inst>1179    : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>;1180class PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst>1181    : Pat<(sext_inreg (OpNode (assertsexti32 GPR:$rj), (assertsexti32 GPR:$rk)), i32), (Inst GPR:$rj, GPR:$rk)>;1182class PatGpr<SDPatternOperator OpNode, LAInst Inst>1183    : Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>;1184 1185class PatGprImm<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>1186    : Pat<(OpNode GPR:$rj, ImmOpnd:$imm),1187          (Inst GPR:$rj, ImmOpnd:$imm)>;1188class PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>1189    : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32),1190          (Inst GPR:$rj, ImmOpnd:$imm)>;1191 1192/// Predicates1193def AddLike: PatFrags<(ops node:$A, node:$B),1194                      [(add node:$A, node:$B), (or node:$A, node:$B)], [{1195    return CurDAG->isBaseWithConstantOffset(SDValue(N, 0));1196}]>;1197 1198/// Simple arithmetic operations1199 1200// Match both a plain shift and one where the shift amount is masked (this is1201// typically introduced when the legalizer promotes the shift amount and1202// zero-extends it). For LoongArch, the mask is unnecessary as shifts in the1203// base ISA only read the least significant 5 bits (LA32) or 6 bits (LA64).1204def shiftMaskGRLen1205    : ComplexPattern<GRLenVT, 1, "selectShiftMaskGRLen", [], [], 0>;1206def shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;1207 1208def sexti32 : ComplexPattern<i64, 1, "selectSExti32">;1209def zexti32 : ComplexPattern<i64, 1, "selectZExti32">;1210 1211class shiftop<SDPatternOperator operator>1212    : PatFrag<(ops node:$val, node:$count),1213              (operator node:$val, (GRLenVT (shiftMaskGRLen node:$count)))>;1214class shiftopw<SDPatternOperator operator>1215    : PatFrag<(ops node:$val, node:$count),1216              (operator node:$val, (i64 (shiftMask32 node:$count)))>;1217 1218def mul_const_oneuse : PatFrag<(ops node:$A, node:$B),1219                               (mul node:$A, node:$B), [{1220  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))1221    return N1C->hasOneUse();1222  return false;1223}]>;1224 1225let Predicates = [IsLA32] in {1226def : PatGprGpr<add, ADD_W>;1227def : PatGprImm<add, ADDI_W, simm12>;1228def : PatGprGpr<sub, SUB_W>;1229def : PatGprGpr<sdiv, DIV_W>;1230def : PatGprGpr<udiv, DIV_WU>;1231def : PatGprGpr<srem, MOD_W>;1232def : PatGprGpr<urem, MOD_WU>;1233def : PatGprGpr<mul, MUL_W>;1234def : PatGprGpr<mulhs, MULH_W>;1235def : PatGprGpr<mulhu, MULH_WU>;1236} // Predicates = [IsLA32]1237 1238let Predicates = [IsLA32, Has32S] in {1239def : PatGprGpr<shiftop<rotr>, ROTR_W>;1240def : PatGprImm<rotr, ROTRI_W, uimm5>;1241 1242foreach Idx = 1...3 in {1243  defvar ShamtA = !mul(8, Idx);1244  defvar ShamtB = !mul(8, !sub(4, Idx));1245  def : Pat<(or (shl GPR:$rk, (i32 ShamtA)), (srl GPR:$rj, (i32 ShamtB))),1246            (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>;1247}1248} // Predicates = [IsLA32, Has32S]1249 1250let Predicates = [IsLA64] in {1251def : PatGprGpr<add, ADD_D>;1252def : PatGprImm<add, ADDI_D, simm12>;1253def : PatGprGpr<sub, SUB_D>;1254def : PatGprGpr<sdiv, DIV_D>;1255def : PatGprGpr_32<sdiv, DIV_W>;1256def : PatGprGpr<udiv, DIV_DU>;1257def : PatGprGpr<loongarch_div_w, DIV_W>;1258def : PatGprGpr<loongarch_div_wu, DIV_WU>;1259def : PatGprGpr<srem, MOD_D>;1260def : PatGprGpr_32<srem, MOD_W>;1261def : PatGprGpr<urem, MOD_DU>;1262def : PatGprGpr<loongarch_mod_w, MOD_W>;1263def : PatGprGpr<loongarch_mod_wu, MOD_WU>;1264def : PatGprGpr<shiftop<rotr>, ROTR_D>;1265def : PatGprGpr<shiftopw<loongarch_rotr_w>, ROTR_W>;1266def : PatGprImm<rotr, ROTRI_D, uimm6>;1267def : PatGprImm_32<rotr, ROTRI_W, uimm5>;1268def : PatGprImm<loongarch_rotr_w, ROTRI_W, uimm5>;1269// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the1270// product are used.1271def : PatGprGpr<mul, MUL_D>;1272def : PatGprGpr<mulhs, MULH_D>;1273def : PatGprGpr<mulhu, MULH_DU>;1274// Select MULW_D_W for calculating the full 64 bits product of i32xi32 signed1275// multiplication.1276def : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))),1277          (MULW_D_W GPR:$rj, GPR:$rk)>;1278// Select MULW_D_WU for calculating the full 64 bits product of i32xi321279// unsigned multiplication.1280def : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)),1281                    (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))),1282          (MULW_D_WU GPR:$rj, GPR:$rk)>;1283 1284def : Pat<(add GPR:$rj, simm16_lsl16:$imm),1285          (ADDU16I_D GPR:$rj, (HI16 $imm))>;1286def : Pat<(add GPR:$rj, simm32_hi16_lo12:$imm),1287          (ADDI_D (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)),1288                  (LO12 $imm))>;1289def : Pat<(sext_inreg (add GPR:$rj, simm32_hi16_lo12:$imm), i32),1290          (ADDI_W (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)),1291                  (LO12 $imm))>;1292 1293let Predicates = [IsLA32] in {1294def : Pat<(add GPR:$rj, (AddiPair:$im)),1295          (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)),1296                  (AddiPairImmSmall AddiPair:$im))>;1297} // Predicates = [IsLA32]1298 1299let Predicates = [IsLA64] in {1300def : Pat<(add GPR:$rj, (AddiPair:$im)),1301          (ADDI_D (ADDI_D GPR:$rj, (AddiPairImmLarge AddiPair:$im)),1302                  (AddiPairImmSmall AddiPair:$im))>;1303def : Pat<(sext_inreg (add GPR:$rj, (AddiPair:$im)), i32),1304          (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)),1305                  (AddiPairImmSmall AddiPair:$im))>;1306} // Predicates = [IsLA64]1307 1308let Predicates = [IsLA32, Has32S] in {1309foreach Idx0 = 1...4 in {1310  foreach Idx1 = 1...4 in {1311    defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1));1312    def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)),1313              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)),1314                      GPR:$r, (i32 Idx1))>;1315  }1316}1317foreach Idx0 = 1...4 in {1318  foreach Idx1 = 1...4 in {1319    defvar Cb = !add(1, !shl(1, Idx0));1320    defvar CImm = !add(Cb, !shl(Cb, Idx1));1321    def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)),1322              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)),1323                      (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>;1324  }1325}1326} // Predicates = [IsLA32, Has32S]1327 1328let Predicates = [IsLA64] in {1329foreach Idx0 = 1...4 in {1330  foreach Idx1 = 1...4 in {1331    defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1));1332    def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32),1333              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)),1334                      GPR:$r, (i64 Idx1))>;1335    def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)),1336              (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)),1337                      GPR:$r, (i64 Idx1))>;1338  }1339}1340foreach Idx0 = 1...4 in {1341  foreach Idx1 = 1...4 in {1342    defvar Cb = !add(1, !shl(1, Idx0));1343    defvar CImm = !add(Cb, !shl(Cb, Idx1));1344    def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32),1345              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)),1346                      (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>;1347    def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)),1348              (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)),1349                      (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>;1350  }1351}1352} // Predicates = [IsLA64]1353 1354let Predicates = [IsLA32, Has32S] in {1355def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)),1356          (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),1357                  (AlslSlliImmI1 AlslSlliImm:$im))>;1358} // Predicates = [IsLA32, Has32S]1359 1360let Predicates = [IsLA64] in {1361def : Pat<(sext_inreg (mul GPR:$rj, (AlslSlliImm:$im)), i32),1362          (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),1363                  (AlslSlliImmI1 AlslSlliImm:$im))>;1364def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)),1365          (SLLI_D (ALSL_D GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),1366                  (AlslSlliImmI1 AlslSlliImm:$im))>;1367} // Predicates = [IsLA64]1368 1369foreach Idx = 1...7 in {1370  defvar ShamtA = !mul(8, Idx);1371  defvar ShamtB = !mul(8, !sub(8, Idx));1372  def : Pat<(or (shl GPR:$rk, (i64 ShamtA)), (srl GPR:$rj, (i64 ShamtB))),1373            (BYTEPICK_D GPR:$rj, GPR:$rk, Idx)>;1374}1375 1376foreach Idx = 1...3 in {1377  defvar ShamtA = !mul(8, Idx);1378  defvar ShamtB = !mul(8, !sub(4, Idx));1379  // NOTE: the srl node would already be transformed into a loongarch_bstrpick1380  // by the time this pattern gets to execute, hence the weird construction.1381  def : Pat<(sext_inreg (or (shl GPR:$rk, (i64 ShamtA)),1382                            (loongarch_bstrpick GPR:$rj, (i64 31),1383                                                         (i64 ShamtB))), i32),1384            (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>;1385}1386} // Predicates = [IsLA64]1387 1388def : PatGprGpr<and, AND>;1389def : PatGprImm<and, ANDI, uimm12>;1390def : PatGprGpr<or, OR>;1391def : PatGprImm<or, ORI, uimm12>;1392def : PatGprGpr<xor, XOR>;1393def : PatGprImm<xor, XORI, uimm12>;1394def : Pat<(not GPR:$rj), (NOR GPR:$rj, R0)>;1395def : Pat<(not (or GPR:$rj, GPR:$rk)), (NOR GPR:$rj, GPR:$rk)>;1396def : Pat<(or GPR:$rj, (not GPR:$rk)), (ORN GPR:$rj, GPR:$rk)>;1397def : Pat<(and GPR:$rj, (not GPR:$rk)), (ANDN GPR:$rj, GPR:$rk)>;1398 1399let Predicates = [IsLA32, Has32S] in {1400def : Pat<(and GPR:$rj, BstrinsImm:$imm),1401          (BSTRINS_W GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm),1402                     (BstrinsLsb BstrinsImm:$imm))>;1403} // Predicates = [IsLA32, Has32S]1404 1405let Predicates = [IsLA64] in {1406def : Pat<(and GPR:$rj, BstrinsImm:$imm),1407          (BSTRINS_D GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm),1408                     (BstrinsLsb BstrinsImm:$imm))>;1409} // Predicates = [IsLA64]1410 1411/// Traps1412 1413// We lower `trap` to `amswap.w rd:$r0, rk:$r1, rj:$r0`, as this is guaranteed1414// to trap with an INE (non-existent on LA32, explicitly documented to INE on1415// LA64). And the resulting signal is different from `debugtrap` like on some1416// other existing ports so programs/porters might have an easier time.1417def PseudoUNIMP : Pseudo<(outs), (ins), [(trap)]>,1418                  PseudoInstExpansion<(AMSWAP_W R0, R1, R0)>;1419 1420// We lower `debugtrap` to `break 0`, as this is guaranteed to exist and work,1421// even for LA32 Primary. Also, because so far the ISA does not provide a1422// specific trap instruction/kind exclusively for alerting the debugger,1423// every other project uses the generic immediate of 0 for this.1424def : Pat<(debugtrap), (BREAK 0)>;1425 1426/// Bit counting operations1427 1428let Predicates = [IsLA64] in {1429def : PatGpr<ctlz, CLZ_D>;1430def : PatGpr<cttz, CTZ_D>;1431def : Pat<(ctlz (not GPR:$rj)), (CLO_D GPR:$rj)>;1432def : Pat<(cttz (not GPR:$rj)), (CTO_D GPR:$rj)>;1433def : PatGpr<loongarch_clzw, CLZ_W>;1434def : PatGpr<loongarch_ctzw, CTZ_W>;1435def : Pat<(loongarch_clzw (not GPR:$rj)), (CLO_W GPR:$rj)>;1436def : Pat<(loongarch_ctzw (not GPR:$rj)), (CTO_W GPR:$rj)>;1437} // Predicates = [IsLA64]1438 1439let Predicates = [IsLA32, Has32S] in {1440def : PatGpr<ctlz, CLZ_W>;1441def : PatGpr<cttz, CTZ_W>;1442def : Pat<(ctlz (not GPR:$rj)), (CLO_W GPR:$rj)>;1443def : Pat<(cttz (not GPR:$rj)), (CTO_W GPR:$rj)>;1444} // Predicates = [IsLA32, Has32S]1445 1446/// FrameIndex calculations1447let Predicates = [IsLA32] in {1448def : Pat<(AddLike (i32 BaseAddr:$rj), simm12:$imm12),1449          (ADDI_W (i32 BaseAddr:$rj), simm12:$imm12)>;1450} // Predicates = [IsLA32]1451let Predicates = [IsLA64] in {1452def : Pat<(AddLike (i64 BaseAddr:$rj), simm12:$imm12),1453          (ADDI_D (i64 BaseAddr:$rj), simm12:$imm12)>;1454} // Predicates = [IsLA64]1455 1456/// Shifted addition1457let Predicates = [IsLA32, Has32S] in {1458def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),1459          (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;1460} // Predicates = [IsLA32, Has32S]1461let Predicates = [IsLA64] in {1462def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),1463          (ALSL_D GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;1464def : Pat<(sext_inreg (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), i32),1465          (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;1466def : Pat<(loongarch_bstrpick (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),1467                              (i64 31), (i64 0)),1468          (ALSL_WU GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;1469} // Predicates = [IsLA64]1470 1471/// Shift1472 1473let Predicates = [IsLA32] in {1474def : PatGprGpr<shiftop<shl>, SLL_W>;1475def : PatGprGpr<shiftop<sra>, SRA_W>;1476def : PatGprGpr<shiftop<srl>, SRL_W>;1477def : PatGprImm<shl, SLLI_W, uimm5>;1478def : PatGprImm<sra, SRAI_W, uimm5>;1479def : PatGprImm<srl, SRLI_W, uimm5>;1480} // Predicates = [IsLA32]1481 1482let Predicates = [IsLA64] in {1483def : PatGprGpr<shiftopw<loongarch_sll_w>, SLL_W>;1484def : PatGprGpr<shiftopw<loongarch_sra_w>, SRA_W>;1485def : PatGprGpr<shiftopw<loongarch_srl_w>, SRL_W>;1486def : PatGprGpr<shiftop<shl>, SLL_D>;1487def : PatGprGpr<shiftop<sra>, SRA_D>;1488def : PatGprGpr<shiftop<srl>, SRL_D>;1489def : PatGprImm<shl, SLLI_D, uimm6>;1490def : PatGprImm<sra, SRAI_D, uimm6>;1491def : PatGprImm<srl, SRLI_D, uimm6>;1492} // Predicates = [IsLA64]1493 1494/// sext and zext1495 1496let Predicates = [Has32S] in {1497def : Pat<(sext_inreg GPR:$rj, i8), (EXT_W_B GPR:$rj)>;1498def : Pat<(sext_inreg GPR:$rj, i16), (EXT_W_H GPR:$rj)>;1499} // Predicates = [Has32S]1500 1501let Predicates = [IsLA64] in {1502def : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>;1503} // Predicates = [IsLA64]1504 1505/// Setcc1506 1507def : PatGprGpr<setlt, SLT>;1508def : PatGprImm<setlt, SLTI, simm12>;1509def : PatGprGpr<setult, SLTU>;1510def : PatGprImm<setult, SLTUI, simm12>;1511 1512// Define pattern expansions for setcc operations that aren't directly1513// handled by a LoongArch instruction.1514def : Pat<(seteq GPR:$rj, 0), (SLTUI GPR:$rj, 1)>;1515def : Pat<(seteq GPR:$rj, GPR:$rk), (SLTUI (XOR GPR:$rj, GPR:$rk), 1)>;1516let Predicates = [IsLA32] in {1517def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12),1518          (SLTUI (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>;1519} // Predicates = [IsLA32]1520let Predicates = [IsLA64] in {1521def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12),1522          (SLTUI (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>;1523} // Predicates = [IsLA64]1524def : Pat<(setne GPR:$rj, 0), (SLTU R0, GPR:$rj)>;1525def : Pat<(setne GPR:$rj, GPR:$rk), (SLTU R0, (XOR GPR:$rj, GPR:$rk))>;1526let Predicates = [IsLA32] in {1527def : Pat<(setne GPR:$rj, simm12_plus1:$imm12),1528          (SLTU R0, (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)))>;1529} // Predicates = [IsLA32]1530let Predicates = [IsLA64] in {1531def : Pat<(setne GPR:$rj, simm12_plus1:$imm12),1532          (SLTU R0, (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)))>;1533} // Predicates = [IsLA64]1534def : Pat<(setugt GPR:$rj, GPR:$rk), (SLTU GPR:$rk, GPR:$rj)>;1535def : Pat<(setuge GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rj, GPR:$rk), 1)>;1536def : Pat<(setule GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rk, GPR:$rj), 1)>;1537def : Pat<(setgt GPR:$rj, GPR:$rk), (SLT GPR:$rk, GPR:$rj)>;1538def : Pat<(setge GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rj, GPR:$rk), 1)>;1539def : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>;1540 1541/// Select1542 1543def IntCCtoBranchOpc : SDNodeXForm<loongarch_selectcc, [{1544  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();1545  unsigned BrCC = getBranchOpcForIntCC(CC);1546  return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getGRLenVT());1547}]>;1548 1549def loongarch_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc,1550                                           node:$truev, node:$falsev),1551                                      (loongarch_selectcc node:$lhs, node:$rhs,1552                                                          node:$cc, node:$truev,1553                                                          node:$falsev), [{}],1554                                      IntCCtoBranchOpc>;1555 1556multiclass SelectCC_GPR_rrirr<DAGOperand valty, ValueType vt> {1557  let usesCustomInserter = 1 in1558  def _Using_CC_GPR : Pseudo<(outs valty:$dst),1559                             (ins GPR:$lhs, GPR:$rhs, GPR:$cc,1560                              valty:$truev, valty:$falsev),1561                             [(set valty:$dst,1562                               (loongarch_selectcc_frag:$cc (GRLenVT GPR:$lhs), GPR:$rhs, cond,1563                                                            (vt valty:$truev), valty:$falsev))]>;1564  // Explicitly select 0 in the condition to R0. The register coalescer doesn't1565  // always do it.1566  def : Pat<(loongarch_selectcc_frag:$cc (GRLenVT GPR:$lhs), 0, cond, (vt valty:$truev),1567                                         valty:$falsev),1568            (!cast<Instruction>(NAME#"_Using_CC_GPR") GPR:$lhs, (GRLenVT R0),1569             (IntCCtoBranchOpc $cc), valty:$truev, valty:$falsev)>;1570}1571 1572defm Select_GPR : SelectCC_GPR_rrirr<GPR, GRLenVT>;1573 1574let Predicates = [Has32S] in {1575def : Pat<(select GPR:$cond, GPR:$t, 0), (MASKEQZ GPR:$t, GPR:$cond)>;1576def : Pat<(select GPR:$cond, 0, GPR:$f), (MASKNEZ GPR:$f, GPR:$cond)>;1577def : Pat<(select GPR:$cond, GPR:$t, GPR:$f),1578          (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>;1579} // Predicates = [Has32S]1580 1581/// Branches and jumps1582 1583let Predicates = [Has32S] in {1584class BccZeroPat<CondCode Cond, LAInst Inst>1585    : Pat<(loongarch_brcc (GRLenVT GPR:$rj), 0, Cond, bb:$imm21),1586           (Inst GPR:$rj, bb:$imm21)>;1587 1588def : BccZeroPat<SETEQ, BEQZ>;1589def : BccZeroPat<SETNE, BNEZ>;1590} // Predicates = [Has32S]1591 1592multiclass BccPat<CondCode Cond, LAInst Inst> {1593  def : Pat<(loongarch_brcc (GRLenVT GPR:$rj), GPR:$rd, Cond, bb:$imm16),1594            (Inst GPR:$rj, GPR:$rd, bb:$imm16)>;1595  // Explicitly select 0 to R0. The register coalescer doesn't always do it.1596  def : Pat<(loongarch_brcc (GRLenVT GPR:$rj), 0, Cond, bb:$imm16),1597            (Inst GPR:$rj, (GRLenVT R0), bb:$imm16)>;1598}1599 1600defm : BccPat<SETEQ, BEQ>;1601defm : BccPat<SETNE, BNE>;1602defm : BccPat<SETLT, BLT>;1603defm : BccPat<SETGE, BGE>;1604defm : BccPat<SETULT, BLTU>;1605defm : BccPat<SETUGE, BGEU>;1606 1607let isBarrier = 1, isBranch = 1, isTerminator = 1 in1608def PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>,1609               PseudoInstExpansion<(B simm26_b:$imm26)>;1610 1611let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in1612def PseudoBRIND : Pseudo<(outs), (ins GPRJR:$rj, simm16_lsl2:$imm16)>,1613                  PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>;1614 1615def : Pat<(brind GPRJR:$rj), (PseudoBRIND GPRJR:$rj, 0)>;1616def : Pat<(brind (add GPRJR:$rj, simm16_lsl2:$imm16)),1617          (PseudoBRIND GPRJR:$rj, simm16_lsl2:$imm16)>;1618 1619// Function call with 'Small' code model.1620let isCall = 1, Defs = [R1] in1621def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>;1622 1623def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;1624def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;1625 1626// Function call with 'Medium' code model.1627let isCall = 1, Defs = [R1, R20], Size = 8 in1628def PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>;1629 1630let Predicates = [IsLA64] in {1631def : Pat<(loongarch_call_medium tglobaladdr:$func),1632          (PseudoCALL_MEDIUM tglobaladdr:$func)>;1633def : Pat<(loongarch_call_medium texternalsym:$func),1634          (PseudoCALL_MEDIUM texternalsym:$func)>;1635} // Predicates = [IsLA64]1636 1637// Function call with 'Large' code model.1638let isCall = 1, Defs = [R1] in1639def PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>;1640 1641let Predicates = [IsLA64] in {1642def : Pat<(loongarch_call_large tglobaladdr:$func),1643          (PseudoCALL_LARGE tglobaladdr:$func)>;1644def : Pat<(loongarch_call_large texternalsym:$func),1645          (PseudoCALL_LARGE texternalsym:$func)>;1646} // Predicates = [IsLA64]1647 1648let isCall = 1, Defs = [R1] in1649def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj),1650                                [(loongarch_call GPR:$rj)]>,1651                         PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>;1652let Predicates = [IsLA64] in {1653def : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;1654def : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;1655}1656 1657let isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in1658def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,1659                      PseudoInstExpansion<(JIRL R1, GPR:$rj,1660                                           simm16_lsl2:$imm16)>;1661 1662let isBarrier = 1, isReturn = 1, isTerminator = 1 in1663def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,1664                PseudoInstExpansion<(JIRL R0, R1, 0)>;1665 1666// Tail call with 'Small' code model.1667let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in1668def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>;1669 1670def : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)),1671          (PseudoTAIL tglobaladdr:$dst)>;1672def : Pat<(loongarch_tail (iPTR texternalsym:$dst)),1673          (PseudoTAIL texternalsym:$dst)>;1674 1675// Tail call with 'Medium' code model.1676let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,1677    Uses = [R3], Defs = [R20], Size = 8 in1678def PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>;1679 1680let Predicates = [IsLA64] in {1681def : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)),1682          (PseudoTAIL_MEDIUM tglobaladdr:$dst)>;1683def : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)),1684          (PseudoTAIL_MEDIUM texternalsym:$dst)>;1685} // Predicates = [IsLA64]1686 1687// Tail call with 'Large' code model.1688let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in1689def PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>;1690 1691let Predicates = [IsLA64] in {1692def : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)),1693          (PseudoTAIL_LARGE tglobaladdr:$dst)>;1694def : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)),1695          (PseudoTAIL_LARGE texternalsym:$dst)>;1696} // Predicates = [IsLA64]1697 1698let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in1699def PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj),1700                                [(loongarch_tail GPRT:$rj)]>,1701                         PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>;1702let Predicates = [IsLA64] in {1703def : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;1704def : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;1705}1706 1707let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,1708    hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in1709def PseudoB_TAIL : Pseudo<(outs), (ins simm26_b:$imm26)>,1710                   PseudoInstExpansion<(B simm26_b:$imm26)>;1711 1712let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,1713    hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in1714def PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,1715                      PseudoInstExpansion<(JIRL R0, GPR:$rj,1716                                           simm16_lsl2:$imm16)>;1717 1718/// call36/taill36 macro instructions1719let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1,1720    Defs = [R1], hasSideEffects = 0, mayStore = 0, mayLoad = 0 in1721def PseudoCALL36 : Pseudo<(outs), (ins bare_symbol:$dst), [],1722                          "call36", "$dst">,1723                   Requires<[IsLA64]>;1724let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3],1725    isCodeGenOnly = 0, isAsmParserOnly = 1, hasSideEffects = 0,1726    mayStore = 0, mayLoad = 0 in1727def PseudoTAIL36 : Pseudo<(outs), (ins GPR:$tmp, bare_symbol:$dst), [],1728                          "tail36", "$tmp, $dst">,1729                   Requires<[IsLA64]>;1730 1731// This is a special case of the ADD_W/D instruction used to facilitate the use1732// of a fourth operand to emit a relocation on a symbol relating to this1733// instruction. The relocation does not affect any bits of the instruction itself1734// but is used as a hint to the linker.1735let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in {1736def PseudoAddTPRel_W : Pseudo<(outs GPR:$rd),1737                              (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [],1738                              "add.w", "$rd, $rj, $rk, $sym">,1739                              Requires<[IsLA32]>;1740def PseudoAddTPRel_D : Pseudo<(outs GPR:$rd),1741                              (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [],1742                              "add.d", "$rd, $rj, $rk, $sym">,1743                              Requires<[IsLA64]>;1744}1745 1746/// Load address (la*) macro instructions.1747 1748// Define isCodeGenOnly = 0 to expose them to tablegened assembly parser.1749let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,1750    isAsmParserOnly = 1 in {1751def PseudoLA_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1752                          "la.abs", "$dst, $src">;1753def PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst),1754                                (ins GPR:$tmp, bare_symbol:$src), [],1755                                "la.abs", "$dst, $src">;1756def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1757                            "la.pcrel", "$dst, $src">;1758def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1759                             "la.tls.ld", "$dst, $src">;1760def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1761                             "la.tls.gd", "$dst, $src">;1762def PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst),1763                                  (ins GPR:$tmp, bare_symbol:$src), [],1764                                  "la.pcrel", "$dst, $tmp, $src">,1765                           Requires<[IsLA64]>;1766def PseudoLA_TLS_LE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1767                             "la.tls.le", "$dst, $src">;1768def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),1769                                   (ins GPR:$tmp, bare_symbol:$src), [],1770                                   "la.tls.ld", "$dst, $tmp, $src">,1771                            Requires<[IsLA64]>;1772def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),1773                                   (ins GPR:$tmp, bare_symbol:$src), [],1774                                   "la.tls.gd", "$dst, $tmp, $src">,1775                            Requires<[IsLA64]>;1776}1777let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,1778    isAsmParserOnly = 1 in {1779def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1780                          "la.got", "$dst, $src">;1781def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1782                             "la.tls.ie", "$dst, $src">;1783def PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst),1784                                (ins GPR:$tmp, bare_symbol:$src), [],1785                                "la.got", "$dst, $tmp, $src">,1786                         Requires<[IsLA64]>;1787def PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst),1788                                   (ins GPR:$tmp, bare_symbol:$src), [],1789                                   "la.tls.ie", "$dst, $tmp, $src">,1790                            Requires<[IsLA64]>;1791}1792 1793// Used for expand PseudoLA_TLS_DESC_* instructions.1794let isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0,1795    Defs = [R4], Uses = [R4] in1796def PseudoDESC_CALL : Pseudo<(outs GPR:$rd), (ins GPR:$rj, simm16_lsl2:$imm16)>,1797                      PseudoInstExpansion<(JIRL GPR:$rd, GPR:$rj,1798                                           simm16_lsl2:$imm16)>;1799// TLSDESC1800let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,1801    isAsmParserOnly = 1, Defs = [R1] in1802def PseudoLA_TLS_DESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1803                               "la.tls.desc", "$dst, $src">;1804let isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0,1805    isCodeGenOnly = 0, isAsmParserOnly = 1, Defs = [R1, R4] in1806def PseudoLA_TLS_DESC_LARGE : Pseudo<(outs GPR:$dst),1807                                     (ins GPR:$tmp, bare_symbol:$src), [],1808                                     "la.tls.desc", "$dst, $tmp, $src">,1809                              Requires<[IsLA64]>;1810 1811// Load address inst alias: "la", "la.global" and "la.local".1812// Default:1813//     la = la.global = la.got1814//     la.local = la.pcrel1815// With feature "+la-global-with-pcrel":1816//     la = la.global = la.pcrel1817// With feature "+la-global-with-abs":1818//     la = la.global = la.abs1819// With feature "+la-local-with-abs":1820//     la.local = la.abs1821// With features "+la-global-with-pcrel,+la-global-with-abs"(disorder):1822//     la = la.global = la.pcrel1823// Note: To keep consistent with gnu-as behavior, the "la" can only have one1824//       register operand.1825def : InstAlias<"la $dst, $src", (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>;1826def : InstAlias<"la.global $dst, $src",1827                (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>;1828def : InstAlias<"la.global $dst, $tmp, $src",1829                (PseudoLA_GOT_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;1830def : InstAlias<"la.local $dst, $src",1831                (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;1832def : InstAlias<"la.local $dst, $tmp, $src",1833                (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;1834 1835// Note: Keep HasLaGlobalWithPcrel before HasLaGlobalWithAbs to ensure1836// "la-global-with-pcrel" takes effect when bose "la-global-with-pcrel" and1837// "la-global-with-abs" are enabled.1838let Predicates = [HasLaGlobalWithPcrel] in {1839def : InstAlias<"la $dst, $src", (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;1840def : InstAlias<"la.global $dst, $src",1841                (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;1842def : InstAlias<"la.global $dst, $tmp, $src",1843                (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;1844} // Predicates = [HasLaGlobalWithPcrel]1845 1846let Predicates = [HasLaGlobalWithAbs] in {1847def : InstAlias<"la $dst, $src", (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;1848def : InstAlias<"la.global $dst, $src",1849                (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;1850def : InstAlias<"la.global $dst, $tmp, $src",1851                (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;1852} // Predicates = [HasLaGlobalWithAbs]1853 1854let Predicates = [HasLaLocalWithAbs] in {1855def : InstAlias<"la.local $dst, $src",1856                (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;1857def : InstAlias<"la.local $dst, $tmp, $src",1858                (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;1859} // Predicates = [HasLaLocalWithAbs]1860 1861/// BSTRINS and BSTRPICK1862 1863let Predicates = [IsLA32, Has32S] in {1864def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd),1865          (BSTRINS_W GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>;1866def : Pat<(loongarch_bstrpick GPR:$rj, uimm5:$msbd, uimm5:$lsbd),1867          (BSTRPICK_W GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>;1868} // Predicates = [IsLA32, Has32S]1869 1870let Predicates = [IsLA64] in {1871def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd),1872          (BSTRINS_D GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>;1873def : Pat<(loongarch_bstrpick GPR:$rj, uimm6:$msbd, uimm6:$lsbd),1874          (BSTRPICK_D GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>;1875} // Predicates = [IsLA64]1876 1877/// Byte-swapping and bit-reversal1878 1879def : Pat<(loongarch_revb_2h GPR:$rj), (REVB_2H GPR:$rj)>;1880def : Pat<(loongarch_bitrev_4b GPR:$rj), (BITREV_4B GPR:$rj)>;1881 1882let Predicates = [IsLA32, Has32S] in {1883def : Pat<(bswap GPR:$rj), (ROTRI_W (REVB_2H GPR:$rj), 16)>;1884def : Pat<(bitreverse GPR:$rj), (BITREV_W GPR:$rj)>;1885def : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_4B GPR:$rj)>;1886def : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_4B GPR:$rj)>;1887} // Predicates = [IsLA32, Has32S]1888 1889let Predicates = [IsLA64] in {1890def : Pat<(loongarch_revb_2w GPR:$rj), (REVB_2W GPR:$rj)>;1891def : Pat<(bswap GPR:$rj), (REVB_D GPR:$rj)>;1892def : Pat<(loongarch_bitrev_8b GPR:$rj), (BITREV_8B GPR:$rj)>;1893def : Pat<(loongarch_bitrev_w GPR:$rj), (BITREV_W GPR:$rj)>;1894def : Pat<(bitreverse GPR:$rj), (BITREV_D GPR:$rj)>;1895def : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_8B GPR:$rj)>;1896def : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_8B GPR:$rj)>;1897} // Predicates = [IsLA64]1898 1899/// Loads1900 1901multiclass LdPat<PatFrags LoadOp, LAInst Inst, ValueType vt = GRLenVT> {1902  def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>;1903  def : Pat<(vt (LoadOp (AddrConstant GPR:$rj, simm12:$imm12))),1904            (Inst GPR:$rj, simm12:$imm12)>;1905  def : Pat<(vt (LoadOp (AddLike BaseAddr:$rj, simm12:$imm12))),1906            (Inst BaseAddr:$rj, simm12:$imm12)>;1907}1908 1909defm : LdPat<sextloadi8, LD_B>;1910defm : LdPat<extloadi8, LD_B>;1911defm : LdPat<sextloadi16, LD_H>;1912defm : LdPat<extloadi16, LD_H>;1913defm : LdPat<load, LD_W>, Requires<[IsLA32]>;1914defm : LdPat<zextloadi8, LD_BU>;1915defm : LdPat<zextloadi16, LD_HU>;1916let Predicates = [IsLA64] in {1917defm : LdPat<sextloadi32, LD_W, i64>;1918defm : LdPat<extloadi32, LD_W, i64>;1919defm : LdPat<zextloadi32, LD_WU, i64>;1920defm : LdPat<load, LD_D, i64>;1921} // Predicates = [IsLA64]1922 1923// LA64 register-register-addressed loads1924let Predicates = [IsLA64] in {1925class RegRegLdPat<PatFrag LoadOp, LAInst Inst, ValueType vt>1926  : Pat<(vt (LoadOp (add NonFIBaseAddr:$rj, GPR:$rk))),1927        (Inst NonFIBaseAddr:$rj, GPR:$rk)>;1928 1929def : RegRegLdPat<extloadi8, LDX_B, i64>;1930def : RegRegLdPat<sextloadi8, LDX_B, i64>;1931def : RegRegLdPat<zextloadi8, LDX_BU, i64>;1932def : RegRegLdPat<extloadi16, LDX_H, i64>;1933def : RegRegLdPat<sextloadi16, LDX_H, i64>;1934def : RegRegLdPat<zextloadi16, LDX_HU, i64>;1935def : RegRegLdPat<extloadi32, LDX_W, i64>;1936def : RegRegLdPat<sextloadi32, LDX_W, i64>;1937def : RegRegLdPat<zextloadi32, LDX_WU, i64>;1938def : RegRegLdPat<load, LDX_D, i64>;1939} // Predicates = [IsLA64]1940 1941/// Stores1942 1943multiclass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,1944                 ValueType vt> {1945  def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj),1946            (Inst StTy:$rd, BaseAddr:$rj, 0)>;1947  def : Pat<(StoreOp (vt StTy:$rs2), (AddrConstant GPR:$rj, simm12:$imm12)),1948            (Inst StTy:$rs2, GPR:$rj, simm12:$imm12)>;1949  def : Pat<(StoreOp (vt StTy:$rd), (AddLike BaseAddr:$rj, simm12:$imm12)),1950            (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>;1951}1952 1953defm : StPat<truncstorei8, ST_B, GPR, GRLenVT>;1954defm : StPat<truncstorei16, ST_H, GPR, GRLenVT>;1955defm : StPat<store, ST_W, GPR, i32>, Requires<[IsLA32]>;1956let Predicates = [IsLA64] in {1957defm : StPat<truncstorei32, ST_W, GPR, i64>;1958defm : StPat<store, ST_D, GPR, i64>;1959} // Predicates = [IsLA64]1960 1961let Predicates = [IsLA64] in {1962def : Pat<(i64 (sextloadi32 (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))),1963          (LDPTR_W BaseAddr:$rj, simm14_lsl2:$imm14)>;1964def : Pat<(i64 (load (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))),1965          (LDPTR_D BaseAddr:$rj, simm14_lsl2:$imm14)>;1966def : Pat<(truncstorei32 (i64 GPR:$rd),1967                         (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)),1968          (STPTR_W GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>;1969def : Pat<(store (i64 GPR:$rd), (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)),1970          (STPTR_D GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>;1971} // Predicates = [IsLA64]1972 1973// LA64 register-register-addressed stores1974let Predicates = [IsLA64] in {1975class RegRegStPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,1976                  ValueType vt>1977  : Pat<(StoreOp (vt StTy:$rd), (add NonFIBaseAddr:$rj, GPR:$rk)),1978        (Inst StTy:$rd, NonFIBaseAddr:$rj, GPR:$rk)>;1979 1980def : RegRegStPat<truncstorei8, STX_B, GPR, i64>;1981def : RegRegStPat<truncstorei16, STX_H, GPR, i64>;1982def : RegRegStPat<truncstorei32, STX_W, GPR, i64>;1983def : RegRegStPat<store, STX_D, GPR, i64>;1984} // Predicates = [IsLA64]1985 1986/// Atomic loads and stores1987 1988// DBAR hint encoding for LA664 and later micro-architectures, paraphrased from1989// the Linux patch revealing it [1]:1990//1991// - Bit 4: kind of constraint (0: completion, 1: ordering)1992// - Bit 3: barrier for previous read (0: true, 1: false)1993// - Bit 2: barrier for previous write (0: true, 1: false)1994// - Bit 1: barrier for succeeding read (0: true, 1: false)1995// - Bit 0: barrier for succeeding write (0: true, 1: false)1996//1997// Hint 0x700: barrier for "read after read" from the same address, which is1998// e.g. needed by LL-SC loops on older models. (DBAR 0x700 behaves the same as1999// nop if such reordering is disabled on supporting newer models.)2000//2001// [1]: https://lore.kernel.org/loongarch/20230516124536.535343-1-chenhuacai@loongson.cn/2002//2003// Implementations without support for the finer-granularity hints simply treat2004// all as the full barrier (DBAR 0), so we can unconditionally start emiting the2005// more precise hints right away.2006 2007def : Pat<(atomic_fence 4, timm), (DBAR 0b10100)>; // acquire2008def : Pat<(atomic_fence 5, timm), (DBAR 0b10010)>; // release2009def : Pat<(atomic_fence 6, timm), (DBAR 0b10000)>; // acqrel2010def : Pat<(atomic_fence 7, timm), (DBAR 0b10000)>; // seqcst2011 2012defm : LdPat<atomic_load_asext_8, LD_B>;2013defm : LdPat<atomic_load_asext_16, LD_H>;2014defm : LdPat<atomic_load_nonext_32, LD_W>, Requires<[IsLA32]>;2015defm : LdPat<atomic_load_asext_32, LD_W>, Requires<[IsLA64]>;2016 2017class release_seqcst_store<PatFrag base>2018    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{2019  AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();2020  return isReleaseOrStronger(Ordering);2021}]>;2022 2023class unordered_monotonic_store<PatFrag base>2024    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{2025  AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();2026  return !isReleaseOrStronger(Ordering);2027}]>;2028 2029def atomic_store_release_seqcst_32 : release_seqcst_store<atomic_store_32>;2030def atomic_store_release_seqcst_64 : release_seqcst_store<atomic_store_64>;2031def atomic_store_unordered_monotonic_322032    : unordered_monotonic_store<atomic_store_32>;2033def atomic_store_unordered_monotonic_642034    : unordered_monotonic_store<atomic_store_64>;2035 2036defm : StPat<atomic_store_8, ST_B, GPR, GRLenVT>;2037defm : StPat<atomic_store_16, ST_H, GPR, GRLenVT>;2038defm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i32>,2039                   Requires<[IsLA32]>;2040 2041def PseudoAtomicStoreW2042  : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>,2043           PseudoInstExpansion<(AMSWAP__DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>;2044 2045def : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk),2046          (PseudoAtomicStoreW GPR:$rj, GPR:$rk)>;2047 2048let Predicates = [IsLA64] in {2049def PseudoAtomicStoreD2050  : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>,2051           PseudoInstExpansion<(AMSWAP__DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>;2052 2053def : Pat<(atomic_store_release_seqcst_64 GPR:$rj, GPR:$rk),2054          (PseudoAtomicStoreD GPR:$rj, GPR:$rk)>;2055 2056defm : LdPat<atomic_load_nonext_64, LD_D>;2057defm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i64>;2058defm : StPat<atomic_store_unordered_monotonic_64, ST_D, GPR, i64>;2059} // Predicates = [IsLA64]2060 2061/// Atomic Ops2062 2063class PseudoMaskedAM2064    : Pseudo<(outs GPR:$res, GPR:$scratch),2065             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> {2066  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";2067  let mayLoad = 1;2068  let mayStore = 1;2069  let hasSideEffects = 0;2070  let Size = 36;2071}2072 2073def PseudoMaskedAtomicSwap32 : PseudoMaskedAM;2074def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAM;2075def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAM;2076def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAM;2077 2078class PseudoAM : Pseudo<(outs GPR:$res, GPR:$scratch),2079                        (ins GPR:$addr, GPR:$incr, grlenimm:$ordering)> {2080  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";2081  let mayLoad = 1;2082  let mayStore = 1;2083  let hasSideEffects = 0;2084  let Size = 24;2085}2086 2087def PseudoAtomicSwap32 : PseudoAM;2088def PseudoAtomicLoadNand32 : PseudoAM;2089def PseudoAtomicLoadNand64 : PseudoAM;2090def PseudoAtomicLoadAdd32 : PseudoAM;2091def PseudoAtomicLoadSub32 : PseudoAM;2092def PseudoAtomicLoadAnd32 : PseudoAM;2093def PseudoAtomicLoadOr32 : PseudoAM;2094def PseudoAtomicLoadXor32 : PseudoAM;2095def PseudoAtomicLoadUMax32 : PseudoAM;2096def PseudoAtomicLoadUMin32 : PseudoAM;2097def PseudoAtomicLoadMax32 : PseudoAM;2098def PseudoAtomicLoadMin32 : PseudoAM;2099 2100multiclass PseudoBinPat<string Op, Pseudo BinInst> {2101  def : Pat<(!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$incr),2102            (BinInst GPR:$addr, GPR:$incr, 2)>;2103  def : Pat<(!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$incr),2104            (BinInst GPR:$addr, GPR:$incr, 4)>;2105  def : Pat<(!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$incr),2106            (BinInst GPR:$addr, GPR:$incr, 5)>;2107  def : Pat<(!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$incr),2108            (BinInst GPR:$addr, GPR:$incr, 6)>;2109  def : Pat<(!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$incr),2110            (BinInst GPR:$addr, GPR:$incr, 7)>;2111}2112 2113class PseudoMaskedAMUMinUMax2114    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),2115             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> {2116  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"2117                    "@earlyclobber $scratch2";2118  let mayLoad = 1;2119  let mayStore = 1;2120  let hasSideEffects = 0;2121  let Size = 48;2122}2123 2124def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMUMinUMax;2125def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMUMinUMax;2126 2127class PseudoMaskedAMMinMax2128    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),2129             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$sextshamt,2130              grlenimm:$ordering)> {2131  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"2132                    "@earlyclobber $scratch2";2133  let mayLoad = 1;2134  let mayStore = 1;2135  let hasSideEffects = 0;2136  let Size = 56;2137}2138 2139def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMMinMax;2140def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax;2141 2142// Data prefetch2143 2144// TODO: Supports for preldx instruction.2145def : Pat<(prefetch (AddrRegImm GPR:$rj, simm12:$imm12), (i32 0), timm, (i32 1)),2146          (PRELD 0, GPR:$rj, simm12:$imm12)>; // data prefetch for loads2147def : Pat<(prefetch (AddrRegImm GPR:$rj, simm12:$imm12), (i32 1), timm, (i32 1)),2148          (PRELD 8, GPR:$rj, simm12:$imm12)>; // data prefetch for stores2149 2150/// Compare and exchange2151 2152class PseudoCmpXchg2153    : Pseudo<(outs GPR:$res, GPR:$scratch),2154             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order)> {2155  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";2156  let mayLoad = 1;2157  let mayStore = 1;2158  let hasSideEffects = 0;2159  let Size = 36;2160}2161 2162def PseudoCmpXchg32 : PseudoCmpXchg;2163def PseudoCmpXchg64 : PseudoCmpXchg;2164 2165class PseudoCmpXchg128Pat 2166    : Pseudo<(outs GPR:$res_lo, GPR:$res_hi, GPR:$scratch),2167             (ins GPR:$addr, GPR:$cmpval_lo, GPR:$cmpval_hi, 2168                  GPR:$newval_lo, GPR:$newval_hi)> {2169  let Constraints = "@earlyclobber $res_lo,@earlyclobber $res_hi,@earlyclobber $scratch";2170  let mayLoad = 1;2171  let mayStore = 1;2172  let hasSideEffects = 0;2173  let Size = 36;2174}2175 2176def PseudoCmpXchg128 : PseudoCmpXchg128Pat;2177def PseudoCmpXchg128Acquire : PseudoCmpXchg128Pat;2178 2179def PseudoMaskedCmpXchg322180    : Pseudo<(outs GPR:$res, GPR:$scratch),2181             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,2182              grlenimm:$fail_order)> {2183  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";2184  let mayLoad = 1;2185  let mayStore = 1;2186  let hasSideEffects = 0;2187  let Size = 44;2188}2189 2190class PseudoMaskedAMMinMaxPat<Intrinsic intrin, Pseudo AMInst>2191    : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,2192           timm:$ordering),2193          (AMInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,2194           timm:$ordering)>;2195 2196class AtomicPat<Intrinsic intrin, Pseudo AMInst>2197    : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),2198          (AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;2199 2200// These atomic cmpxchg PatFrags only care about the failure ordering.2201// The PatFrags defined by multiclass `ternary_atomic_op_ord` in2202// TargetSelectionDAG.td care about the merged memory ordering that is the2203// stronger one between success and failure. But for LoongArch LL-SC we only2204// need to care about the failure ordering as explained in PR #67391. So we2205// define these PatFrags that will be used to define cmpxchg pats below.2206multiclass ternary_atomic_op_failure_ord {2207  def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),2208      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{2209    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();2210    return Ordering == AtomicOrdering::Monotonic;2211  }]>;2212  def NAME#_failure_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),2213      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{2214    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();2215    return Ordering == AtomicOrdering::Acquire;2216  }]>;2217  def NAME#_failure_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),2218      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{2219    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();2220    return Ordering == AtomicOrdering::Release;2221  }]>;2222  def NAME#_failure_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),2223      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{2224    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();2225    return Ordering == AtomicOrdering::AcquireRelease;2226  }]>;2227  def NAME#_failure_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),2228      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{2229    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();2230    return Ordering == AtomicOrdering::SequentiallyConsistent;2231  }]>;2232}2233 2234defm atomic_cmp_swap_i32 : ternary_atomic_op_failure_ord;2235defm atomic_cmp_swap_i64 : ternary_atomic_op_failure_ord;2236 2237// Atomic operation for word and double word2238multiclass binary_atomic_op_wd<string inst, string op, string signed = ""> {2239  def : Pat<(!cast<PatFrag>(op#"_i32_monotonic") GPR:$rj, GPR:$rk),2240            (!cast<Instruction>(inst#"_W"#signed) GPR:$rk, GPR:$rj)>;2241  def : Pat<(!cast<PatFrag>(op#"_i64_monotonic") GPR:$rj, GPR:$rk),2242            (!cast<Instruction>(inst#"_D"#signed) GPR:$rk, GPR:$rj)>;2243 2244  def : Pat<(!cast<PatFrag>(op#"_i32") GPR:$rj, GPR:$rk),2245            (!cast<Instruction>(inst#"__DB_W"#signed) GPR:$rk, GPR:$rj)>;2246  def : Pat<(!cast<PatFrag>(op#"_i64") GPR:$rj, GPR:$rk),2247            (!cast<Instruction>(inst#"__DB_D"#signed) GPR:$rk, GPR:$rj)>;2248}2249 2250// Atomic operation for byte and half word2251multiclass binary_atomic_op_bh<string inst, string op> {2252  def : Pat<(!cast<PatFrag>(op#"_i8_monotonic") GPR:$rj, GPR:$rk),2253            (!cast<Instruction>(inst#"_B") GPR:$rk, GPR:$rj)>;2254  def : Pat<(!cast<PatFrag>(op#"_i16_monotonic") GPR:$rj, GPR:$rk),2255            (!cast<Instruction>(inst#"_H") GPR:$rk, GPR:$rj)>;2256 2257  def : Pat<(!cast<PatFrag>(op#"_i8") GPR:$rj, GPR:$rk),2258            (!cast<Instruction>(inst#"__DB_B") GPR:$rk, GPR:$rj)>;2259  def : Pat<(!cast<PatFrag>(op#"_i16") GPR:$rj, GPR:$rk),2260            (!cast<Instruction>(inst#"__DB_H") GPR:$rk, GPR:$rj)>;2261}2262 2263let Predicates = [ HasLAM_BH, IsLA64 ] in {2264defm : binary_atomic_op_bh<"AMSWAP", "atomic_swap">;2265defm : binary_atomic_op_bh<"AMADD", "atomic_load_add">;2266def : Pat<(atomic_load_sub_i8_monotonic GPR:$rj, GPR:$rk),2267          (AMADD_B (SUB_W R0, GPR:$rk), GPR:$rj)>;2268def : Pat<(atomic_load_sub_i16_monotonic GPR:$rj, GPR:$rk),2269          (AMADD_H (SUB_W R0, GPR:$rk), GPR:$rj)>;2270 2271def : Pat<(atomic_load_sub_i8 GPR:$rj, GPR:$rk),2272          (AMADD__DB_B (SUB_W R0, GPR:$rk), GPR:$rj)>;2273def : Pat<(atomic_load_sub_i16 GPR:$rj, GPR:$rk),2274          (AMADD__DB_H (SUB_W R0, GPR:$rk), GPR:$rj)>;2275} // Predicates = [ IsLA64, HasLAM_BH ]2276 2277let Predicates = [ HasLAMCAS, IsLA64 ] in {2278def : Pat<(atomic_cmp_swap_i8_monotonic GPR:$addr, GPR:$cmp, GPR:$new),2279          (AMCAS_B GPR:$cmp, GPR:$new, GPR:$addr)>;2280def : Pat<(atomic_cmp_swap_i16_monotonic GPR:$addr, GPR:$cmp, GPR:$new),2281          (AMCAS_H GPR:$cmp, GPR:$new, GPR:$addr)>;2282def : Pat<(atomic_cmp_swap_i32_monotonic GPR:$addr, GPR:$cmp, GPR:$new),2283          (AMCAS_W GPR:$cmp, GPR:$new, GPR:$addr)>;2284def : Pat<(atomic_cmp_swap_i64_monotonic GPR:$addr, GPR:$cmp, GPR:$new),2285          (AMCAS_D GPR:$cmp, GPR:$new, GPR:$addr)>;2286 2287def : Pat<(atomic_cmp_swap_i8 GPR:$addr, GPR:$cmp, GPR:$new),2288          (AMCAS__DB_B GPR:$cmp, GPR:$new, GPR:$addr)>;2289def : Pat<(atomic_cmp_swap_i16 GPR:$addr, GPR:$cmp, GPR:$new),2290          (AMCAS__DB_H GPR:$cmp, GPR:$new, GPR:$addr)>;2291def : Pat<(atomic_cmp_swap_i32 GPR:$addr, GPR:$cmp, GPR:$new),2292          (AMCAS__DB_W GPR:$cmp, GPR:$new, GPR:$addr)>;2293def : Pat<(atomic_cmp_swap_i64 GPR:$addr, GPR:$cmp, GPR:$new),2294          (AMCAS__DB_D GPR:$cmp, GPR:$new, GPR:$addr)>;2295}2296 2297// Ordering constants must be kept in sync with the AtomicOrdering enum in2298// AtomicOrdering.h.2299multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,2300                            ValueType vt = GRLenVT> {2301  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)),2302            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;2303  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acquire") GPR:$addr, GPR:$cmp, GPR:$new)),2304            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;2305  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_release") GPR:$addr, GPR:$cmp, GPR:$new)),2306            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;2307  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)),2308            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;2309  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)),2310            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;2311}2312 2313let Predicates = [IsLA64] in {2314defm : binary_atomic_op_wd<"AMSWAP", "atomic_swap">;2315defm : binary_atomic_op_wd<"AMADD", "atomic_load_add">;2316defm : binary_atomic_op_wd<"AMAND", "atomic_load_and">;2317defm : binary_atomic_op_wd<"AMOR", "atomic_load_or">;2318defm : binary_atomic_op_wd<"AMXOR", "atomic_load_xor">;2319defm : binary_atomic_op_wd<"AMMIN", "atomic_load_umin", "U">;2320defm : binary_atomic_op_wd<"AMMAX", "atomic_load_umax", "U">;2321defm : binary_atomic_op_wd<"AMMIN", "atomic_load_min">;2322defm : binary_atomic_op_wd<"AMMAX", "atomic_load_max">;2323def : Pat<(atomic_load_sub_i32_monotonic GPR:$rj, GPR:$rk),2324          (AMADD_W (SUB_W R0, GPR:$rk), GPR:$rj)>;2325def : Pat<(atomic_load_sub_i64_monotonic GPR:$rj, GPR:$rk),2326          (AMADD_D (SUB_D R0, GPR:$rk), GPR:$rj)>;2327 2328def : Pat<(atomic_load_sub_i32 GPR:$rj, GPR:$rk),2329          (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>;2330def : Pat<(atomic_load_sub_i64 GPR:$rj, GPR:$rk),2331          (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>;2332 2333def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,2334                PseudoMaskedAtomicSwap32>;2335def : AtomicPat<int_loongarch_masked_atomicrmw_add_i64,2336                PseudoMaskedAtomicLoadAdd32>;2337def : AtomicPat<int_loongarch_masked_atomicrmw_sub_i64,2338                PseudoMaskedAtomicLoadSub32>;2339defm : PseudoBinPat<"atomic_load_nand_i64", PseudoAtomicLoadNand64>;2340def : AtomicPat<int_loongarch_masked_atomicrmw_nand_i64,2341                PseudoMaskedAtomicLoadNand32>;2342 2343def : AtomicPat<int_loongarch_masked_atomicrmw_umax_i64,2344                PseudoMaskedAtomicLoadUMax32>;2345def : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64,2346                PseudoMaskedAtomicLoadUMin32>;2347 2348defm : PseudoCmpXchgPat<"atomic_cmp_swap_i64", PseudoCmpXchg64, i64>;2349def : Pat<(int_loongarch_masked_cmpxchg_i642350            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order),2351          (PseudoMaskedCmpXchg322352            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order)>;2353 2354def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64,2355                              PseudoMaskedAtomicLoadMax32>;2356def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_min_i64,2357                              PseudoMaskedAtomicLoadMin32>;2358} // Predicates = [IsLA64]2359 2360defm : PseudoCmpXchgPat<"atomic_cmp_swap_i32", PseudoCmpXchg32>;2361defm : PseudoBinPat<"atomic_load_nand_i32", PseudoAtomicLoadNand32>;2362 2363let Predicates = [IsLA32] in {2364def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i32,2365                PseudoMaskedAtomicSwap32>;2366defm : PseudoBinPat<"atomic_swap_i32", PseudoAtomicSwap32>;2367def : AtomicPat<int_loongarch_masked_atomicrmw_add_i32,2368                PseudoMaskedAtomicLoadAdd32>;2369def : AtomicPat<int_loongarch_masked_atomicrmw_sub_i32,2370                PseudoMaskedAtomicLoadSub32>;2371def : AtomicPat<int_loongarch_masked_atomicrmw_nand_i32,2372                PseudoMaskedAtomicLoadNand32>;2373def : AtomicPat<int_loongarch_masked_atomicrmw_umax_i32,2374                PseudoMaskedAtomicLoadUMax32>;2375def : AtomicPat<int_loongarch_masked_atomicrmw_umin_i32,2376                PseudoMaskedAtomicLoadUMin32>;2377 2378def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i32,2379                              PseudoMaskedAtomicLoadMax32>;2380def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_min_i32,2381                              PseudoMaskedAtomicLoadMin32>;2382 2383def : Pat<(int_loongarch_masked_cmpxchg_i322384            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order),2385          (PseudoMaskedCmpXchg322386            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order)>;2387 2388defm : PseudoBinPat<"atomic_load_add_i32", PseudoAtomicLoadAdd32>;2389defm : PseudoBinPat<"atomic_load_sub_i32", PseudoAtomicLoadSub32>;2390defm : PseudoBinPat<"atomic_load_and_i32", PseudoAtomicLoadAnd32>;2391defm : PseudoBinPat<"atomic_load_or_i32", PseudoAtomicLoadOr32>;2392defm : PseudoBinPat<"atomic_load_xor_i32", PseudoAtomicLoadXor32>;2393defm : PseudoBinPat<"atomic_load_umax_i32", PseudoAtomicLoadUMax32>;2394defm : PseudoBinPat<"atomic_load_umin_i32", PseudoAtomicLoadUMin32>;2395defm : PseudoBinPat<"atomic_load_max_i32", PseudoAtomicLoadMax32>;2396defm : PseudoBinPat<"atomic_load_min_i32", PseudoAtomicLoadMin32>;2397} // Predicates = [IsLA32]2398 2399/// Intrinsics2400 2401def : Pat<(int_loongarch_cacop_d timm:$op, i64:$rj, timm:$imm12),2402          (CACOP timm:$op, GPR:$rj, timm:$imm12)>;2403def : Pat<(int_loongarch_cacop_w i32:$op, i32:$rj, i32:$imm12),2404          (CACOP timm:$op, GPR:$rj, timm:$imm12)>;2405def : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;2406def : Pat<(loongarch_ibar uimm15:$imm15), (IBAR uimm15:$imm15)>;2407def : Pat<(loongarch_break uimm15:$imm15), (BREAK uimm15:$imm15)>;2408def : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>;2409 2410let Predicates = [IsLA64] in {2411// CRC Check Instructions2412def : PatGprGpr<loongarch_crc_w_b_w, CRC_W_B_W>;2413def : PatGprGpr<loongarch_crc_w_h_w, CRC_W_H_W>;2414def : PatGprGpr<loongarch_crc_w_w_w, CRC_W_W_W>;2415def : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>;2416def : PatGprGpr<loongarch_crcc_w_b_w, CRCC_W_B_W>;2417def : PatGprGpr<loongarch_crcc_w_h_w, CRCC_W_H_W>;2418def : PatGprGpr<loongarch_crcc_w_w_w, CRCC_W_W_W>;2419def : PatGprGpr<loongarch_crcc_w_d_w, CRCC_W_D_W>;2420} // Predicates = [IsLA64]2421 2422/// Other pseudo-instructions2423 2424// Pessimistically assume the stack pointer will be clobbered2425let Defs = [R3], Uses = [R3] in {2426def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),2427                              [(callseq_start timm:$amt1, timm:$amt2)]>;2428def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),2429                              [(callseq_end timm:$amt1, timm:$amt2)]>;2430} // Defs = [R3], Uses = [R3]2431 2432//===----------------------------------------------------------------------===//2433// Assembler Pseudo Instructions2434//===----------------------------------------------------------------------===//2435 2436def : InstAlias<"nop", (ANDI R0, R0, 0)>;2437def : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>;2438// `ret` is supported since binutils commit 20f2e2686c79a5ac (version 2.40 and2439// later).2440def : InstAlias<"ret", (JIRL R0, R1, 0)>;2441def : InstAlias<"jr $rj", (JIRL R0, GPR:$rj, 0)>;2442 2443def : InstAlias<"rdcntid.w $rj", (RDTIMEL_W R0, GPR:$rj)>;2444def : InstAlias<"rdcntvh.w $rd", (RDTIMEH_W GPR:$rd, R0)>;2445def : InstAlias<"rdcntvl.w $rd", (RDTIMEL_W GPR:$rd, R0)>;2446 2447// Branches implemented with aliases.2448// Disassemble branch instructions not having a $zero operand to the2449// canonical mnemonics respectively, but disassemble BLT/BGE with a $zero2450// operand to the corresponding pseudo-instruction.2451// GNU Binutils behave like this since 2.41, e.g. "bgt" will be recognised2452// by the assembler but always disassembles as "blt" by objdump, while "bgtz"2453// will come back intact.2454// Match this behaviour by setting a zero weight for the b{gt,le}{,u}2455// patterns only.2456def : InstAlias<"bgt $rj, $rd, $imm16",2457                (BLT GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;2458def : InstAlias<"bgtu $rj, $rd, $imm16",2459                (BLTU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;2460def : InstAlias<"ble $rj, $rd, $imm16",2461                (BGE GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;2462def : InstAlias<"bleu $rj, $rd, $imm16",2463                (BGEU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;2464def : InstAlias<"bltz $rd, $imm16",2465                (BLT GPR:$rd, R0, simm16_lsl2_br:$imm16)>;2466def : InstAlias<"bgtz $rj, $imm16",2467                (BLT R0, GPR:$rj, simm16_lsl2_br:$imm16)>;2468def : InstAlias<"blez $rj, $imm16",2469                (BGE R0, GPR:$rj, simm16_lsl2_br:$imm16)>;2470def : InstAlias<"bgez $rd, $imm16",2471                (BGE GPR:$rd, R0, simm16_lsl2_br:$imm16)>;2472 2473// Load immediate.2474let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,2475    isAsmParserOnly = 1 in {2476def PseudoLI_W : Pseudo<(outs GPR:$rd), (ins imm32:$imm), [],2477                        "li.w", "$rd, $imm">;2478def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins imm64:$imm), [],2479                        "li.d", "$rd, $imm">, Requires<[IsLA64]>;2480}2481 2482//===----------------------------------------------------------------------===//2483// Basic Floating-Point Instructions2484//===----------------------------------------------------------------------===//2485 2486include "LoongArchFloat32InstrInfo.td"2487include "LoongArchFloat64InstrInfo.td"2488 2489let Predicates = [HasBasicF], usesCustomInserter = 1 in {2490  def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src),2491               [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>;2492  def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr),2493               [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>;2494}2495 2496//===----------------------------------------------------------------------===//2497// Privilege Instructions2498//===----------------------------------------------------------------------===//2499 2500// CSR Access Instructions2501let hasSideEffects = 1 in2502def CSRRD : FmtCSR<0x04000000, (outs GPR:$rd), (ins uimm14:$csr_num),2503                   "$rd, $csr_num">;2504let hasSideEffects = 1, Constraints = "$rd = $dst" in {2505def CSRWR : FmtCSR<0x04000020, (outs GPR:$dst),2506                   (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">;2507def CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst),2508                         (ins GPR:$rd, GPRNoR0R1:$rj, uimm14:$csr_num),2509                         "$rd, $rj, $csr_num">;2510} // hasSideEffects = 1, Constraints = "$rd = $dst"2511 2512// IOCSR Access Instructions2513def IOCSRRD_B : IOCSRRD<0x06480000>;2514def IOCSRRD_H : IOCSRRD<0x06480400>;2515def IOCSRRD_W : IOCSRRD<0x06480800>;2516def IOCSRWR_B : IOCSRWR<0x06481000>;2517def IOCSRWR_H : IOCSRWR<0x06481400>;2518def IOCSRWR_W : IOCSRWR<0x06481800>;2519let Predicates = [IsLA64] in {2520def IOCSRRD_D : IOCSRRD<0x06480c00>;2521def IOCSRWR_D : IOCSRWR<0x06481c00>;2522} // Predicates = [IsLA64]2523 2524// TLB Maintenance Instructions2525let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {2526def TLBSRCH  : FmtI32<0x06482800>;2527def TLBRD    : FmtI32<0x06482c00>;2528def TLBWR    : FmtI32<0x06483000>;2529def TLBFILL  : FmtI32<0x06483400>;2530def TLBCLR   : FmtI32<0x06482000>;2531def TLBFLUSH : FmtI32<0x06482400>;2532def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op),2533                       "$op, $rj, $rk">;2534} // hasSideEffects = 1, mayLoad = 0, mayStore = 02535 2536// Software Page Walking Instructions2537def LDDIR : Fmt2RI8<0x06400000, (outs GPR:$rd),2538                    (ins GPR:$rj, uimm8:$imm8), "$rd, $rj, $imm8">;2539def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "$rj, $seq">;2540 2541 2542// Other Miscellaneous Instructions2543let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in2544def ERTN : FmtI32<0x06483800>;2545def DBCL : MISC_I15<0x002a8000>;2546def IDLE : MISC_I15<0x06488000>;2547 2548//===----------------------------------------------------------------------===//2549// Privilege Intrinsics2550//===----------------------------------------------------------------------===//2551 2552def : Pat<(loongarch_csrrd uimm14:$imm14), (CSRRD uimm14:$imm14)>;2553def : Pat<(loongarch_csrwr GPR:$rd, uimm14:$imm14),2554          (CSRWR GPR:$rd, uimm14:$imm14)>;2555def : Pat<(loongarch_csrxchg GPR:$rd, GPRNoR0R1:$rj, uimm14:$imm14),2556          (CSRXCHG GPR:$rd, GPRNoR0R1:$rj, uimm14:$imm14)>;2557 2558def : Pat<(loongarch_iocsrrd_b GPR:$rj), (IOCSRRD_B GPR:$rj)>;2559def : Pat<(loongarch_iocsrrd_h GPR:$rj), (IOCSRRD_H GPR:$rj)>;2560def : Pat<(loongarch_iocsrrd_w GPR:$rj), (IOCSRRD_W GPR:$rj)>;2561 2562def : Pat<(loongarch_iocsrwr_b GPR:$rd, GPR:$rj), (IOCSRWR_B GPR:$rd, GPR:$rj)>;2563def : Pat<(loongarch_iocsrwr_h GPR:$rd, GPR:$rj), (IOCSRWR_H GPR:$rd, GPR:$rj)>;2564def : Pat<(loongarch_iocsrwr_w GPR:$rd, GPR:$rj), (IOCSRWR_W GPR:$rd, GPR:$rj)>;2565 2566def : Pat<(loongarch_cpucfg GPR:$rj), (CPUCFG GPR:$rj)>;2567 2568let Predicates = [IsLA64] in {2569def : Pat<(loongarch_iocsrrd_d GPR:$rj), (IOCSRRD_D GPR:$rj)>;2570def : Pat<(loongarch_iocsrwr_d GPR:$rd, GPR:$rj), (IOCSRWR_D GPR:$rd, GPR:$rj)>;2571def : Pat<(int_loongarch_asrtle_d GPR:$rj, GPR:$rk),2572          (ASRTLE_D GPR:$rj, GPR:$rk)>;2573def : Pat<(int_loongarch_asrtgt_d GPR:$rj, GPR:$rk),2574          (ASRTGT_D GPR:$rj, GPR:$rk)>;2575def : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8),2576          (LDDIR GPR:$rj, timm:$imm8)>;2577def : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8),2578          (LDPTE GPR:$rj, timm:$imm8)>;2579} // Predicates = [IsLA64]2580 2581//===----------------------------------------------------------------------===//2582// LSX Instructions2583//===----------------------------------------------------------------------===//2584include "LoongArchLSXInstrInfo.td"2585 2586//===----------------------------------------------------------------------===//2587// LASX Instructions2588//===----------------------------------------------------------------------===//2589include "LoongArchLASXInstrInfo.td"2590 2591//===----------------------------------------------------------------------===//2592// LVZ Instructions2593//===----------------------------------------------------------------------===//2594include "LoongArchLVZInstrInfo.td"2595 2596//===----------------------------------------------------------------------===//2597// LBT Instructions2598//===----------------------------------------------------------------------===//2599include "LoongArchLBTInstrInfo.td"2600