181ad6265SDimitry Andric//== LoongArchInstrInfo.td - Target Description for LoongArch -*- tablegen -*-// 281ad6265SDimitry Andric// 381ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric// 781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 881ad6265SDimitry Andric// 981ad6265SDimitry Andric// This file describes the LoongArch instructions in TableGen format. 1081ad6265SDimitry Andric// 1181ad6265SDimitry Andric//===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric//===----------------------------------------------------------------------===// 1481ad6265SDimitry Andric// LoongArch specific DAG Nodes. 1581ad6265SDimitry Andric//===----------------------------------------------------------------------===// 1681ad6265SDimitry Andric 17753f127fSDimitry Andric// Target-independent type requirements, but with target-specific formats. 18753f127fSDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 19753f127fSDimitry Andric SDTCisVT<1, i32>]>; 20753f127fSDimitry Andricdef SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 21753f127fSDimitry Andric SDTCisVT<1, i32>]>; 22753f127fSDimitry Andric 2381ad6265SDimitry Andric// Target-dependent type requirements. 24753f127fSDimitry Andricdef SDT_LoongArchCall : SDTypeProfile<0, -1, [SDTCisVT<0, GRLenVT>]>; 2581ad6265SDimitry Andricdef SDT_LoongArchIntBinOpW : SDTypeProfile<1, 2, [ 2681ad6265SDimitry Andric SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64> 2781ad6265SDimitry Andric]>; 2881ad6265SDimitry Andric 29753f127fSDimitry Andricdef SDT_LoongArchBStrIns: SDTypeProfile<1, 4, [ 30753f127fSDimitry Andric SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>, 31753f127fSDimitry Andric SDTCisSameAs<3, 4> 32753f127fSDimitry Andric]>; 33753f127fSDimitry Andric 3481ad6265SDimitry Andricdef SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [ 3581ad6265SDimitry Andric SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3> 3681ad6265SDimitry Andric]>; 3781ad6265SDimitry Andric 38bdd1243dSDimitry Andric// "VI" means no output and an integer input. 39bdd1243dSDimitry Andricdef SDT_LoongArchVI : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>; 40bdd1243dSDimitry Andric 41bdd1243dSDimitry Andricdef SDT_LoongArchCsrrd : SDTypeProfile<1, 1, [SDTCisInt<0>, 42bdd1243dSDimitry Andric SDTCisVT<1, GRLenVT>]>; 43bdd1243dSDimitry Andricdef SDT_LoongArchCsrwr : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 44bdd1243dSDimitry Andric SDTCisVT<2, GRLenVT>]>; 45bdd1243dSDimitry Andricdef SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>, 46bdd1243dSDimitry Andric SDTCisSameAs<0, 1>, 47bdd1243dSDimitry Andric SDTCisSameAs<0, 2>, 48bdd1243dSDimitry Andric SDTCisVT<3, GRLenVT>]>; 49bdd1243dSDimitry Andricdef SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>, 50bdd1243dSDimitry Andric SDTCisSameAs<0, 1>]>; 51bdd1243dSDimitry Andricdef SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>, 52bdd1243dSDimitry Andric SDTCisSameAs<0, 1>]>; 53bdd1243dSDimitry Andricdef SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>, 54bdd1243dSDimitry Andric SDTCisSameAs<0, 1>]>; 55bdd1243dSDimitry Andric 5681ad6265SDimitry Andric// TODO: Add LoongArch specific DAG Nodes 57753f127fSDimitry Andric// Target-independent nodes, but with target-specific formats. 58753f127fSDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 59753f127fSDimitry Andric [SDNPHasChain, SDNPOutGlue]>; 60753f127fSDimitry Andricdef callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 61753f127fSDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 62753f127fSDimitry Andric 6381ad6265SDimitry Andric// Target-dependent nodes. 64753f127fSDimitry Andricdef loongarch_call : SDNode<"LoongArchISD::CALL", SDT_LoongArchCall, 65753f127fSDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 66753f127fSDimitry Andric SDNPVariadic]>; 6781ad6265SDimitry Andricdef loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone, 6881ad6265SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 69bdd1243dSDimitry Andricdef loongarch_tail : SDNode<"LoongArchISD::TAIL", SDT_LoongArchCall, 70bdd1243dSDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 71bdd1243dSDimitry Andric SDNPVariadic]>; 721db9f3b2SDimitry Andricdef loongarch_call_medium : SDNode<"LoongArchISD::CALL_MEDIUM", SDT_LoongArchCall, 731db9f3b2SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 741db9f3b2SDimitry Andric SDNPVariadic]>; 751db9f3b2SDimitry Andricdef loongarch_tail_medium : SDNode<"LoongArchISD::TAIL_MEDIUM", SDT_LoongArchCall, 761db9f3b2SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 771db9f3b2SDimitry Andric SDNPVariadic]>; 781db9f3b2SDimitry Andricdef loongarch_call_large : SDNode<"LoongArchISD::CALL_LARGE", SDT_LoongArchCall, 791db9f3b2SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 801db9f3b2SDimitry Andric SDNPVariadic]>; 811db9f3b2SDimitry Andricdef loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall, 821db9f3b2SDimitry Andric [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 831db9f3b2SDimitry Andric SDNPVariadic]>; 8481ad6265SDimitry Andricdef loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>; 8581ad6265SDimitry Andricdef loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>; 8681ad6265SDimitry Andricdef loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>; 87bdd1243dSDimitry Andricdef loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>; 880fca6ea1SDimitry Andricdef loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>; 890fca6ea1SDimitry Andricdef loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>; 90bdd1243dSDimitry Andricdef loongarch_crc_w_b_w 9106c3fb27SDimitry Andric : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 92bdd1243dSDimitry Andricdef loongarch_crc_w_h_w 9306c3fb27SDimitry Andric : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 94bdd1243dSDimitry Andricdef loongarch_crc_w_w_w 9506c3fb27SDimitry Andric : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 96bdd1243dSDimitry Andricdef loongarch_crc_w_d_w 9706c3fb27SDimitry Andric : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 9806c3fb27SDimitry Andricdef loongarch_crcc_w_b_w : SDNode<"LoongArchISD::CRCC_W_B_W", 9906c3fb27SDimitry Andric SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 10006c3fb27SDimitry Andricdef loongarch_crcc_w_h_w : SDNode<"LoongArchISD::CRCC_W_H_W", 10106c3fb27SDimitry Andric SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 10206c3fb27SDimitry Andricdef loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W", 10306c3fb27SDimitry Andric SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 10406c3fb27SDimitry Andricdef loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W", 10506c3fb27SDimitry Andric SDT_LoongArchIntBinOpW, [SDNPHasChain]>; 106753f127fSDimitry Andricdef loongarch_bstrins 107753f127fSDimitry Andric : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>; 10881ad6265SDimitry Andricdef loongarch_bstrpick 10981ad6265SDimitry Andric : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>; 110bdd1243dSDimitry Andricdef loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>; 111bdd1243dSDimitry Andricdef loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>; 112bdd1243dSDimitry Andricdef loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>; 113bdd1243dSDimitry Andricdef loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>; 114bdd1243dSDimitry Andricdef loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>; 115bdd1243dSDimitry Andricdef loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>; 116bdd1243dSDimitry Andricdef loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI, 117bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 118bdd1243dSDimitry Andricdef loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI, 119bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 120bdd1243dSDimitry Andricdef loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI, 121bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 12206c3fb27SDimitry Andricdef loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", 12306c3fb27SDimitry Andric SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>; 12406c3fb27SDimitry Andricdef loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR", 12506c3fb27SDimitry Andric SDT_LoongArchMovgr2fcsr, 126bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 127bdd1243dSDimitry Andricdef loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI, 128bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 129bdd1243dSDimitry Andricdef loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd, 130bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 131bdd1243dSDimitry Andricdef loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr, 132bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 133bdd1243dSDimitry Andricdef loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG", 134bdd1243dSDimitry Andric SDT_LoongArchCsrxchg, 135bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 136bdd1243dSDimitry Andricdef loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp, 137bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 138bdd1243dSDimitry Andricdef loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp, 139bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 140bdd1243dSDimitry Andricdef loongarch_iocsrrd_w : SDNode<"LoongArchISD::IOCSRRD_W", SDTUnaryOp, 141bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 142bdd1243dSDimitry Andricdef loongarch_iocsrrd_d : SDNode<"LoongArchISD::IOCSRRD_D", SDTUnaryOp, 143bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 144bdd1243dSDimitry Andricdef loongarch_iocsrwr_b : SDNode<"LoongArchISD::IOCSRWR_B", 145bdd1243dSDimitry Andric SDT_LoongArchIocsrwr, 146bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 147bdd1243dSDimitry Andricdef loongarch_iocsrwr_h : SDNode<"LoongArchISD::IOCSRWR_H", 148bdd1243dSDimitry Andric SDT_LoongArchIocsrwr, 149bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 150bdd1243dSDimitry Andricdef loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W", 151bdd1243dSDimitry Andric SDT_LoongArchIocsrwr, 152bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 153bdd1243dSDimitry Andricdef loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D", 154bdd1243dSDimitry Andric SDT_LoongArchIocsrwr, 155bdd1243dSDimitry Andric [SDNPHasChain, SDNPSideEffect]>; 156bdd1243dSDimitry Andricdef loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp, 15706c3fb27SDimitry Andric [SDNPHasChain]>; 15881ad6265SDimitry Andric 1595f757f3fSDimitry Andricdef to_fclass_mask: SDNodeXForm<timm, [{ 1605f757f3fSDimitry Andric uint64_t Check = N->getZExtValue(); 1615f757f3fSDimitry Andric unsigned Mask = 0; 1625f757f3fSDimitry Andric if (Check & fcSNan) 1635f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskSignalingNaN; 1645f757f3fSDimitry Andric if (Check & fcQNan) 1655f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskQuietNaN; 1665f757f3fSDimitry Andric if (Check & fcPosInf) 1675f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskPositiveInfinity; 1685f757f3fSDimitry Andric if (Check & fcNegInf) 1695f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskNegativeInfinity; 1705f757f3fSDimitry Andric if (Check & fcPosNormal) 1715f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskPositiveNormal; 1725f757f3fSDimitry Andric if (Check & fcNegNormal) 1735f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskNegativeNormal; 1745f757f3fSDimitry Andric if (Check & fcPosSubnormal) 1755f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskPositiveSubnormal; 1765f757f3fSDimitry Andric if (Check & fcNegSubnormal) 1775f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskNegativeSubnormal; 1785f757f3fSDimitry Andric if (Check & fcPosZero) 1795f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskPositiveZero; 1805f757f3fSDimitry Andric if (Check & fcNegZero) 1815f757f3fSDimitry Andric Mask |= LoongArch::FClassMaskNegativeZero; 1825f757f3fSDimitry Andric return CurDAG->getTargetConstant(Mask, SDLoc(N), Subtarget->getGRLenVT()); 1835f757f3fSDimitry Andric}]>; 1845f757f3fSDimitry Andric 18581ad6265SDimitry Andric//===----------------------------------------------------------------------===// 18681ad6265SDimitry Andric// Operand and SDNode transformation definitions. 18781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 18881ad6265SDimitry Andric 18981ad6265SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> 19081ad6265SDimitry Andric : AsmOperandClass { 19181ad6265SDimitry Andric let Name = prefix # "Imm" # width # suffix; 19281ad6265SDimitry Andric let DiagnosticType = !strconcat("Invalid", Name); 19381ad6265SDimitry Andric let RenderMethod = "addImmOperands"; 19481ad6265SDimitry Andric} 19581ad6265SDimitry Andric 19681ad6265SDimitry Andricclass SImmAsmOperand<int width, string suffix = ""> 19781ad6265SDimitry Andric : ImmAsmOperand<"S", width, suffix> { 19881ad6265SDimitry Andric} 19981ad6265SDimitry Andric 20081ad6265SDimitry Andricclass UImmAsmOperand<int width, string suffix = ""> 20181ad6265SDimitry Andric : ImmAsmOperand<"U", width, suffix> { 20281ad6265SDimitry Andric} 20381ad6265SDimitry Andric 204bdd1243dSDimitry Andric// A parse method for "$r*" or "$r*, 0", where the 0 is be silently ignored. 205bdd1243dSDimitry Andric// Only used for "AM*" instructions, in order to be compatible with GAS. 206bdd1243dSDimitry Andricdef AtomicMemAsmOperand : AsmOperandClass { 207bdd1243dSDimitry Andric let Name = "AtomicMemAsmOperand"; 208bdd1243dSDimitry Andric let RenderMethod = "addRegOperands"; 209bdd1243dSDimitry Andric let PredicateMethod = "isGPR"; 210bdd1243dSDimitry Andric let ParserMethod = "parseAtomicMemOp"; 211bdd1243dSDimitry Andric} 212bdd1243dSDimitry Andric 213bdd1243dSDimitry Andricdef GPRMemAtomic : RegisterOperand<GPR> { 214bdd1243dSDimitry Andric let ParserMatchClass = AtomicMemAsmOperand; 215bdd1243dSDimitry Andric let PrintMethod = "printAtomicMemOp"; 216bdd1243dSDimitry Andric} 217bdd1243dSDimitry Andric 218bdd1243dSDimitry Andric// A parameterized register class alternative to i32imm/i64imm from Target.td. 219bdd1243dSDimitry Andricdef grlenimm : Operand<GRLenVT>; 220bdd1243dSDimitry Andricdef imm32 : Operand<GRLenVT> { 221bdd1243dSDimitry Andric let ParserMatchClass = ImmAsmOperand<"", 32, "">; 222bdd1243dSDimitry Andric} 2230fca6ea1SDimitry Andricdef imm64 : Operand<i64> { 2240fca6ea1SDimitry Andric let ParserMatchClass = ImmAsmOperand<"", 64, "">; 2250fca6ea1SDimitry Andric} 226bdd1243dSDimitry Andric 2275f757f3fSDimitry Andricdef uimm1 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<1>(Imm);}]>{ 22806c3fb27SDimitry Andric let ParserMatchClass = UImmAsmOperand<1>; 22906c3fb27SDimitry Andric} 23006c3fb27SDimitry Andric 231bdd1243dSDimitry Andricdef uimm2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]> { 23281ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<2>; 23381ad6265SDimitry Andric} 23481ad6265SDimitry Andric 235bdd1243dSDimitry Andricdef uimm2_plus1 : Operand<GRLenVT>, 236bdd1243dSDimitry Andric ImmLeaf<GRLenVT, [{return isUInt<2>(Imm - 1);}]> { 23781ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<2, "plus1">; 23881ad6265SDimitry Andric let EncoderMethod = "getImmOpValueSub1"; 23981ad6265SDimitry Andric let DecoderMethod = "decodeUImmOperand<2, 1>"; 24081ad6265SDimitry Andric} 24181ad6265SDimitry Andric 2425f757f3fSDimitry Andricdef uimm3 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<3>(Imm);}]> { 24381ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<3>; 24481ad6265SDimitry Andric} 24581ad6265SDimitry Andric 2465f757f3fSDimitry Andricdef uimm4 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<4>(Imm);}]> { 24706c3fb27SDimitry Andric let ParserMatchClass = UImmAsmOperand<4>; 24806c3fb27SDimitry Andric} 24906c3fb27SDimitry Andric 25081ad6265SDimitry Andricdef uimm5 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<5>(Imm);}]> { 25181ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<5>; 25281ad6265SDimitry Andric} 25381ad6265SDimitry Andric 25481ad6265SDimitry Andricdef uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> { 25581ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<6>; 25681ad6265SDimitry Andric} 25781ad6265SDimitry Andric 25806c3fb27SDimitry Andricdef uimm7 : Operand<GRLenVT> { 25906c3fb27SDimitry Andric let ParserMatchClass = UImmAsmOperand<7>; 26006c3fb27SDimitry Andric} 26106c3fb27SDimitry Andric 262bdd1243dSDimitry Andricdef uimm8 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<8>(Imm);}]> { 26381ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<8>; 26481ad6265SDimitry Andric} 26581ad6265SDimitry Andric 266bdd1243dSDimitry Andricclass UImm12Operand : Operand<GRLenVT>, 267bdd1243dSDimitry Andric ImmLeaf <GRLenVT, [{return isUInt<12>(Imm);}]> { 268bdd1243dSDimitry Andric let DecoderMethod = "decodeUImmOperand<12>"; 269bdd1243dSDimitry Andric} 270bdd1243dSDimitry Andric 271bdd1243dSDimitry Andricdef uimm12 : UImm12Operand { 27281ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<12>; 27381ad6265SDimitry Andric} 27481ad6265SDimitry Andric 275bdd1243dSDimitry Andricdef uimm12_ori : UImm12Operand { 276bdd1243dSDimitry Andric let ParserMatchClass = UImmAsmOperand<12, "ori">; 277bdd1243dSDimitry Andric} 278bdd1243dSDimitry Andric 279bdd1243dSDimitry Andricdef uimm14 : Operand<GRLenVT>, 280bdd1243dSDimitry Andric ImmLeaf <GRLenVT, [{return isUInt<14>(Imm);}]> { 28181ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<14>; 28281ad6265SDimitry Andric} 28381ad6265SDimitry Andric 284bdd1243dSDimitry Andricdef uimm15 : Operand<GRLenVT>, 285bdd1243dSDimitry Andric ImmLeaf <GRLenVT, [{return isUInt<15>(Imm);}]> { 28681ad6265SDimitry Andric let ParserMatchClass = UImmAsmOperand<15>; 28781ad6265SDimitry Andric} 28881ad6265SDimitry Andric 28906c3fb27SDimitry Andricdef simm5 : Operand<GRLenVT> { 29006c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<5>; 29106c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<5>"; 29206c3fb27SDimitry Andric} 29306c3fb27SDimitry Andric 29406c3fb27SDimitry Andricdef simm8 : Operand<GRLenVT> { 29506c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<8>; 29606c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<8>"; 29706c3fb27SDimitry Andric} 29806c3fb27SDimitry Andric 29906c3fb27SDimitry Andricforeach I = [1, 2, 3] in { 30006c3fb27SDimitry Andricdef simm8_lsl # I : Operand<GRLenVT> { 30106c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<8, "lsl" # I>; 30206c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<" # I # ">"; 30306c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<8," # I # ">"; 30406c3fb27SDimitry Andric} 30506c3fb27SDimitry Andric} 30606c3fb27SDimitry Andric 30706c3fb27SDimitry Andricdef simm9_lsl3 : Operand<GRLenVT> { 30806c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<9, "lsl3">; 30906c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<3>"; 31006c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<9, 3>"; 31106c3fb27SDimitry Andric} 31206c3fb27SDimitry Andric 31306c3fb27SDimitry Andricdef simm10 : Operand<GRLenVT> { 31406c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<10>; 31506c3fb27SDimitry Andric} 31606c3fb27SDimitry Andric 31706c3fb27SDimitry Andricdef simm10_lsl2 : Operand<GRLenVT> { 31806c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<10, "lsl2">; 31906c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 32006c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<10, 2>"; 32106c3fb27SDimitry Andric} 32206c3fb27SDimitry Andric 32306c3fb27SDimitry Andricdef simm11_lsl1 : Operand<GRLenVT> { 32406c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<11, "lsl1">; 32506c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<1>"; 32606c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<11, 1>"; 32706c3fb27SDimitry Andric} 32806c3fb27SDimitry Andric 329bdd1243dSDimitry Andricclass SImm12Operand : Operand<GRLenVT>, 330bdd1243dSDimitry Andric ImmLeaf <GRLenVT, [{return isInt<12>(Imm);}]> { 33181ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<12>"; 33281ad6265SDimitry Andric} 33381ad6265SDimitry Andric 334bdd1243dSDimitry Andricdef simm12 : SImm12Operand { 335bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<12>; 336bdd1243dSDimitry Andric} 337bdd1243dSDimitry Andric 338bdd1243dSDimitry Andricdef simm12_addlike : SImm12Operand { 339bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<12, "addlike">; 340bdd1243dSDimitry Andric} 341bdd1243dSDimitry Andric 342bdd1243dSDimitry Andricdef simm12_lu52id : SImm12Operand { 343bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<12, "lu52id">; 344bdd1243dSDimitry Andric} 345bdd1243dSDimitry Andric 34606c3fb27SDimitry Andricdef simm13 : Operand<GRLenVT> { 34706c3fb27SDimitry Andric let ParserMatchClass = SImmAsmOperand<13>; 34806c3fb27SDimitry Andric let DecoderMethod = "decodeSImmOperand<13>"; 34906c3fb27SDimitry Andric} 35006c3fb27SDimitry Andric 351bdd1243dSDimitry Andricdef simm14_lsl2 : Operand<GRLenVT>, 352bdd1243dSDimitry Andric ImmLeaf<GRLenVT, [{return isShiftedInt<14,2>(Imm);}]> { 35381ad6265SDimitry Andric let ParserMatchClass = SImmAsmOperand<14, "lsl2">; 35406c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 35581ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<14, 2>"; 35681ad6265SDimitry Andric} 35781ad6265SDimitry Andric 35881ad6265SDimitry Andricdef simm16 : Operand<GRLenVT> { 35981ad6265SDimitry Andric let ParserMatchClass = SImmAsmOperand<16>; 36081ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<16>"; 36181ad6265SDimitry Andric} 36281ad6265SDimitry Andric 363753f127fSDimitry Andricdef simm16_lsl2 : Operand<GRLenVT>, 364753f127fSDimitry Andric ImmLeaf<GRLenVT, [{return isInt<16>(Imm>>2);}]> { 365753f127fSDimitry Andric let ParserMatchClass = SImmAsmOperand<16, "lsl2">; 36606c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 367753f127fSDimitry Andric let DecoderMethod = "decodeSImmOperand<16, 2>"; 368753f127fSDimitry Andric} 369753f127fSDimitry Andric 370753f127fSDimitry Andricdef simm16_lsl2_br : Operand<OtherVT> { 37181ad6265SDimitry Andric let ParserMatchClass = SImmAsmOperand<16, "lsl2">; 37206c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 37381ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<16, 2>"; 37481ad6265SDimitry Andric} 37581ad6265SDimitry Andric 376bdd1243dSDimitry Andricclass SImm20Operand : Operand<GRLenVT> { 37781ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<20>"; 37881ad6265SDimitry Andric} 37981ad6265SDimitry Andric 380bdd1243dSDimitry Andricdef simm20 : SImm20Operand { 381bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<20>; 382bdd1243dSDimitry Andric} 383bdd1243dSDimitry Andric 384bdd1243dSDimitry Andricdef simm20_pcalau12i : SImm20Operand { 385bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<20, "pcalau12i">; 386bdd1243dSDimitry Andric} 387bdd1243dSDimitry Andric 388bdd1243dSDimitry Andricdef simm20_lu12iw : SImm20Operand { 389bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<20, "lu12iw">; 390bdd1243dSDimitry Andric} 391bdd1243dSDimitry Andric 392bdd1243dSDimitry Andricdef simm20_lu32id : SImm20Operand { 393bdd1243dSDimitry Andric let ParserMatchClass = SImmAsmOperand<20, "lu32id">; 394bdd1243dSDimitry Andric} 395bdd1243dSDimitry Andric 3961db9f3b2SDimitry Andricdef simm20_pcaddu18i : SImm20Operand { 3971db9f3b2SDimitry Andric let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">; 3981db9f3b2SDimitry Andric} 3991db9f3b2SDimitry Andric 40052418fc2SDimitry Andricdef simm20_pcaddi : SImm20Operand { 40152418fc2SDimitry Andric let ParserMatchClass = SImmAsmOperand<20, "pcaddi">; 40252418fc2SDimitry Andric} 40352418fc2SDimitry Andric 404753f127fSDimitry Andricdef simm21_lsl2 : Operand<OtherVT> { 40581ad6265SDimitry Andric let ParserMatchClass = SImmAsmOperand<21, "lsl2">; 40606c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 40781ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<21, 2>"; 40881ad6265SDimitry Andric} 40981ad6265SDimitry Andric 410bdd1243dSDimitry Andricdef SImm26OperandB: AsmOperandClass { 411bdd1243dSDimitry Andric let Name = "SImm26OperandB"; 412bdd1243dSDimitry Andric let PredicateMethod = "isSImm26Operand"; 413bdd1243dSDimitry Andric let RenderMethod = "addImmOperands"; 414bdd1243dSDimitry Andric let DiagnosticType = "InvalidSImm26Operand"; 415bdd1243dSDimitry Andric let ParserMethod = "parseImmediate"; 416bdd1243dSDimitry Andric} 417bdd1243dSDimitry Andric 418bdd1243dSDimitry Andric// A symbol or an imm used in B/PseudoBR. 419bdd1243dSDimitry Andricdef simm26_b : Operand<OtherVT> { 420bdd1243dSDimitry Andric let ParserMatchClass = SImm26OperandB; 42106c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 42281ad6265SDimitry Andric let DecoderMethod = "decodeSImmOperand<26, 2>"; 42381ad6265SDimitry Andric} 42481ad6265SDimitry Andric 425bdd1243dSDimitry Andricdef SImm26OperandBL: AsmOperandClass { 426bdd1243dSDimitry Andric let Name = "SImm26OperandBL"; 427bdd1243dSDimitry Andric let PredicateMethod = "isSImm26Operand"; 428bdd1243dSDimitry Andric let RenderMethod = "addImmOperands"; 429bdd1243dSDimitry Andric let DiagnosticType = "InvalidSImm26Operand"; 430bdd1243dSDimitry Andric let ParserMethod = "parseSImm26Operand"; 431bdd1243dSDimitry Andric} 432bdd1243dSDimitry Andric 433bdd1243dSDimitry Andric// A symbol or an imm used in BL/PseudoCALL/PseudoTAIL. 434bdd1243dSDimitry Andricdef simm26_symbol : Operand<GRLenVT> { 435bdd1243dSDimitry Andric let ParserMatchClass = SImm26OperandBL; 43606c3fb27SDimitry Andric let EncoderMethod = "getImmOpValueAsr<2>"; 437bdd1243dSDimitry Andric let DecoderMethod = "decodeSImmOperand<26, 2>"; 438bdd1243dSDimitry Andric} 439bdd1243dSDimitry Andric 44006c3fb27SDimitry Andric// A 32-bit signed immediate with the lowest 16 bits zeroed, suitable for 44106c3fb27SDimitry Andric// direct use with `addu16i.d`. 44206c3fb27SDimitry Andricdef simm16_lsl16 : Operand<GRLenVT>, 44306c3fb27SDimitry Andric ImmLeaf<GRLenVT, [{return isShiftedInt<16, 16>(Imm);}]>; 44406c3fb27SDimitry Andric 44506c3fb27SDimitry Andric// A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for 44606c3fb27SDimitry Andric// use in additions. 44706c3fb27SDimitry Andricdef simm32_hi16_lo12: Operand<GRLenVT>, ImmLeaf<GRLenVT, [{ 4480fca6ea1SDimitry Andric return !isInt<12>(Imm) && isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm)); 44906c3fb27SDimitry Andric}]>; 45006c3fb27SDimitry Andric 451bdd1243dSDimitry Andricdef BareSymbol : AsmOperandClass { 452bdd1243dSDimitry Andric let Name = "BareSymbol"; 453bdd1243dSDimitry Andric let RenderMethod = "addImmOperands"; 454bdd1243dSDimitry Andric let DiagnosticType = "InvalidBareSymbol"; 455bdd1243dSDimitry Andric let ParserMethod = "parseImmediate"; 456bdd1243dSDimitry Andric} 457bdd1243dSDimitry Andric 458bdd1243dSDimitry Andric// A bare symbol used in "PseudoLA_*" instructions. 459bdd1243dSDimitry Andricdef bare_symbol : Operand<GRLenVT> { 460bdd1243dSDimitry Andric let ParserMatchClass = BareSymbol; 461bdd1243dSDimitry Andric} 462bdd1243dSDimitry Andric 4630fca6ea1SDimitry Andricdef TPRelAddSymbol : AsmOperandClass { 4640fca6ea1SDimitry Andric let Name = "TPRelAddSymbol"; 4650fca6ea1SDimitry Andric let RenderMethod = "addImmOperands"; 4660fca6ea1SDimitry Andric let DiagnosticType = "InvalidTPRelAddSymbol"; 4670fca6ea1SDimitry Andric let ParserMethod = "parseOperandWithModifier"; 4680fca6ea1SDimitry Andric} 4690fca6ea1SDimitry Andric 4700fca6ea1SDimitry Andric// A bare symbol with the %le_add_r variant. 4710fca6ea1SDimitry Andricdef tprel_add_symbol : Operand<GRLenVT> { 4720fca6ea1SDimitry Andric let ParserMatchClass = TPRelAddSymbol; 4730fca6ea1SDimitry Andric} 4740fca6ea1SDimitry Andric 4750fca6ea1SDimitry Andric 47681ad6265SDimitry Andric// Standalone (codegen-only) immleaf patterns. 47781ad6265SDimitry Andric 47881ad6265SDimitry Andric// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048]. 47981ad6265SDimitry Andricdef simm12_plus1 : ImmLeaf<GRLenVT, 48081ad6265SDimitry Andric [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>; 48181ad6265SDimitry Andric 48281ad6265SDimitry Andric// Return the negation of an immediate value. 48381ad6265SDimitry Andricdef NegImm : SDNodeXForm<imm, [{ 48481ad6265SDimitry Andric return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), 48581ad6265SDimitry Andric N->getValueType(0)); 48681ad6265SDimitry Andric}]>; 48781ad6265SDimitry Andric 488753f127fSDimitry Andric// FP immediate patterns. 489753f127fSDimitry Andricdef fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; 490753f127fSDimitry Andricdef fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; 491753f127fSDimitry Andricdef fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>; 492753f127fSDimitry Andric 493bdd1243dSDimitry Andric// Return an immediate subtracted from 32. 494bdd1243dSDimitry Andricdef ImmSubFrom32 : SDNodeXForm<imm, [{ 495bdd1243dSDimitry Andric return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), 496bdd1243dSDimitry Andric N->getValueType(0)); 497bdd1243dSDimitry Andric}]>; 498753f127fSDimitry Andric 49906c3fb27SDimitry Andric// Return the lowest 12 bits of the signed immediate. 50006c3fb27SDimitry Andricdef LO12: SDNodeXForm<imm, [{ 50106c3fb27SDimitry Andric return CurDAG->getTargetConstant(SignExtend64<12>(N->getSExtValue()), 50206c3fb27SDimitry Andric SDLoc(N), N->getValueType(0)); 50306c3fb27SDimitry Andric}]>; 50406c3fb27SDimitry Andric 50506c3fb27SDimitry Andric// Return the higher 16 bits of the signed immediate. 50606c3fb27SDimitry Andricdef HI16 : SDNodeXForm<imm, [{ 50706c3fb27SDimitry Andric return CurDAG->getTargetConstant(N->getSExtValue() >> 16, SDLoc(N), 50806c3fb27SDimitry Andric N->getValueType(0)); 50906c3fb27SDimitry Andric}]>; 51006c3fb27SDimitry Andric 51106c3fb27SDimitry Andric// Return the higher 16 bits of the signed immediate, adjusted for use within an 51206c3fb27SDimitry Andric// `addu16i.d + addi` pair. 51306c3fb27SDimitry Andricdef HI16ForAddu16idAddiPair: SDNodeXForm<imm, [{ 51406c3fb27SDimitry Andric auto Imm = N->getSExtValue(); 51506c3fb27SDimitry Andric return CurDAG->getTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16, 51606c3fb27SDimitry Andric SDLoc(N), N->getValueType(0)); 51706c3fb27SDimitry Andric}]>; 51806c3fb27SDimitry Andric 519753f127fSDimitry Andricdef BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; 52006c3fb27SDimitry Andricdef AddrConstant : ComplexPattern<iPTR, 2, "SelectAddrConstant">; 521bdd1243dSDimitry Andricdef NonFIBaseAddr : ComplexPattern<iPTR, 1, "selectNonFIBaseAddr">; 522bdd1243dSDimitry Andric 523bdd1243dSDimitry Andricdef fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa), 524bdd1243dSDimitry Andric (fma node:$fj, node:$fk, node:$fa), [{ 525bdd1243dSDimitry Andric return N->getFlags().hasNoSignedZeros(); 526bdd1243dSDimitry Andric}]>; 527753f127fSDimitry Andric 52806c3fb27SDimitry Andric// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), 52906c3fb27SDimitry Andric// in which imm = imm0 + imm1, and both imm0 & imm1 are simm12. 53006c3fb27SDimitry Andricdef AddiPair : PatLeaf<(imm), [{ 53106c3fb27SDimitry Andric if (!N->hasOneUse()) 53206c3fb27SDimitry Andric return false; 53306c3fb27SDimitry Andric // The immediate operand must be in range [-4096,-2049] or [2048,4094]. 53406c3fb27SDimitry Andric int64_t Imm = N->getSExtValue(); 53506c3fb27SDimitry Andric return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); 53606c3fb27SDimitry Andric}]>; 53706c3fb27SDimitry Andric 53806c3fb27SDimitry Andric// Return -2048 if immediate is negative or 2047 if positive. 53906c3fb27SDimitry Andricdef AddiPairImmLarge : SDNodeXForm<imm, [{ 54006c3fb27SDimitry Andric int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047; 54106c3fb27SDimitry Andric return CurDAG->getTargetConstant(Imm, SDLoc(N), 54206c3fb27SDimitry Andric N->getValueType(0)); 54306c3fb27SDimitry Andric}]>; 54406c3fb27SDimitry Andric 54506c3fb27SDimitry Andric// Return imm - (imm < 0 ? -2048 : 2047). 54606c3fb27SDimitry Andricdef AddiPairImmSmall : SDNodeXForm<imm, [{ 54706c3fb27SDimitry Andric int64_t Imm = N->getSExtValue(); 54806c3fb27SDimitry Andric int64_t Adj = Imm < 0 ? -2048 : 2047; 54906c3fb27SDimitry Andric return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N), 55006c3fb27SDimitry Andric N->getValueType(0)); 55106c3fb27SDimitry Andric}]>; 55206c3fb27SDimitry Andric 55306c3fb27SDimitry Andric// Check if (mul r, imm) can be optimized to (SLLI (ALSL r, r, i0), i1), 55406c3fb27SDimitry Andric// in which imm = (1 + (1 << i0)) << i1. 55506c3fb27SDimitry Andricdef AlslSlliImm : PatLeaf<(imm), [{ 55606c3fb27SDimitry Andric if (!N->hasOneUse()) 55706c3fb27SDimitry Andric return false; 55806c3fb27SDimitry Andric uint64_t Imm = N->getZExtValue(); 55906c3fb27SDimitry Andric unsigned I1 = llvm::countr_zero(Imm); 56006c3fb27SDimitry Andric uint64_t Rem = Imm >> I1; 56106c3fb27SDimitry Andric return Rem == 3 || Rem == 5 || Rem == 9 || Rem == 17; 56206c3fb27SDimitry Andric}]>; 56306c3fb27SDimitry Andric 56406c3fb27SDimitry Andricdef AlslSlliImmI1 : SDNodeXForm<imm, [{ 56506c3fb27SDimitry Andric uint64_t Imm = N->getZExtValue(); 56606c3fb27SDimitry Andric unsigned I1 = llvm::countr_zero(Imm); 56706c3fb27SDimitry Andric return CurDAG->getTargetConstant(I1, SDLoc(N), 56806c3fb27SDimitry Andric N->getValueType(0)); 56906c3fb27SDimitry Andric}]>; 57006c3fb27SDimitry Andric 57106c3fb27SDimitry Andricdef AlslSlliImmI0 : SDNodeXForm<imm, [{ 57206c3fb27SDimitry Andric uint64_t Imm = N->getZExtValue(); 57306c3fb27SDimitry Andric unsigned I1 = llvm::countr_zero(Imm); 57406c3fb27SDimitry Andric uint64_t I0; 57506c3fb27SDimitry Andric switch (Imm >> I1) { 57606c3fb27SDimitry Andric case 3: I0 = 1; break; 57706c3fb27SDimitry Andric case 5: I0 = 2; break; 57806c3fb27SDimitry Andric case 9: I0 = 3; break; 57906c3fb27SDimitry Andric default: I0 = 4; break; 58006c3fb27SDimitry Andric } 58106c3fb27SDimitry Andric return CurDAG->getTargetConstant(I0, SDLoc(N), 58206c3fb27SDimitry Andric N->getValueType(0)); 58306c3fb27SDimitry Andric}]>; 58406c3fb27SDimitry Andric 5855f757f3fSDimitry Andric// Check if (and r, imm) can be optimized to (BSTRINS r, R0, msb, lsb), 5865f757f3fSDimitry Andric// in which imm = ~((2^^(msb-lsb+1) - 1) << lsb). 5875f757f3fSDimitry Andricdef BstrinsImm : PatLeaf<(imm), [{ 5885f757f3fSDimitry Andric if (!N->hasOneUse()) 5895f757f3fSDimitry Andric return false; 5905f757f3fSDimitry Andric uint64_t Imm = N->getZExtValue(); 5915f757f3fSDimitry Andric // andi can be used instead if Imm <= 0xfff. 5925f757f3fSDimitry Andric if (Imm <= 0xfff) 5935f757f3fSDimitry Andric return false; 5945f757f3fSDimitry Andric unsigned MaskIdx, MaskLen; 5955f757f3fSDimitry Andric return N->getValueType(0).getSizeInBits() == 32 5965f757f3fSDimitry Andric ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) 5975f757f3fSDimitry Andric : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); 5985f757f3fSDimitry Andric}]>; 5995f757f3fSDimitry Andric 6005f757f3fSDimitry Andricdef BstrinsMsb: SDNodeXForm<imm, [{ 6015f757f3fSDimitry Andric uint64_t Imm = N->getZExtValue(); 6025f757f3fSDimitry Andric unsigned MaskIdx, MaskLen; 6035f757f3fSDimitry Andric N->getValueType(0).getSizeInBits() == 32 6045f757f3fSDimitry Andric ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) 6055f757f3fSDimitry Andric : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); 6065f757f3fSDimitry Andric return CurDAG->getTargetConstant(MaskIdx + MaskLen - 1, SDLoc(N), 6075f757f3fSDimitry Andric N->getValueType(0)); 6085f757f3fSDimitry Andric}]>; 6095f757f3fSDimitry Andric 6105f757f3fSDimitry Andricdef BstrinsLsb: SDNodeXForm<imm, [{ 6115f757f3fSDimitry Andric uint64_t Imm = N->getZExtValue(); 6125f757f3fSDimitry Andric unsigned MaskIdx, MaskLen; 6135f757f3fSDimitry Andric N->getValueType(0).getSizeInBits() == 32 6145f757f3fSDimitry Andric ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) 6155f757f3fSDimitry Andric : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); 6165f757f3fSDimitry Andric return CurDAG->getTargetConstant(MaskIdx, SDLoc(N), N->getValueType(0)); 6175f757f3fSDimitry Andric}]>; 6185f757f3fSDimitry Andric 61981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 62081ad6265SDimitry Andric// Instruction Formats 62181ad6265SDimitry Andric//===----------------------------------------------------------------------===// 62281ad6265SDimitry Andric 62381ad6265SDimitry Andricinclude "LoongArchInstrFormats.td" 62481ad6265SDimitry Andricinclude "LoongArchFloatInstrFormats.td" 62506c3fb27SDimitry Andricinclude "LoongArchLSXInstrFormats.td" 62606c3fb27SDimitry Andricinclude "LoongArchLASXInstrFormats.td" 62706c3fb27SDimitry Andricinclude "LoongArchLBTInstrFormats.td" 62881ad6265SDimitry Andric 62981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 63081ad6265SDimitry Andric// Instruction Class Templates 63181ad6265SDimitry Andric//===----------------------------------------------------------------------===// 63281ad6265SDimitry Andric 63306c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 63406c3fb27SDimitry Andricclass ALU_3R<bits<32> op> 63506c3fb27SDimitry Andric : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">; 63606c3fb27SDimitry Andricclass ALU_2R<bits<32> op> 63706c3fb27SDimitry Andric : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">; 63881ad6265SDimitry Andric 63906c3fb27SDimitry Andricclass ALU_3RI2<bits<32> op, Operand ImmOpnd> 64006c3fb27SDimitry Andric : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2), 64181ad6265SDimitry Andric "$rd, $rj, $rk, $imm2">; 64206c3fb27SDimitry Andricclass ALU_3RI3<bits<32> op, Operand ImmOpnd> 64306c3fb27SDimitry Andric : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3), 64481ad6265SDimitry Andric "$rd, $rj, $rk, $imm3">; 64506c3fb27SDimitry Andricclass ALU_2RI5<bits<32> op, Operand ImmOpnd> 64606c3fb27SDimitry Andric : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5), 64781ad6265SDimitry Andric "$rd, $rj, $imm5">; 64806c3fb27SDimitry Andricclass ALU_2RI6<bits<32> op, Operand ImmOpnd> 64906c3fb27SDimitry Andric : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6), 65081ad6265SDimitry Andric "$rd, $rj, $imm6">; 65106c3fb27SDimitry Andricclass ALU_2RI12<bits<32> op, Operand ImmOpnd> 65206c3fb27SDimitry Andric : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12), 65381ad6265SDimitry Andric "$rd, $rj, $imm12">; 65406c3fb27SDimitry Andricclass ALU_2RI16<bits<32> op, Operand ImmOpnd> 65506c3fb27SDimitry Andric : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16), 65681ad6265SDimitry Andric "$rd, $rj, $imm16">; 65706c3fb27SDimitry Andricclass ALU_1RI20<bits<32> op, Operand ImmOpnd> 65806c3fb27SDimitry Andric : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), "$rd, $imm20">; 65906c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 66081ad6265SDimitry Andric 66106c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 66206c3fb27SDimitry Andricclass MISC_I15<bits<32> op> 66306c3fb27SDimitry Andric : FmtI15<op, (outs), (ins uimm15:$imm15), "$imm15">; 66481ad6265SDimitry Andric 66506c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 66606c3fb27SDimitry Andricclass RDTIME_2R<bits<32> op> 66706c3fb27SDimitry Andric : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), "$rd, $rj">; 66881ad6265SDimitry Andric 66906c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 67006c3fb27SDimitry Andricclass BrCC_2RI16<bits<32> op> 67106c3fb27SDimitry Andric : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16), 67281ad6265SDimitry Andric "$rj, $rd, $imm16"> { 67381ad6265SDimitry Andric let isBranch = 1; 67481ad6265SDimitry Andric let isTerminator = 1; 67581ad6265SDimitry Andric} 67606c3fb27SDimitry Andricclass BrCCZ_1RI21<bits<32> op> 67706c3fb27SDimitry Andric : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21), 67881ad6265SDimitry Andric "$rj, $imm21"> { 67981ad6265SDimitry Andric let isBranch = 1; 68081ad6265SDimitry Andric let isTerminator = 1; 68181ad6265SDimitry Andric} 68206c3fb27SDimitry Andricclass Br_I26<bits<32> op> 68306c3fb27SDimitry Andric : FmtI26<op, (outs), (ins simm26_b:$imm26), "$imm26"> { 68481ad6265SDimitry Andric let isBranch = 1; 68581ad6265SDimitry Andric let isTerminator = 1; 6865f757f3fSDimitry Andric let isBarrier = 1; 68781ad6265SDimitry Andric} 68806c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 68981ad6265SDimitry Andric 69006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 69106c3fb27SDimitry Andricclass LOAD_3R<bits<32> op> 69206c3fb27SDimitry Andric : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">; 69306c3fb27SDimitry Andricclass LOAD_2RI12<bits<32> op> 69406c3fb27SDimitry Andric : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12_addlike:$imm12), 69581ad6265SDimitry Andric "$rd, $rj, $imm12">; 69606c3fb27SDimitry Andricclass LOAD_2RI14<bits<32> op> 69706c3fb27SDimitry Andric : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), 69881ad6265SDimitry Andric "$rd, $rj, $imm14">; 69906c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 1, mayStore = 0 70081ad6265SDimitry Andric 70106c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 70206c3fb27SDimitry Andricclass STORE_3R<bits<32> op> 70306c3fb27SDimitry Andric : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk), 70481ad6265SDimitry Andric "$rd, $rj, $rk">; 70506c3fb27SDimitry Andricclass STORE_2RI12<bits<32> op> 70606c3fb27SDimitry Andric : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12_addlike:$imm12), 70781ad6265SDimitry Andric "$rd, $rj, $imm12">; 70806c3fb27SDimitry Andricclass STORE_2RI14<bits<32> op> 70906c3fb27SDimitry Andric : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), 71081ad6265SDimitry Andric "$rd, $rj, $imm14">; 71106c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 1 71281ad6265SDimitry Andric 71306c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in 71406c3fb27SDimitry Andricclass AM_3R<bits<32> op> 71506c3fb27SDimitry Andric : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj), 716bdd1243dSDimitry Andric "$rd, $rk, $rj">; 71781ad6265SDimitry Andric 7187a6dacacSDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 71906c3fb27SDimitry Andricclass LLBase<bits<32> op> 72006c3fb27SDimitry Andric : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), 72181ad6265SDimitry Andric "$rd, $rj, $imm14">; 7227a6dacacSDimitry Andricclass LLBase_ACQ<bits<32> op> 7237a6dacacSDimitry Andric : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">; 7247a6dacacSDimitry Andric} 72581ad6265SDimitry Andric 7267a6dacacSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in { 72706c3fb27SDimitry Andricclass SCBase<bits<32> op> 72881ad6265SDimitry Andric : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), 72906c3fb27SDimitry Andric "$rd, $rj, $imm14">; 7307a6dacacSDimitry Andricclass SCBase_128<bits<32> op> 7317a6dacacSDimitry Andric : Fmt3R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rk, GPR:$rj), 7327a6dacacSDimitry Andric "$rd, $rk, $rj">; 7337a6dacacSDimitry Andricclass SCBase_REL<bits<32> op> 7347a6dacacSDimitry Andric : Fmt2R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj), "$rd, $rj">; 7357a6dacacSDimitry Andric} 73681ad6265SDimitry Andric 73706c3fb27SDimitry Andriclet hasSideEffects = 1 in 73806c3fb27SDimitry Andricclass IOCSRRD<bits<32> op> 73906c3fb27SDimitry Andric : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">; 74081ad6265SDimitry Andric 74106c3fb27SDimitry Andriclet hasSideEffects = 1 in 74206c3fb27SDimitry Andricclass IOCSRWR<bits<32> op> 74306c3fb27SDimitry Andric : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), "$rd, $rj">; 74481ad6265SDimitry Andric 74581ad6265SDimitry Andric//===----------------------------------------------------------------------===// 74681ad6265SDimitry Andric// Basic Integer Instructions 74781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 74881ad6265SDimitry Andric 74981ad6265SDimitry Andric// Arithmetic Operation Instructions 75006c3fb27SDimitry Andricdef ADD_W : ALU_3R<0x00100000>; 75106c3fb27SDimitry Andricdef SUB_W : ALU_3R<0x00110000>; 75206c3fb27SDimitry Andricdef ADDI_W : ALU_2RI12<0x02800000, simm12_addlike>; 75306c3fb27SDimitry Andricdef ALSL_W : ALU_3RI2<0x00040000, uimm2_plus1>; 7540fca6ea1SDimitry Andriclet isReMaterializable = 1 in { 75506c3fb27SDimitry Andricdef LU12I_W : ALU_1RI20<0x14000000, simm20_lu12iw>; 7560fca6ea1SDimitry Andric} 75706c3fb27SDimitry Andricdef SLT : ALU_3R<0x00120000>; 75806c3fb27SDimitry Andricdef SLTU : ALU_3R<0x00128000>; 75906c3fb27SDimitry Andricdef SLTI : ALU_2RI12<0x02000000, simm12>; 76006c3fb27SDimitry Andricdef SLTUI : ALU_2RI12<0x02400000, simm12>; 76152418fc2SDimitry Andricdef PCADDI : ALU_1RI20<0x18000000, simm20_pcaddi>; 76206c3fb27SDimitry Andricdef PCADDU12I : ALU_1RI20<0x1c000000, simm20>; 76306c3fb27SDimitry Andricdef PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>; 76406c3fb27SDimitry Andricdef AND : ALU_3R<0x00148000>; 76506c3fb27SDimitry Andricdef OR : ALU_3R<0x00150000>; 76606c3fb27SDimitry Andricdef NOR : ALU_3R<0x00140000>; 76706c3fb27SDimitry Andricdef XOR : ALU_3R<0x00158000>; 76806c3fb27SDimitry Andricdef ANDN : ALU_3R<0x00168000>; 76906c3fb27SDimitry Andricdef ORN : ALU_3R<0x00160000>; 77006c3fb27SDimitry Andricdef ANDI : ALU_2RI12<0x03400000, uimm12>; 7710fca6ea1SDimitry Andric// See LoongArchInstrInfo::isAsCheapAsAMove for more details. 7720fca6ea1SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in { 77306c3fb27SDimitry Andricdef ORI : ALU_2RI12<0x03800000, uimm12_ori>; 77406c3fb27SDimitry Andricdef XORI : ALU_2RI12<0x03c00000, uimm12>; 7750fca6ea1SDimitry Andric} 77606c3fb27SDimitry Andricdef MUL_W : ALU_3R<0x001c0000>; 77706c3fb27SDimitry Andricdef MULH_W : ALU_3R<0x001c8000>; 77806c3fb27SDimitry Andricdef MULH_WU : ALU_3R<0x001d0000>; 779753f127fSDimitry Andriclet usesCustomInserter = true in { 78006c3fb27SDimitry Andricdef DIV_W : ALU_3R<0x00200000>; 78106c3fb27SDimitry Andricdef MOD_W : ALU_3R<0x00208000>; 78206c3fb27SDimitry Andricdef DIV_WU : ALU_3R<0x00210000>; 78306c3fb27SDimitry Andricdef MOD_WU : ALU_3R<0x00218000>; 784753f127fSDimitry Andric} // usesCustomInserter = true 78581ad6265SDimitry Andric 78681ad6265SDimitry Andric// Bit-shift Instructions 78706c3fb27SDimitry Andricdef SLL_W : ALU_3R<0x00170000>; 78806c3fb27SDimitry Andricdef SRL_W : ALU_3R<0x00178000>; 78906c3fb27SDimitry Andricdef SRA_W : ALU_3R<0x00180000>; 79006c3fb27SDimitry Andricdef ROTR_W : ALU_3R<0x001b0000>; 79181ad6265SDimitry Andric 79206c3fb27SDimitry Andricdef SLLI_W : ALU_2RI5<0x00408000, uimm5>; 79306c3fb27SDimitry Andricdef SRLI_W : ALU_2RI5<0x00448000, uimm5>; 79406c3fb27SDimitry Andricdef SRAI_W : ALU_2RI5<0x00488000, uimm5>; 79506c3fb27SDimitry Andricdef ROTRI_W : ALU_2RI5<0x004c8000, uimm5>; 79681ad6265SDimitry Andric 79781ad6265SDimitry Andric// Bit-manipulation Instructions 79806c3fb27SDimitry Andricdef EXT_W_B : ALU_2R<0x00005c00>; 79906c3fb27SDimitry Andricdef EXT_W_H : ALU_2R<0x00005800>; 80006c3fb27SDimitry Andricdef CLO_W : ALU_2R<0x00001000>; 80106c3fb27SDimitry Andricdef CLZ_W : ALU_2R<0x00001400>; 80206c3fb27SDimitry Andricdef CTO_W : ALU_2R<0x00001800>; 80306c3fb27SDimitry Andricdef CTZ_W : ALU_2R<0x00001c00>; 80406c3fb27SDimitry Andricdef BYTEPICK_W : ALU_3RI2<0x00080000, uimm2>; 80506c3fb27SDimitry Andricdef REVB_2H : ALU_2R<0x00003000>; 80606c3fb27SDimitry Andricdef BITREV_4B : ALU_2R<0x00004800>; 80706c3fb27SDimitry Andricdef BITREV_W : ALU_2R<0x00005000>; 80881ad6265SDimitry Andriclet Constraints = "$rd = $dst" in { 80906c3fb27SDimitry Andricdef BSTRINS_W : FmtBSTR_W<0x00600000, (outs GPR:$dst), 81081ad6265SDimitry Andric (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw), 81106c3fb27SDimitry Andric "$rd, $rj, $msbw, $lsbw">; 81281ad6265SDimitry Andric} 81306c3fb27SDimitry Andricdef BSTRPICK_W : FmtBSTR_W<0x00608000, (outs GPR:$rd), 81481ad6265SDimitry Andric (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw), 81506c3fb27SDimitry Andric "$rd, $rj, $msbw, $lsbw">; 81606c3fb27SDimitry Andricdef MASKEQZ : ALU_3R<0x00130000>; 81706c3fb27SDimitry Andricdef MASKNEZ : ALU_3R<0x00138000>; 81881ad6265SDimitry Andric 81981ad6265SDimitry Andric// Branch Instructions 82006c3fb27SDimitry Andricdef BEQ : BrCC_2RI16<0x58000000>; 82106c3fb27SDimitry Andricdef BNE : BrCC_2RI16<0x5c000000>; 82206c3fb27SDimitry Andricdef BLT : BrCC_2RI16<0x60000000>; 82306c3fb27SDimitry Andricdef BGE : BrCC_2RI16<0x64000000>; 82406c3fb27SDimitry Andricdef BLTU : BrCC_2RI16<0x68000000>; 82506c3fb27SDimitry Andricdef BGEU : BrCC_2RI16<0x6c000000>; 82606c3fb27SDimitry Andricdef BEQZ : BrCCZ_1RI21<0x40000000>; 82706c3fb27SDimitry Andricdef BNEZ : BrCCZ_1RI21<0x44000000>; 82806c3fb27SDimitry Andricdef B : Br_I26<0x50000000>; 82981ad6265SDimitry Andric 83006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, Defs=[R1] in 83106c3fb27SDimitry Andricdef BL : FmtI26<0x54000000, (outs), (ins simm26_symbol:$imm26), "$imm26">; 83206c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 83306c3fb27SDimitry Andricdef JIRL : Fmt2RI16<0x4c000000, (outs GPR:$rd), 83406c3fb27SDimitry Andric (ins GPR:$rj, simm16_lsl2:$imm16), "$rd, $rj, $imm16">; 83581ad6265SDimitry Andric 83681ad6265SDimitry Andric// Common Memory Access Instructions 83706c3fb27SDimitry Andricdef LD_B : LOAD_2RI12<0x28000000>; 83806c3fb27SDimitry Andricdef LD_H : LOAD_2RI12<0x28400000>; 83906c3fb27SDimitry Andricdef LD_W : LOAD_2RI12<0x28800000>; 84006c3fb27SDimitry Andricdef LD_BU : LOAD_2RI12<0x2a000000>; 84106c3fb27SDimitry Andricdef LD_HU : LOAD_2RI12<0x2a400000>; 84206c3fb27SDimitry Andricdef ST_B : STORE_2RI12<0x29000000>; 84306c3fb27SDimitry Andricdef ST_H : STORE_2RI12<0x29400000>; 84406c3fb27SDimitry Andricdef ST_W : STORE_2RI12<0x29800000>; 84506c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1 in 84606c3fb27SDimitry Andricdef PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), 84781ad6265SDimitry Andric "$imm5, $rj, $imm12">; 84881ad6265SDimitry Andric 84981ad6265SDimitry Andric// Atomic Memory Access Instructions 85006c3fb27SDimitry Andricdef LL_W : LLBase<0x20000000>; 85106c3fb27SDimitry Andricdef SC_W : SCBase<0x21000000>; 8527a6dacacSDimitry Andricdef LLACQ_W : LLBase_ACQ<0x38578000>; 8537a6dacacSDimitry Andricdef SCREL_W : SCBase_REL<0x38578400>; 85481ad6265SDimitry Andric 85581ad6265SDimitry Andric// Barrier Instructions 85606c3fb27SDimitry Andricdef DBAR : MISC_I15<0x38720000>; 85706c3fb27SDimitry Andricdef IBAR : MISC_I15<0x38728000>; 85881ad6265SDimitry Andric 85981ad6265SDimitry Andric// Other Miscellaneous Instructions 86006c3fb27SDimitry Andricdef SYSCALL : MISC_I15<0x002b0000>; 86106c3fb27SDimitry Andricdef BREAK : MISC_I15<0x002a0000>; 86206c3fb27SDimitry Andricdef RDTIMEL_W : RDTIME_2R<0x00006000>; 86306c3fb27SDimitry Andricdef RDTIMEH_W : RDTIME_2R<0x00006400>; 86406c3fb27SDimitry Andricdef CPUCFG : ALU_2R<0x00006c00>; 86581ad6265SDimitry Andric 866bdd1243dSDimitry Andric// Cache Maintenance Instructions 86706c3fb27SDimitry Andricdef CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), 868bdd1243dSDimitry Andric "$op, $rj, $imm12">; 869bdd1243dSDimitry Andric 87081ad6265SDimitry Andric/// LA64 instructions 87181ad6265SDimitry Andric 87281ad6265SDimitry Andriclet Predicates = [IsLA64] in { 87381ad6265SDimitry Andric 87481ad6265SDimitry Andric// Arithmetic Operation Instructions for 64-bits 87506c3fb27SDimitry Andricdef ADD_D : ALU_3R<0x00108000>; 87606c3fb27SDimitry Andricdef SUB_D : ALU_3R<0x00118000>; 8770fca6ea1SDimitry Andric// ADDI_D isn't always rematerializable, but isReMaterializable will be used as 8780fca6ea1SDimitry Andric// a hint which is verified in isReallyTriviallyReMaterializable. 8790fca6ea1SDimitry Andric// See LoongArchInstrInfo::isAsCheapAsAMove for more details. 8800fca6ea1SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in { 88106c3fb27SDimitry Andricdef ADDI_D : ALU_2RI12<0x02c00000, simm12_addlike>; 8820fca6ea1SDimitry Andric} 88306c3fb27SDimitry Andricdef ADDU16I_D : ALU_2RI16<0x10000000, simm16>; 88406c3fb27SDimitry Andricdef ALSL_WU : ALU_3RI2<0x00060000, uimm2_plus1>; 88506c3fb27SDimitry Andricdef ALSL_D : ALU_3RI2<0x002c0000, uimm2_plus1>; 88681ad6265SDimitry Andriclet Constraints = "$rd = $dst" in { 8870fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, 8880fca6ea1SDimitry Andric isReMaterializable = 1 in 88906c3fb27SDimitry Andricdef LU32I_D : Fmt1RI20<0x16000000, (outs GPR:$dst), 89006c3fb27SDimitry Andric (ins GPR:$rd, simm20_lu32id:$imm20), 89181ad6265SDimitry Andric "$rd, $imm20">; 89281ad6265SDimitry Andric} 8930fca6ea1SDimitry Andriclet isReMaterializable = 1 in { 89406c3fb27SDimitry Andricdef LU52I_D : ALU_2RI12<0x03000000, simm12_lu52id>; 8950fca6ea1SDimitry Andric} 8961db9f3b2SDimitry Andricdef PCADDU18I : ALU_1RI20<0x1e000000, simm20_pcaddu18i>; 89706c3fb27SDimitry Andricdef MUL_D : ALU_3R<0x001d8000>; 89806c3fb27SDimitry Andricdef MULH_D : ALU_3R<0x001e0000>; 89906c3fb27SDimitry Andricdef MULH_DU : ALU_3R<0x001e8000>; 90006c3fb27SDimitry Andricdef MULW_D_W : ALU_3R<0x001f0000>; 90106c3fb27SDimitry Andricdef MULW_D_WU : ALU_3R<0x001f8000>; 902753f127fSDimitry Andriclet usesCustomInserter = true in { 90306c3fb27SDimitry Andricdef DIV_D : ALU_3R<0x00220000>; 90406c3fb27SDimitry Andricdef MOD_D : ALU_3R<0x00228000>; 90506c3fb27SDimitry Andricdef DIV_DU : ALU_3R<0x00230000>; 90606c3fb27SDimitry Andricdef MOD_DU : ALU_3R<0x00238000>; 907753f127fSDimitry Andric} // usesCustomInserter = true 90881ad6265SDimitry Andric 90981ad6265SDimitry Andric// Bit-shift Instructions for 64-bits 91006c3fb27SDimitry Andricdef SLL_D : ALU_3R<0x00188000>; 91106c3fb27SDimitry Andricdef SRL_D : ALU_3R<0x00190000>; 91206c3fb27SDimitry Andricdef SRA_D : ALU_3R<0x00198000>; 91306c3fb27SDimitry Andricdef ROTR_D : ALU_3R<0x001b8000>; 91406c3fb27SDimitry Andricdef SLLI_D : ALU_2RI6<0x00410000, uimm6>; 91506c3fb27SDimitry Andricdef SRLI_D : ALU_2RI6<0x00450000, uimm6>; 91606c3fb27SDimitry Andricdef SRAI_D : ALU_2RI6<0x00490000, uimm6>; 91706c3fb27SDimitry Andricdef ROTRI_D : ALU_2RI6<0x004d0000, uimm6>; 91881ad6265SDimitry Andric 91981ad6265SDimitry Andric// Bit-manipulation Instructions for 64-bits 92006c3fb27SDimitry Andricdef CLO_D : ALU_2R<0x00002000>; 92106c3fb27SDimitry Andricdef CLZ_D : ALU_2R<0x00002400>; 92206c3fb27SDimitry Andricdef CTO_D : ALU_2R<0x00002800>; 92306c3fb27SDimitry Andricdef CTZ_D : ALU_2R<0x00002c00>; 92406c3fb27SDimitry Andricdef BYTEPICK_D : ALU_3RI3<0x000c0000, uimm3>; 92506c3fb27SDimitry Andricdef REVB_4H : ALU_2R<0x00003400>; 92606c3fb27SDimitry Andricdef REVB_2W : ALU_2R<0x00003800>; 92706c3fb27SDimitry Andricdef REVB_D : ALU_2R<0x00003c00>; 92806c3fb27SDimitry Andricdef REVH_2W : ALU_2R<0x00004000>; 92906c3fb27SDimitry Andricdef REVH_D : ALU_2R<0x00004400>; 93006c3fb27SDimitry Andricdef BITREV_8B : ALU_2R<0x00004c00>; 93106c3fb27SDimitry Andricdef BITREV_D : ALU_2R<0x00005400>; 93281ad6265SDimitry Andriclet Constraints = "$rd = $dst" in { 93306c3fb27SDimitry Andricdef BSTRINS_D : FmtBSTR_D<0x00800000, (outs GPR:$dst), 93481ad6265SDimitry Andric (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 93506c3fb27SDimitry Andric "$rd, $rj, $msbd, $lsbd">; 93681ad6265SDimitry Andric} 93706c3fb27SDimitry Andricdef BSTRPICK_D : FmtBSTR_D<0x00c00000, (outs GPR:$rd), 93881ad6265SDimitry Andric (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 93906c3fb27SDimitry Andric "$rd, $rj, $msbd, $lsbd">; 94081ad6265SDimitry Andric 94181ad6265SDimitry Andric// Common Memory Access Instructions for 64-bits 94206c3fb27SDimitry Andricdef LD_WU : LOAD_2RI12<0x2a800000>; 94306c3fb27SDimitry Andricdef LD_D : LOAD_2RI12<0x28c00000>; 94406c3fb27SDimitry Andricdef ST_D : STORE_2RI12<0x29c00000>; 94506c3fb27SDimitry Andricdef LDX_B : LOAD_3R<0x38000000>; 94606c3fb27SDimitry Andricdef LDX_H : LOAD_3R<0x38040000>; 94706c3fb27SDimitry Andricdef LDX_W : LOAD_3R<0x38080000>; 94806c3fb27SDimitry Andricdef LDX_D : LOAD_3R<0x380c0000>; 94906c3fb27SDimitry Andricdef LDX_BU : LOAD_3R<0x38200000>; 95006c3fb27SDimitry Andricdef LDX_HU : LOAD_3R<0x38240000>; 95106c3fb27SDimitry Andricdef LDX_WU : LOAD_3R<0x38280000>; 95206c3fb27SDimitry Andricdef STX_B : STORE_3R<0x38100000>; 95306c3fb27SDimitry Andricdef STX_H : STORE_3R<0x38140000>; 95406c3fb27SDimitry Andricdef STX_W : STORE_3R<0x38180000>; 95506c3fb27SDimitry Andricdef STX_D : STORE_3R<0x381c0000>; 95606c3fb27SDimitry Andricdef LDPTR_W : LOAD_2RI14<0x24000000>; 95706c3fb27SDimitry Andricdef LDPTR_D : LOAD_2RI14<0x26000000>; 95806c3fb27SDimitry Andricdef STPTR_W : STORE_2RI14<0x25000000>; 95906c3fb27SDimitry Andricdef STPTR_D : STORE_2RI14<0x27000000>; 96006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1 in 96106c3fb27SDimitry Andricdef PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), 96281ad6265SDimitry Andric "$imm5, $rj, $rk">; 96381ad6265SDimitry Andric 96481ad6265SDimitry Andric// Bound Check Memory Access Instructions 96506c3fb27SDimitry Andricdef LDGT_B : LOAD_3R<0x38780000>; 96606c3fb27SDimitry Andricdef LDGT_H : LOAD_3R<0x38788000>; 96706c3fb27SDimitry Andricdef LDGT_W : LOAD_3R<0x38790000>; 96806c3fb27SDimitry Andricdef LDGT_D : LOAD_3R<0x38798000>; 96906c3fb27SDimitry Andricdef LDLE_B : LOAD_3R<0x387a0000>; 97006c3fb27SDimitry Andricdef LDLE_H : LOAD_3R<0x387a8000>; 97106c3fb27SDimitry Andricdef LDLE_W : LOAD_3R<0x387b0000>; 97206c3fb27SDimitry Andricdef LDLE_D : LOAD_3R<0x387b8000>; 97306c3fb27SDimitry Andricdef STGT_B : STORE_3R<0x387c0000>; 97406c3fb27SDimitry Andricdef STGT_H : STORE_3R<0x387c8000>; 97506c3fb27SDimitry Andricdef STGT_W : STORE_3R<0x387d0000>; 97606c3fb27SDimitry Andricdef STGT_D : STORE_3R<0x387d8000>; 97706c3fb27SDimitry Andricdef STLE_B : STORE_3R<0x387e0000>; 97806c3fb27SDimitry Andricdef STLE_H : STORE_3R<0x387e8000>; 97906c3fb27SDimitry Andricdef STLE_W : STORE_3R<0x387f0000>; 98006c3fb27SDimitry Andricdef STLE_D : STORE_3R<0x387f8000>; 98181ad6265SDimitry Andric 98281ad6265SDimitry Andric// Atomic Memory Access Instructions for 64-bits 9837a6dacacSDimitry Andricdef AMSWAP_B : AM_3R<0x385c0000>; 9847a6dacacSDimitry Andricdef AMSWAP_H : AM_3R<0x385c8000>; 98506c3fb27SDimitry Andricdef AMSWAP_W : AM_3R<0x38600000>; 98606c3fb27SDimitry Andricdef AMSWAP_D : AM_3R<0x38608000>; 9877a6dacacSDimitry Andricdef AMADD_B : AM_3R<0x385d0000>; 9887a6dacacSDimitry Andricdef AMADD_H : AM_3R<0x385d8000>; 98906c3fb27SDimitry Andricdef AMADD_W : AM_3R<0x38610000>; 99006c3fb27SDimitry Andricdef AMADD_D : AM_3R<0x38618000>; 99106c3fb27SDimitry Andricdef AMAND_W : AM_3R<0x38620000>; 99206c3fb27SDimitry Andricdef AMAND_D : AM_3R<0x38628000>; 99306c3fb27SDimitry Andricdef AMOR_W : AM_3R<0x38630000>; 99406c3fb27SDimitry Andricdef AMOR_D : AM_3R<0x38638000>; 99506c3fb27SDimitry Andricdef AMXOR_W : AM_3R<0x38640000>; 99606c3fb27SDimitry Andricdef AMXOR_D : AM_3R<0x38648000>; 99706c3fb27SDimitry Andricdef AMMAX_W : AM_3R<0x38650000>; 99806c3fb27SDimitry Andricdef AMMAX_D : AM_3R<0x38658000>; 99906c3fb27SDimitry Andricdef AMMIN_W : AM_3R<0x38660000>; 100006c3fb27SDimitry Andricdef AMMIN_D : AM_3R<0x38668000>; 100106c3fb27SDimitry Andricdef AMMAX_WU : AM_3R<0x38670000>; 100206c3fb27SDimitry Andricdef AMMAX_DU : AM_3R<0x38678000>; 100306c3fb27SDimitry Andricdef AMMIN_WU : AM_3R<0x38680000>; 100406c3fb27SDimitry Andricdef AMMIN_DU : AM_3R<0x38688000>; 10057a6dacacSDimitry Andricdef AMSWAP__DB_B : AM_3R<0x385e0000>; 10067a6dacacSDimitry Andricdef AMSWAP__DB_H : AM_3R<0x385e8000>; 100706c3fb27SDimitry Andricdef AMSWAP__DB_W : AM_3R<0x38690000>; 100806c3fb27SDimitry Andricdef AMSWAP__DB_D : AM_3R<0x38698000>; 10097a6dacacSDimitry Andricdef AMADD__DB_B : AM_3R<0x385f0000>; 10107a6dacacSDimitry Andricdef AMADD__DB_H : AM_3R<0x385f8000>; 101106c3fb27SDimitry Andricdef AMADD__DB_W : AM_3R<0x386a0000>; 101206c3fb27SDimitry Andricdef AMADD__DB_D : AM_3R<0x386a8000>; 101306c3fb27SDimitry Andricdef AMAND__DB_W : AM_3R<0x386b0000>; 101406c3fb27SDimitry Andricdef AMAND__DB_D : AM_3R<0x386b8000>; 101506c3fb27SDimitry Andricdef AMOR__DB_W : AM_3R<0x386c0000>; 101606c3fb27SDimitry Andricdef AMOR__DB_D : AM_3R<0x386c8000>; 101706c3fb27SDimitry Andricdef AMXOR__DB_W : AM_3R<0x386d0000>; 101806c3fb27SDimitry Andricdef AMXOR__DB_D : AM_3R<0x386d8000>; 101906c3fb27SDimitry Andricdef AMMAX__DB_W : AM_3R<0x386e0000>; 102006c3fb27SDimitry Andricdef AMMAX__DB_D : AM_3R<0x386e8000>; 102106c3fb27SDimitry Andricdef AMMIN__DB_W : AM_3R<0x386f0000>; 102206c3fb27SDimitry Andricdef AMMIN__DB_D : AM_3R<0x386f8000>; 102306c3fb27SDimitry Andricdef AMMAX__DB_WU : AM_3R<0x38700000>; 102406c3fb27SDimitry Andricdef AMMAX__DB_DU : AM_3R<0x38708000>; 102506c3fb27SDimitry Andricdef AMMIN__DB_WU : AM_3R<0x38710000>; 102606c3fb27SDimitry Andricdef AMMIN__DB_DU : AM_3R<0x38718000>; 10277a6dacacSDimitry Andricdef AMCAS_B : AM_3R<0x38580000>; 10287a6dacacSDimitry Andricdef AMCAS_H : AM_3R<0x38588000>; 10297a6dacacSDimitry Andricdef AMCAS_W : AM_3R<0x38590000>; 10307a6dacacSDimitry Andricdef AMCAS_D : AM_3R<0x38598000>; 10317a6dacacSDimitry Andricdef AMCAS__DB_B : AM_3R<0x385a0000>; 10327a6dacacSDimitry Andricdef AMCAS__DB_H : AM_3R<0x385a8000>; 10337a6dacacSDimitry Andricdef AMCAS__DB_W : AM_3R<0x385b0000>; 10347a6dacacSDimitry Andricdef AMCAS__DB_D : AM_3R<0x385b8000>; 103506c3fb27SDimitry Andricdef LL_D : LLBase<0x22000000>; 103606c3fb27SDimitry Andricdef SC_D : SCBase<0x23000000>; 10377a6dacacSDimitry Andricdef SC_Q : SCBase_128<0x38570000>; 10387a6dacacSDimitry Andricdef LLACQ_D : LLBase_ACQ<0x38578800>; 10397a6dacacSDimitry Andricdef SCREL_D : SCBase_REL<0x38578C00>; 104081ad6265SDimitry Andric 104181ad6265SDimitry Andric// CRC Check Instructions 104206c3fb27SDimitry Andricdef CRC_W_B_W : ALU_3R<0x00240000>; 104306c3fb27SDimitry Andricdef CRC_W_H_W : ALU_3R<0x00248000>; 104406c3fb27SDimitry Andricdef CRC_W_W_W : ALU_3R<0x00250000>; 104506c3fb27SDimitry Andricdef CRC_W_D_W : ALU_3R<0x00258000>; 104606c3fb27SDimitry Andricdef CRCC_W_B_W : ALU_3R<0x00260000>; 104706c3fb27SDimitry Andricdef CRCC_W_H_W : ALU_3R<0x00268000>; 104806c3fb27SDimitry Andricdef CRCC_W_W_W : ALU_3R<0x00270000>; 104906c3fb27SDimitry Andricdef CRCC_W_D_W : ALU_3R<0x00278000>; 105081ad6265SDimitry Andric 105181ad6265SDimitry Andric// Other Miscellaneous Instructions for 64-bits 105206c3fb27SDimitry Andricdef ASRTLE_D : FmtASRT<0x00010000, (outs), (ins GPR:$rj, GPR:$rk), 105306c3fb27SDimitry Andric "$rj, $rk">; 105406c3fb27SDimitry Andricdef ASRTGT_D : FmtASRT<0x00018000, (outs), (ins GPR:$rj, GPR:$rk), 105506c3fb27SDimitry Andric "$rj, $rk">; 105606c3fb27SDimitry Andricdef RDTIME_D : RDTIME_2R<0x00006800>; 105781ad6265SDimitry Andric} // Predicates = [IsLA64] 105881ad6265SDimitry Andric 105981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 106081ad6265SDimitry Andric// Pseudo-instructions and codegen patterns 106181ad6265SDimitry Andric// 106281ad6265SDimitry Andric// Naming convention: For 'generic' pattern classes, we use the naming 106381ad6265SDimitry Andric// convention PatTy1Ty2. 106481ad6265SDimitry Andric//===----------------------------------------------------------------------===// 106581ad6265SDimitry Andric 106681ad6265SDimitry Andric/// Generic pattern classes 106781ad6265SDimitry Andric 1068*6e516c87SDimitry Andricdef assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{ 1069*6e516c87SDimitry Andric return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32); 1070*6e516c87SDimitry Andric}]>; 107181ad6265SDimitry Andricclass PatGprGpr<SDPatternOperator OpNode, LAInst Inst> 107281ad6265SDimitry Andric : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>; 107381ad6265SDimitry Andricclass PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst> 1074*6e516c87SDimitry Andric : Pat<(sext_inreg (OpNode (assertsexti32 GPR:$rj), (assertsexti32 GPR:$rk)), i32), (Inst GPR:$rj, GPR:$rk)>; 1075bdd1243dSDimitry Andricclass PatGpr<SDPatternOperator OpNode, LAInst Inst> 1076bdd1243dSDimitry Andric : Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>; 107781ad6265SDimitry Andric 107881ad6265SDimitry Andricclass PatGprImm<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd> 107981ad6265SDimitry Andric : Pat<(OpNode GPR:$rj, ImmOpnd:$imm), 108081ad6265SDimitry Andric (Inst GPR:$rj, ImmOpnd:$imm)>; 108181ad6265SDimitry Andricclass PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd> 108281ad6265SDimitry Andric : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32), 108381ad6265SDimitry Andric (Inst GPR:$rj, ImmOpnd:$imm)>; 108481ad6265SDimitry Andric 1085bdd1243dSDimitry Andric/// Predicates 1086bdd1243dSDimitry Andricdef AddLike: PatFrags<(ops node:$A, node:$B), 1087bdd1243dSDimitry Andric [(add node:$A, node:$B), (or node:$A, node:$B)], [{ 10880fca6ea1SDimitry Andric return CurDAG->isBaseWithConstantOffset(SDValue(N, 0)); 1089bdd1243dSDimitry Andric}]>; 1090bdd1243dSDimitry Andric 109181ad6265SDimitry Andric/// Simple arithmetic operations 109281ad6265SDimitry Andric 109381ad6265SDimitry Andric// Match both a plain shift and one where the shift amount is masked (this is 109481ad6265SDimitry Andric// typically introduced when the legalizer promotes the shift amount and 109581ad6265SDimitry Andric// zero-extends it). For LoongArch, the mask is unnecessary as shifts in the 109681ad6265SDimitry Andric// base ISA only read the least significant 5 bits (LA32) or 6 bits (LA64). 109781ad6265SDimitry Andricdef shiftMaskGRLen 109881ad6265SDimitry Andric : ComplexPattern<GRLenVT, 1, "selectShiftMaskGRLen", [], [], 0>; 109981ad6265SDimitry Andricdef shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>; 110081ad6265SDimitry Andric 1101753f127fSDimitry Andricdef sexti32 : ComplexPattern<i64, 1, "selectSExti32">; 1102753f127fSDimitry Andricdef zexti32 : ComplexPattern<i64, 1, "selectZExti32">; 1103753f127fSDimitry Andric 110481ad6265SDimitry Andricclass shiftop<SDPatternOperator operator> 110581ad6265SDimitry Andric : PatFrag<(ops node:$val, node:$count), 110681ad6265SDimitry Andric (operator node:$val, (GRLenVT (shiftMaskGRLen node:$count)))>; 110781ad6265SDimitry Andricclass shiftopw<SDPatternOperator operator> 110881ad6265SDimitry Andric : PatFrag<(ops node:$val, node:$count), 110981ad6265SDimitry Andric (operator node:$val, (i64 (shiftMask32 node:$count)))>; 111081ad6265SDimitry Andric 111106c3fb27SDimitry Andricdef mul_const_oneuse : PatFrag<(ops node:$A, node:$B), 111206c3fb27SDimitry Andric (mul node:$A, node:$B), [{ 111306c3fb27SDimitry Andric if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 111406c3fb27SDimitry Andric return N1C->hasOneUse(); 111506c3fb27SDimitry Andric return false; 111606c3fb27SDimitry Andric}]>; 111706c3fb27SDimitry Andric 111881ad6265SDimitry Andriclet Predicates = [IsLA32] in { 111981ad6265SDimitry Andricdef : PatGprGpr<add, ADD_W>; 112081ad6265SDimitry Andricdef : PatGprImm<add, ADDI_W, simm12>; 112181ad6265SDimitry Andricdef : PatGprGpr<sub, SUB_W>; 1122753f127fSDimitry Andricdef : PatGprGpr<sdiv, DIV_W>; 1123753f127fSDimitry Andricdef : PatGprGpr<udiv, DIV_WU>; 1124753f127fSDimitry Andricdef : PatGprGpr<srem, MOD_W>; 1125753f127fSDimitry Andricdef : PatGprGpr<urem, MOD_WU>; 1126753f127fSDimitry Andricdef : PatGprGpr<mul, MUL_W>; 1127753f127fSDimitry Andricdef : PatGprGpr<mulhs, MULH_W>; 1128753f127fSDimitry Andricdef : PatGprGpr<mulhu, MULH_WU>; 1129bdd1243dSDimitry Andricdef : PatGprGpr<rotr, ROTR_W>; 1130bdd1243dSDimitry Andricdef : PatGprImm<rotr, ROTRI_W, uimm5>; 113106c3fb27SDimitry Andric 113206c3fb27SDimitry Andricforeach Idx = 1...3 in { 113306c3fb27SDimitry Andric defvar ShamtA = !mul(8, Idx); 113406c3fb27SDimitry Andric defvar ShamtB = !mul(8, !sub(4, Idx)); 113506c3fb27SDimitry Andric def : Pat<(or (shl GPR:$rk, (i32 ShamtA)), (srl GPR:$rj, (i32 ShamtB))), 113606c3fb27SDimitry Andric (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; 113706c3fb27SDimitry Andric} 113881ad6265SDimitry Andric} // Predicates = [IsLA32] 113981ad6265SDimitry Andric 114081ad6265SDimitry Andriclet Predicates = [IsLA64] in { 114181ad6265SDimitry Andricdef : PatGprGpr<add, ADD_D>; 114281ad6265SDimitry Andricdef : PatGprImm<add, ADDI_D, simm12>; 114381ad6265SDimitry Andricdef : PatGprGpr<sub, SUB_D>; 1144753f127fSDimitry Andricdef : PatGprGpr<sdiv, DIV_D>; 11450fca6ea1SDimitry Andricdef : PatGprGpr_32<sdiv, DIV_W>; 1146753f127fSDimitry Andricdef : PatGprGpr<udiv, DIV_DU>; 11470fca6ea1SDimitry Andricdef : PatGprGpr<loongarch_div_wu, DIV_WU>; 1148753f127fSDimitry Andricdef : PatGprGpr<srem, MOD_D>; 11490fca6ea1SDimitry Andricdef : PatGprGpr_32<srem, MOD_W>; 1150753f127fSDimitry Andricdef : PatGprGpr<urem, MOD_DU>; 11510fca6ea1SDimitry Andricdef : PatGprGpr<loongarch_mod_wu, MOD_WU>; 1152bdd1243dSDimitry Andricdef : PatGprGpr<rotr, ROTR_D>; 1153bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_rotr_w, ROTR_W>; 1154bdd1243dSDimitry Andricdef : PatGprImm<rotr, ROTRI_D, uimm6>; 1155bdd1243dSDimitry Andricdef : PatGprImm_32<rotr, ROTRI_W, uimm5>; 11560fca6ea1SDimitry Andricdef : PatGprImm<loongarch_rotr_w, ROTRI_W, uimm5>; 1157753f127fSDimitry Andric// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the 1158753f127fSDimitry Andric// product are used. 1159753f127fSDimitry Andricdef : PatGprGpr<mul, MUL_D>; 1160753f127fSDimitry Andricdef : PatGprGpr<mulhs, MULH_D>; 1161753f127fSDimitry Andricdef : PatGprGpr<mulhu, MULH_DU>; 1162753f127fSDimitry Andric// Select MULW_D_W for calculating the full 64 bits product of i32xi32 signed 1163753f127fSDimitry Andric// multiplication. 1164753f127fSDimitry Andricdef : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))), 1165753f127fSDimitry Andric (MULW_D_W GPR:$rj, GPR:$rk)>; 1166753f127fSDimitry Andric// Select MULW_D_WU for calculating the full 64 bits product of i32xi32 1167753f127fSDimitry Andric// unsigned multiplication. 1168753f127fSDimitry Andricdef : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)), 1169753f127fSDimitry Andric (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))), 1170753f127fSDimitry Andric (MULW_D_WU GPR:$rj, GPR:$rk)>; 117106c3fb27SDimitry Andric 117206c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, simm16_lsl16:$imm), 117306c3fb27SDimitry Andric (ADDU16I_D GPR:$rj, (HI16 $imm))>; 117406c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, simm32_hi16_lo12:$imm), 117506c3fb27SDimitry Andric (ADDI_D (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), 117606c3fb27SDimitry Andric (LO12 $imm))>; 117706c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rj, simm32_hi16_lo12:$imm), i32), 117806c3fb27SDimitry Andric (ADDI_W (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), 117906c3fb27SDimitry Andric (LO12 $imm))>; 118006c3fb27SDimitry Andric 118106c3fb27SDimitry Andriclet Predicates = [IsLA32] in { 118206c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, (AddiPair:$im)), 118306c3fb27SDimitry Andric (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), 118406c3fb27SDimitry Andric (AddiPairImmSmall AddiPair:$im))>; 118506c3fb27SDimitry Andric} // Predicates = [IsLA32] 118606c3fb27SDimitry Andric 118706c3fb27SDimitry Andriclet Predicates = [IsLA64] in { 118806c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, (AddiPair:$im)), 118906c3fb27SDimitry Andric (ADDI_D (ADDI_D GPR:$rj, (AddiPairImmLarge AddiPair:$im)), 119006c3fb27SDimitry Andric (AddiPairImmSmall AddiPair:$im))>; 119106c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rj, (AddiPair:$im)), i32), 119206c3fb27SDimitry Andric (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), 119306c3fb27SDimitry Andric (AddiPairImmSmall AddiPair:$im))>; 119406c3fb27SDimitry Andric} // Predicates = [IsLA64] 119506c3fb27SDimitry Andric 119606c3fb27SDimitry Andriclet Predicates = [IsLA32] in { 119706c3fb27SDimitry Andricforeach Idx0 = 1...4 in { 119806c3fb27SDimitry Andric foreach Idx1 = 1...4 in { 119906c3fb27SDimitry Andric defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); 120006c3fb27SDimitry Andric def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), 120106c3fb27SDimitry Andric (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), 120206c3fb27SDimitry Andric GPR:$r, (i32 Idx1))>; 120306c3fb27SDimitry Andric } 120406c3fb27SDimitry Andric} 120506c3fb27SDimitry Andricforeach Idx0 = 1...4 in { 120606c3fb27SDimitry Andric foreach Idx1 = 1...4 in { 120706c3fb27SDimitry Andric defvar Cb = !add(1, !shl(1, Idx0)); 120806c3fb27SDimitry Andric defvar CImm = !add(Cb, !shl(Cb, Idx1)); 120906c3fb27SDimitry Andric def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), 121006c3fb27SDimitry Andric (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), 121106c3fb27SDimitry Andric (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>; 121206c3fb27SDimitry Andric } 121306c3fb27SDimitry Andric} 121406c3fb27SDimitry Andric} // Predicates = [IsLA32] 121506c3fb27SDimitry Andric 121606c3fb27SDimitry Andriclet Predicates = [IsLA64] in { 121706c3fb27SDimitry Andricforeach Idx0 = 1...4 in { 121806c3fb27SDimitry Andric foreach Idx1 = 1...4 in { 121906c3fb27SDimitry Andric defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); 122006c3fb27SDimitry Andric def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), 122106c3fb27SDimitry Andric (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), 122206c3fb27SDimitry Andric GPR:$r, (i64 Idx1))>; 122306c3fb27SDimitry Andric def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), 122406c3fb27SDimitry Andric (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), 122506c3fb27SDimitry Andric GPR:$r, (i64 Idx1))>; 122606c3fb27SDimitry Andric } 122706c3fb27SDimitry Andric} 122806c3fb27SDimitry Andricforeach Idx0 = 1...4 in { 122906c3fb27SDimitry Andric foreach Idx1 = 1...4 in { 123006c3fb27SDimitry Andric defvar Cb = !add(1, !shl(1, Idx0)); 123106c3fb27SDimitry Andric defvar CImm = !add(Cb, !shl(Cb, Idx1)); 123206c3fb27SDimitry Andric def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), 123306c3fb27SDimitry Andric (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), 123406c3fb27SDimitry Andric (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; 123506c3fb27SDimitry Andric def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), 123606c3fb27SDimitry Andric (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), 123706c3fb27SDimitry Andric (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; 123806c3fb27SDimitry Andric } 123906c3fb27SDimitry Andric} 124006c3fb27SDimitry Andric} // Predicates = [IsLA64] 124106c3fb27SDimitry Andric 124206c3fb27SDimitry Andriclet Predicates = [IsLA32] in { 124306c3fb27SDimitry Andricdef : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), 124406c3fb27SDimitry Andric (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), 124506c3fb27SDimitry Andric (AlslSlliImmI1 AlslSlliImm:$im))>; 124606c3fb27SDimitry Andric} // Predicates = [IsLA32] 124706c3fb27SDimitry Andric 124806c3fb27SDimitry Andriclet Predicates = [IsLA64] in { 124906c3fb27SDimitry Andricdef : Pat<(sext_inreg (mul GPR:$rj, (AlslSlliImm:$im)), i32), 125006c3fb27SDimitry Andric (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), 125106c3fb27SDimitry Andric (AlslSlliImmI1 AlslSlliImm:$im))>; 125206c3fb27SDimitry Andricdef : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), 125306c3fb27SDimitry Andric (SLLI_D (ALSL_D GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), 125406c3fb27SDimitry Andric (AlslSlliImmI1 AlslSlliImm:$im))>; 125506c3fb27SDimitry Andric} // Predicates = [IsLA64] 125606c3fb27SDimitry Andric 125706c3fb27SDimitry Andricforeach Idx = 1...7 in { 125806c3fb27SDimitry Andric defvar ShamtA = !mul(8, Idx); 125906c3fb27SDimitry Andric defvar ShamtB = !mul(8, !sub(8, Idx)); 126006c3fb27SDimitry Andric def : Pat<(or (shl GPR:$rk, (i64 ShamtA)), (srl GPR:$rj, (i64 ShamtB))), 126106c3fb27SDimitry Andric (BYTEPICK_D GPR:$rj, GPR:$rk, Idx)>; 126206c3fb27SDimitry Andric} 126306c3fb27SDimitry Andric 126406c3fb27SDimitry Andricforeach Idx = 1...3 in { 126506c3fb27SDimitry Andric defvar ShamtA = !mul(8, Idx); 126606c3fb27SDimitry Andric defvar ShamtB = !mul(8, !sub(4, Idx)); 126706c3fb27SDimitry Andric // NOTE: the srl node would already be transformed into a loongarch_bstrpick 126806c3fb27SDimitry Andric // by the time this pattern gets to execute, hence the weird construction. 126906c3fb27SDimitry Andric def : Pat<(sext_inreg (or (shl GPR:$rk, (i64 ShamtA)), 127006c3fb27SDimitry Andric (loongarch_bstrpick GPR:$rj, (i64 31), 127106c3fb27SDimitry Andric (i64 ShamtB))), i32), 127206c3fb27SDimitry Andric (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; 127306c3fb27SDimitry Andric} 127481ad6265SDimitry Andric} // Predicates = [IsLA64] 127581ad6265SDimitry Andric 127681ad6265SDimitry Andricdef : PatGprGpr<and, AND>; 127781ad6265SDimitry Andricdef : PatGprImm<and, ANDI, uimm12>; 127881ad6265SDimitry Andricdef : PatGprGpr<or, OR>; 127981ad6265SDimitry Andricdef : PatGprImm<or, ORI, uimm12>; 128081ad6265SDimitry Andricdef : PatGprGpr<xor, XOR>; 128181ad6265SDimitry Andricdef : PatGprImm<xor, XORI, uimm12>; 1282bdd1243dSDimitry Andricdef : Pat<(not GPR:$rj), (NOR GPR:$rj, R0)>; 1283bdd1243dSDimitry Andricdef : Pat<(not (or GPR:$rj, GPR:$rk)), (NOR GPR:$rj, GPR:$rk)>; 1284bdd1243dSDimitry Andricdef : Pat<(or GPR:$rj, (not GPR:$rk)), (ORN GPR:$rj, GPR:$rk)>; 1285bdd1243dSDimitry Andricdef : Pat<(and GPR:$rj, (not GPR:$rk)), (ANDN GPR:$rj, GPR:$rk)>; 1286bdd1243dSDimitry Andric 12875f757f3fSDimitry Andriclet Predicates = [IsLA32] in { 12885f757f3fSDimitry Andricdef : Pat<(and GPR:$rj, BstrinsImm:$imm), 12895f757f3fSDimitry Andric (BSTRINS_W GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm), 12905f757f3fSDimitry Andric (BstrinsLsb BstrinsImm:$imm))>; 12915f757f3fSDimitry Andric} // Predicates = [IsLA32] 12925f757f3fSDimitry Andric 12935f757f3fSDimitry Andriclet Predicates = [IsLA64] in { 12945f757f3fSDimitry Andricdef : Pat<(and GPR:$rj, BstrinsImm:$imm), 12955f757f3fSDimitry Andric (BSTRINS_D GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm), 12965f757f3fSDimitry Andric (BstrinsLsb BstrinsImm:$imm))>; 12975f757f3fSDimitry Andric} // Predicates = [IsLA64] 12985f757f3fSDimitry Andric 1299bdd1243dSDimitry Andric/// Traps 1300bdd1243dSDimitry Andric 1301bdd1243dSDimitry Andric// We lower `trap` to `amswap.w rd:$r0, rk:$r1, rj:$r0`, as this is guaranteed 1302bdd1243dSDimitry Andric// to trap with an INE (non-existent on LA32, explicitly documented to INE on 1303bdd1243dSDimitry Andric// LA64). And the resulting signal is different from `debugtrap` like on some 1304bdd1243dSDimitry Andric// other existing ports so programs/porters might have an easier time. 1305bdd1243dSDimitry Andricdef PseudoUNIMP : Pseudo<(outs), (ins), [(trap)]>, 1306bdd1243dSDimitry Andric PseudoInstExpansion<(AMSWAP_W R0, R1, R0)>; 1307bdd1243dSDimitry Andric 1308bdd1243dSDimitry Andric// We lower `debugtrap` to `break 0`, as this is guaranteed to exist and work, 1309bdd1243dSDimitry Andric// even for LA32 Primary. Also, because so far the ISA does not provide a 1310bdd1243dSDimitry Andric// specific trap instruction/kind exclusively for alerting the debugger, 1311bdd1243dSDimitry Andric// every other project uses the generic immediate of 0 for this. 1312bdd1243dSDimitry Andricdef : Pat<(debugtrap), (BREAK 0)>; 1313bdd1243dSDimitry Andric 1314bdd1243dSDimitry Andric/// Bit counting operations 1315bdd1243dSDimitry Andric 1316bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1317bdd1243dSDimitry Andricdef : PatGpr<ctlz, CLZ_D>; 1318bdd1243dSDimitry Andricdef : PatGpr<cttz, CTZ_D>; 1319bdd1243dSDimitry Andricdef : Pat<(ctlz (not GPR:$rj)), (CLO_D GPR:$rj)>; 1320bdd1243dSDimitry Andricdef : Pat<(cttz (not GPR:$rj)), (CTO_D GPR:$rj)>; 1321bdd1243dSDimitry Andricdef : PatGpr<loongarch_clzw, CLZ_W>; 1322bdd1243dSDimitry Andricdef : PatGpr<loongarch_ctzw, CTZ_W>; 1323bdd1243dSDimitry Andricdef : Pat<(loongarch_clzw (not GPR:$rj)), (CLO_W GPR:$rj)>; 1324bdd1243dSDimitry Andricdef : Pat<(loongarch_ctzw (not GPR:$rj)), (CTO_W GPR:$rj)>; 1325bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1326bdd1243dSDimitry Andric 1327bdd1243dSDimitry Andriclet Predicates = [IsLA32] in { 1328bdd1243dSDimitry Andricdef : PatGpr<ctlz, CLZ_W>; 1329bdd1243dSDimitry Andricdef : PatGpr<cttz, CTZ_W>; 1330bdd1243dSDimitry Andricdef : Pat<(ctlz (not GPR:$rj)), (CLO_W GPR:$rj)>; 1331bdd1243dSDimitry Andricdef : Pat<(cttz (not GPR:$rj)), (CTO_W GPR:$rj)>; 1332bdd1243dSDimitry Andric} // Predicates = [IsLA32] 1333bdd1243dSDimitry Andric 1334bdd1243dSDimitry Andric/// FrameIndex calculations 1335bdd1243dSDimitry Andriclet Predicates = [IsLA32] in { 1336bdd1243dSDimitry Andricdef : Pat<(AddLike (i32 BaseAddr:$rj), simm12:$imm12), 1337bdd1243dSDimitry Andric (ADDI_W (i32 BaseAddr:$rj), simm12:$imm12)>; 1338bdd1243dSDimitry Andric} // Predicates = [IsLA32] 1339bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1340bdd1243dSDimitry Andricdef : Pat<(AddLike (i64 BaseAddr:$rj), simm12:$imm12), 1341bdd1243dSDimitry Andric (ADDI_D (i64 BaseAddr:$rj), simm12:$imm12)>; 1342bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1343bdd1243dSDimitry Andric 1344bdd1243dSDimitry Andric/// Shifted addition 1345bdd1243dSDimitry Andriclet Predicates = [IsLA32] in { 1346bdd1243dSDimitry Andricdef : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), 1347bdd1243dSDimitry Andric (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; 1348bdd1243dSDimitry Andric} // Predicates = [IsLA32] 1349bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1350bdd1243dSDimitry Andricdef : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), 1351bdd1243dSDimitry Andric (ALSL_D GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; 135206c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), i32), 135306c3fb27SDimitry Andric (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; 1354bdd1243dSDimitry Andricdef : Pat<(loongarch_bstrpick (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), 1355bdd1243dSDimitry Andric (i64 31), (i64 0)), 1356bdd1243dSDimitry Andric (ALSL_WU GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; 1357bdd1243dSDimitry Andric} // Predicates = [IsLA64] 135881ad6265SDimitry Andric 135981ad6265SDimitry Andric/// Shift 136081ad6265SDimitry Andric 136181ad6265SDimitry Andriclet Predicates = [IsLA32] in { 136281ad6265SDimitry Andricdef : PatGprGpr<shiftop<shl>, SLL_W>; 136381ad6265SDimitry Andricdef : PatGprGpr<shiftop<sra>, SRA_W>; 136481ad6265SDimitry Andricdef : PatGprGpr<shiftop<srl>, SRL_W>; 136581ad6265SDimitry Andricdef : PatGprImm<shl, SLLI_W, uimm5>; 136681ad6265SDimitry Andricdef : PatGprImm<sra, SRAI_W, uimm5>; 136781ad6265SDimitry Andricdef : PatGprImm<srl, SRLI_W, uimm5>; 136881ad6265SDimitry Andric} // Predicates = [IsLA32] 136981ad6265SDimitry Andric 137081ad6265SDimitry Andriclet Predicates = [IsLA64] in { 137181ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_sll_w>, SLL_W>; 137281ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_sra_w>, SRA_W>; 137381ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_srl_w>, SRL_W>; 137481ad6265SDimitry Andricdef : PatGprGpr<shiftop<shl>, SLL_D>; 137581ad6265SDimitry Andricdef : PatGprGpr<shiftop<sra>, SRA_D>; 137681ad6265SDimitry Andricdef : PatGprGpr<shiftop<srl>, SRL_D>; 137781ad6265SDimitry Andricdef : PatGprImm<shl, SLLI_D, uimm6>; 137881ad6265SDimitry Andricdef : PatGprImm<sra, SRAI_D, uimm6>; 137981ad6265SDimitry Andricdef : PatGprImm<srl, SRLI_D, uimm6>; 138081ad6265SDimitry Andric} // Predicates = [IsLA64] 138181ad6265SDimitry Andric 138281ad6265SDimitry Andric/// sext and zext 138381ad6265SDimitry Andric 138481ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i8), (EXT_W_B GPR:$rj)>; 138581ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i16), (EXT_W_H GPR:$rj)>; 138681ad6265SDimitry Andric 138781ad6265SDimitry Andriclet Predicates = [IsLA64] in { 138881ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>; 138981ad6265SDimitry Andric} // Predicates = [IsLA64] 139081ad6265SDimitry Andric 139181ad6265SDimitry Andric/// Setcc 139281ad6265SDimitry Andric 139381ad6265SDimitry Andricdef : PatGprGpr<setlt, SLT>; 139481ad6265SDimitry Andricdef : PatGprImm<setlt, SLTI, simm12>; 139581ad6265SDimitry Andricdef : PatGprGpr<setult, SLTU>; 139681ad6265SDimitry Andricdef : PatGprImm<setult, SLTUI, simm12>; 139781ad6265SDimitry Andric 139881ad6265SDimitry Andric// Define pattern expansions for setcc operations that aren't directly 139981ad6265SDimitry Andric// handled by a LoongArch instruction. 140081ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, 0), (SLTUI GPR:$rj, 1)>; 140181ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, GPR:$rk), (SLTUI (XOR GPR:$rj, GPR:$rk), 1)>; 140281ad6265SDimitry Andriclet Predicates = [IsLA32] in { 140381ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), 140481ad6265SDimitry Andric (SLTUI (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; 140581ad6265SDimitry Andric} // Predicates = [IsLA32] 140681ad6265SDimitry Andriclet Predicates = [IsLA64] in { 140781ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), 140881ad6265SDimitry Andric (SLTUI (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; 140981ad6265SDimitry Andric} // Predicates = [IsLA64] 141081ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, 0), (SLTU R0, GPR:$rj)>; 141181ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, GPR:$rk), (SLTU R0, (XOR GPR:$rj, GPR:$rk))>; 141281ad6265SDimitry Andriclet Predicates = [IsLA32] in { 141381ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, simm12_plus1:$imm12), 141481ad6265SDimitry Andric (SLTU R0, (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)))>; 141581ad6265SDimitry Andric} // Predicates = [IsLA32] 141681ad6265SDimitry Andriclet Predicates = [IsLA64] in { 141781ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, simm12_plus1:$imm12), 141881ad6265SDimitry Andric (SLTU R0, (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)))>; 141981ad6265SDimitry Andric} // Predicates = [IsLA64] 142081ad6265SDimitry Andricdef : Pat<(setugt GPR:$rj, GPR:$rk), (SLTU GPR:$rk, GPR:$rj)>; 142181ad6265SDimitry Andricdef : Pat<(setuge GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rj, GPR:$rk), 1)>; 142281ad6265SDimitry Andricdef : Pat<(setule GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rk, GPR:$rj), 1)>; 142381ad6265SDimitry Andricdef : Pat<(setgt GPR:$rj, GPR:$rk), (SLT GPR:$rk, GPR:$rj)>; 142481ad6265SDimitry Andricdef : Pat<(setge GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rj, GPR:$rk), 1)>; 142581ad6265SDimitry Andricdef : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>; 142681ad6265SDimitry Andric 142781ad6265SDimitry Andric/// Select 142881ad6265SDimitry Andric 142906c3fb27SDimitry Andricdef : Pat<(select GPR:$cond, GPR:$t, 0), (MASKEQZ GPR:$t, GPR:$cond)>; 143006c3fb27SDimitry Andricdef : Pat<(select GPR:$cond, 0, GPR:$f), (MASKNEZ GPR:$f, GPR:$cond)>; 143181ad6265SDimitry Andricdef : Pat<(select GPR:$cond, GPR:$t, GPR:$f), 143281ad6265SDimitry Andric (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>; 143381ad6265SDimitry Andric 143481ad6265SDimitry Andric/// Branches and jumps 143581ad6265SDimitry Andric 1436753f127fSDimitry Andricclass BccPat<PatFrag CondOp, LAInst Inst> 1437753f127fSDimitry Andric : Pat<(brcond (GRLenVT (CondOp GPR:$rj, GPR:$rd)), bb:$imm16), 1438753f127fSDimitry Andric (Inst GPR:$rj, GPR:$rd, bb:$imm16)>; 1439753f127fSDimitry Andric 1440753f127fSDimitry Andricdef : BccPat<seteq, BEQ>; 1441753f127fSDimitry Andricdef : BccPat<setne, BNE>; 1442753f127fSDimitry Andricdef : BccPat<setlt, BLT>; 1443753f127fSDimitry Andricdef : BccPat<setge, BGE>; 1444753f127fSDimitry Andricdef : BccPat<setult, BLTU>; 1445753f127fSDimitry Andricdef : BccPat<setuge, BGEU>; 1446753f127fSDimitry Andric 1447753f127fSDimitry Andricclass BccSwapPat<PatFrag CondOp, LAInst InstBcc> 1448753f127fSDimitry Andric : Pat<(brcond (GRLenVT (CondOp GPR:$rd, GPR:$rj)), bb:$imm16), 1449753f127fSDimitry Andric (InstBcc GPR:$rj, GPR:$rd, bb:$imm16)>; 1450753f127fSDimitry Andric 1451753f127fSDimitry Andric// Condition codes that don't have matching LoongArch branch instructions, but 1452753f127fSDimitry Andric// are trivially supported by swapping the two input operands. 1453753f127fSDimitry Andricdef : BccSwapPat<setgt, BLT>; 1454753f127fSDimitry Andricdef : BccSwapPat<setle, BGE>; 1455753f127fSDimitry Andricdef : BccSwapPat<setugt, BLTU>; 1456753f127fSDimitry Andricdef : BccSwapPat<setule, BGEU>; 1457753f127fSDimitry Andric 1458753f127fSDimitry Andric// An extra pattern is needed for a brcond without a setcc (i.e. where the 1459753f127fSDimitry Andric// condition was calculated elsewhere). 1460753f127fSDimitry Andricdef : Pat<(brcond GPR:$rj, bb:$imm21), (BNEZ GPR:$rj, bb:$imm21)>; 1461753f127fSDimitry Andric 1462bdd1243dSDimitry Andricdef : Pat<(brcond (GRLenVT (seteq GPR:$rj, 0)), bb:$imm21), 1463bdd1243dSDimitry Andric (BEQZ GPR:$rj, bb:$imm21)>; 1464bdd1243dSDimitry Andricdef : Pat<(brcond (GRLenVT (setne GPR:$rj, 0)), bb:$imm21), 1465bdd1243dSDimitry Andric (BNEZ GPR:$rj, bb:$imm21)>; 1466bdd1243dSDimitry Andric 1467753f127fSDimitry Andriclet isBarrier = 1, isBranch = 1, isTerminator = 1 in 1468bdd1243dSDimitry Andricdef PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>, 1469bdd1243dSDimitry Andric PseudoInstExpansion<(B simm26_b:$imm26)>; 1470753f127fSDimitry Andric 1471753f127fSDimitry Andriclet isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in 1472bdd1243dSDimitry Andricdef PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, 1473753f127fSDimitry Andric PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>; 1474753f127fSDimitry Andric 1475753f127fSDimitry Andricdef : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>; 1476753f127fSDimitry Andricdef : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)), 1477753f127fSDimitry Andric (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; 1478753f127fSDimitry Andric 14791db9f3b2SDimitry Andric// Function call with 'Small' code model. 1480753f127fSDimitry Andriclet isCall = 1, Defs = [R1] in 14811db9f3b2SDimitry Andricdef PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>; 1482753f127fSDimitry Andric 1483753f127fSDimitry Andricdef : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; 1484753f127fSDimitry Andricdef : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; 1485753f127fSDimitry Andric 14861db9f3b2SDimitry Andric// Function call with 'Medium' code model. 14871db9f3b2SDimitry Andriclet isCall = 1, Defs = [R1, R20], Size = 8 in 14881db9f3b2SDimitry Andricdef PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>; 14891db9f3b2SDimitry Andric 14901db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 14911db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium tglobaladdr:$func), 14921db9f3b2SDimitry Andric (PseudoCALL_MEDIUM tglobaladdr:$func)>; 14931db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium texternalsym:$func), 14941db9f3b2SDimitry Andric (PseudoCALL_MEDIUM texternalsym:$func)>; 14951db9f3b2SDimitry Andric} // Predicates = [IsLA64] 14961db9f3b2SDimitry Andric 14971db9f3b2SDimitry Andric// Function call with 'Large' code model. 14981db9f3b2SDimitry Andriclet isCall = 1, Defs = [R1, R20], Size = 24 in 14991db9f3b2SDimitry Andricdef PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>; 15001db9f3b2SDimitry Andric 15011db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 15021db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large tglobaladdr:$func), 15031db9f3b2SDimitry Andric (PseudoCALL_LARGE tglobaladdr:$func)>; 15041db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large texternalsym:$func), 15051db9f3b2SDimitry Andric (PseudoCALL_LARGE texternalsym:$func)>; 15061db9f3b2SDimitry Andric} // Predicates = [IsLA64] 15071db9f3b2SDimitry Andric 1508753f127fSDimitry Andriclet isCall = 1, Defs = [R1] in 1509753f127fSDimitry Andricdef PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj), 1510753f127fSDimitry Andric [(loongarch_call GPR:$rj)]>, 1511753f127fSDimitry Andric PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>; 15121db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 15131db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>; 15141db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>; 15151db9f3b2SDimitry Andric} 1516753f127fSDimitry Andric 151706c3fb27SDimitry Andriclet isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in 1518bdd1243dSDimitry Andricdef PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, 1519bdd1243dSDimitry Andric PseudoInstExpansion<(JIRL R1, GPR:$rj, 1520bdd1243dSDimitry Andric simm16_lsl2:$imm16)>; 1521bdd1243dSDimitry Andric 152281ad6265SDimitry Andriclet isBarrier = 1, isReturn = 1, isTerminator = 1 in 152381ad6265SDimitry Andricdef PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>, 152481ad6265SDimitry Andric PseudoInstExpansion<(JIRL R0, R1, 0)>; 152581ad6265SDimitry Andric 15261db9f3b2SDimitry Andric// Tail call with 'Small' code model. 1527bdd1243dSDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in 15281db9f3b2SDimitry Andricdef PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>; 1529bdd1243dSDimitry Andric 1530bdd1243dSDimitry Andricdef : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)), 1531bdd1243dSDimitry Andric (PseudoTAIL tglobaladdr:$dst)>; 1532bdd1243dSDimitry Andricdef : Pat<(loongarch_tail (iPTR texternalsym:$dst)), 1533bdd1243dSDimitry Andric (PseudoTAIL texternalsym:$dst)>; 1534bdd1243dSDimitry Andric 15351db9f3b2SDimitry Andric// Tail call with 'Medium' code model. 15361db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 15371db9f3b2SDimitry Andric Uses = [R3], Defs = [R20], Size = 8 in 15381db9f3b2SDimitry Andricdef PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>; 15391db9f3b2SDimitry Andric 15401db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 15411db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)), 15421db9f3b2SDimitry Andric (PseudoTAIL_MEDIUM tglobaladdr:$dst)>; 15431db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)), 15441db9f3b2SDimitry Andric (PseudoTAIL_MEDIUM texternalsym:$dst)>; 15451db9f3b2SDimitry Andric} // Predicates = [IsLA64] 15461db9f3b2SDimitry Andric 15471db9f3b2SDimitry Andric// Tail call with 'Large' code model. 15481db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 15491db9f3b2SDimitry Andric Uses = [R3], Defs = [R19, R20], Size = 24 in 15501db9f3b2SDimitry Andricdef PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>; 15511db9f3b2SDimitry Andric 15521db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 15531db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)), 15541db9f3b2SDimitry Andric (PseudoTAIL_LARGE tglobaladdr:$dst)>; 15551db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)), 15561db9f3b2SDimitry Andric (PseudoTAIL_LARGE texternalsym:$dst)>; 15571db9f3b2SDimitry Andric} // Predicates = [IsLA64] 15581db9f3b2SDimitry Andric 1559bdd1243dSDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in 1560bdd1243dSDimitry Andricdef PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj), 1561bdd1243dSDimitry Andric [(loongarch_tail GPRT:$rj)]>, 1562bdd1243dSDimitry Andric PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>; 15631db9f3b2SDimitry Andriclet Predicates = [IsLA64] in { 15641db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>; 15651db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>; 15661db9f3b2SDimitry Andric} 1567bdd1243dSDimitry Andric 156806c3fb27SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 156906c3fb27SDimitry Andric hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in 1570bdd1243dSDimitry Andricdef PseudoB_TAIL : Pseudo<(outs), (ins simm26_b:$imm26)>, 1571bdd1243dSDimitry Andric PseudoInstExpansion<(B simm26_b:$imm26)>; 1572bdd1243dSDimitry Andric 157306c3fb27SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 157406c3fb27SDimitry Andric hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in 1575bdd1243dSDimitry Andricdef PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, 1576bdd1243dSDimitry Andric PseudoInstExpansion<(JIRL R0, GPR:$rj, 1577bdd1243dSDimitry Andric simm16_lsl2:$imm16)>; 1578bdd1243dSDimitry Andric 15791db9f3b2SDimitry Andric/// call36/taill36 macro instructions 15801db9f3b2SDimitry Andriclet isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1, 15811db9f3b2SDimitry Andric Defs = [R1], Size = 8, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in 15821db9f3b2SDimitry Andricdef PseudoCALL36 : Pseudo<(outs), (ins bare_symbol:$dst), [], 15831db9f3b2SDimitry Andric "call36", "$dst">, 15841db9f3b2SDimitry Andric Requires<[IsLA64]>; 15851db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3], 15861db9f3b2SDimitry Andric isCodeGenOnly = 0, isAsmParserOnly = 1, Size = 8, hasSideEffects = 0, 15871db9f3b2SDimitry Andric mayStore = 0, mayLoad = 0 in 15881db9f3b2SDimitry Andricdef PseudoTAIL36 : Pseudo<(outs), (ins GPR:$tmp, bare_symbol:$dst), [], 15891db9f3b2SDimitry Andric "tail36", "$tmp, $dst">, 15901db9f3b2SDimitry Andric Requires<[IsLA64]>; 15911db9f3b2SDimitry Andric 15920fca6ea1SDimitry Andric// This is a special case of the ADD_W/D instruction used to facilitate the use 15930fca6ea1SDimitry Andric// of a fourth operand to emit a relocation on a symbol relating to this 15940fca6ea1SDimitry Andric// instruction. The relocation does not affect any bits of the instruction itself 15950fca6ea1SDimitry Andric// but is used as a hint to the linker. 15960fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in { 15970fca6ea1SDimitry Andricdef PseudoAddTPRel_W : Pseudo<(outs GPR:$rd), 15980fca6ea1SDimitry Andric (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [], 15990fca6ea1SDimitry Andric "add.w", "$rd, $rj, $rk, $sym">, 16000fca6ea1SDimitry Andric Requires<[IsLA32]>; 16010fca6ea1SDimitry Andricdef PseudoAddTPRel_D : Pseudo<(outs GPR:$rd), 16020fca6ea1SDimitry Andric (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [], 16030fca6ea1SDimitry Andric "add.d", "$rd, $rj, $rk, $sym">, 16040fca6ea1SDimitry Andric Requires<[IsLA64]>; 16050fca6ea1SDimitry Andric} 16060fca6ea1SDimitry Andric 1607bdd1243dSDimitry Andric/// Load address (la*) macro instructions. 1608bdd1243dSDimitry Andric 1609bdd1243dSDimitry Andric// Define isCodeGenOnly = 0 to expose them to tablegened assembly parser. 1610bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, 1611bdd1243dSDimitry Andric isAsmParserOnly = 1 in { 1612bdd1243dSDimitry Andricdef PseudoLA_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1613bdd1243dSDimitry Andric "la.abs", "$dst, $src">; 1614bdd1243dSDimitry Andricdef PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst), 1615bdd1243dSDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 1616bdd1243dSDimitry Andric "la.abs", "$dst, $src">; 1617bdd1243dSDimitry Andricdef PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1618bdd1243dSDimitry Andric "la.pcrel", "$dst, $src">; 16190fca6ea1SDimitry Andricdef PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 16200fca6ea1SDimitry Andric "la.tls.ld", "$dst, $src">; 16210fca6ea1SDimitry Andricdef PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 16220fca6ea1SDimitry Andric "la.tls.gd", "$dst, $src">; 16230fca6ea1SDimitry Andriclet Defs = [R20], Size = 20 in { 1624bdd1243dSDimitry Andricdef PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst), 1625bdd1243dSDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 1626bdd1243dSDimitry Andric "la.pcrel", "$dst, $tmp, $src">, 1627bdd1243dSDimitry Andric Requires<[IsLA64]>; 1628bdd1243dSDimitry Andricdef PseudoLA_TLS_LE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1629bdd1243dSDimitry Andric "la.tls.le", "$dst, $src">; 1630bdd1243dSDimitry Andricdef PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst), 1631bdd1243dSDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 1632bdd1243dSDimitry Andric "la.tls.ld", "$dst, $tmp, $src">, 1633bdd1243dSDimitry Andric Requires<[IsLA64]>; 1634bdd1243dSDimitry Andricdef PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst), 1635bdd1243dSDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 1636bdd1243dSDimitry Andric "la.tls.gd", "$dst, $tmp, $src">, 1637bdd1243dSDimitry Andric Requires<[IsLA64]>; 16381db9f3b2SDimitry Andric} // Defs = [R20], Size = 20 1639bdd1243dSDimitry Andric} 16400fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, 16410fca6ea1SDimitry Andric isAsmParserOnly = 1 in { 16420fca6ea1SDimitry Andricdef PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 16430fca6ea1SDimitry Andric "la.got", "$dst, $src">; 16440fca6ea1SDimitry Andricdef PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 16450fca6ea1SDimitry Andric "la.tls.ie", "$dst, $src">; 16460fca6ea1SDimitry Andriclet Defs = [R20], Size = 20 in { 16470fca6ea1SDimitry Andricdef PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst), 16480fca6ea1SDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 16490fca6ea1SDimitry Andric "la.got", "$dst, $tmp, $src">, 16500fca6ea1SDimitry Andric Requires<[IsLA64]>; 16510fca6ea1SDimitry Andricdef PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst), 16520fca6ea1SDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 16530fca6ea1SDimitry Andric "la.tls.ie", "$dst, $tmp, $src">, 16540fca6ea1SDimitry Andric Requires<[IsLA64]>; 16550fca6ea1SDimitry Andric} // Defs = [R20], Size = 20 16560fca6ea1SDimitry Andric} 16570fca6ea1SDimitry Andric 16580fca6ea1SDimitry Andric// Used for expand PseudoLA_TLS_DESC_* instructions. 16590fca6ea1SDimitry Andriclet isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, 16600fca6ea1SDimitry Andric Defs = [R4], Uses = [R4] in 16610fca6ea1SDimitry Andricdef PseudoDESC_CALL : Pseudo<(outs GPR:$rd), (ins GPR:$rj, simm16_lsl2:$imm16)>, 16620fca6ea1SDimitry Andric PseudoInstExpansion<(JIRL GPR:$rd, GPR:$rj, 16630fca6ea1SDimitry Andric simm16_lsl2:$imm16)>; 16640fca6ea1SDimitry Andric 16650fca6ea1SDimitry Andric// TLSDESC 16660fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, 16670fca6ea1SDimitry Andric isAsmParserOnly = 1, Defs = [R1] in { 16680fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), 16690fca6ea1SDimitry Andric [], "la.tls.desc", "$dst, $src">, 16700fca6ea1SDimitry Andric Requires<[IsLA32, HasLaGlobalWithAbs]>; 16710fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_ABS_LARGE : Pseudo<(outs GPR:$dst), 16720fca6ea1SDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 16730fca6ea1SDimitry Andric "la.tls.desc", "$dst, $src">, 16740fca6ea1SDimitry Andric Requires<[IsLA64, HasLaGlobalWithAbs]>; 16750fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_PC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 16760fca6ea1SDimitry Andric "la.tls.desc", "$dst, $src">; 16770fca6ea1SDimitry Andric} 16780fca6ea1SDimitry Andric 16790fca6ea1SDimitry Andriclet isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, 16800fca6ea1SDimitry Andric isCodeGenOnly = 0, isAsmParserOnly = 1, Defs = [R1, R4, R20], Size = 32 in 16810fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_PC_LARGE : Pseudo<(outs GPR:$dst), 16820fca6ea1SDimitry Andric (ins GPR:$tmp, bare_symbol:$src), [], 16830fca6ea1SDimitry Andric "la.tls.desc", "$dst, $tmp, $src">, 16840fca6ea1SDimitry Andric Requires<[IsLA64]>; 1685bdd1243dSDimitry Andric 1686bdd1243dSDimitry Andric// Load address inst alias: "la", "la.global" and "la.local". 1687bdd1243dSDimitry Andric// Default: 1688bdd1243dSDimitry Andric// la = la.global = la.got 1689bdd1243dSDimitry Andric// la.local = la.pcrel 1690bdd1243dSDimitry Andric// With feature "+la-global-with-pcrel": 1691bdd1243dSDimitry Andric// la = la.global = la.pcrel 1692bdd1243dSDimitry Andric// With feature "+la-global-with-abs": 1693bdd1243dSDimitry Andric// la = la.global = la.abs 1694bdd1243dSDimitry Andric// With feature "+la-local-with-abs": 1695bdd1243dSDimitry Andric// la.local = la.abs 1696bdd1243dSDimitry Andric// With features "+la-global-with-pcrel,+la-global-with-abs"(disorder): 1697bdd1243dSDimitry Andric// la = la.global = la.pcrel 1698bdd1243dSDimitry Andric// Note: To keep consistent with gnu-as behavior, the "la" can only have one 1699bdd1243dSDimitry Andric// register operand. 1700bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>; 1701bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src", 1702bdd1243dSDimitry Andric (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>; 1703bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src", 1704bdd1243dSDimitry Andric (PseudoLA_GOT_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; 1705bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $src", 1706bdd1243dSDimitry Andric (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; 1707bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $tmp, $src", 1708bdd1243dSDimitry Andric (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; 1709bdd1243dSDimitry Andric 1710bdd1243dSDimitry Andric// Note: Keep HasLaGlobalWithPcrel before HasLaGlobalWithAbs to ensure 1711bdd1243dSDimitry Andric// "la-global-with-pcrel" takes effect when bose "la-global-with-pcrel" and 1712bdd1243dSDimitry Andric// "la-global-with-abs" are enabled. 1713bdd1243dSDimitry Andriclet Predicates = [HasLaGlobalWithPcrel] in { 1714bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; 1715bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src", 1716bdd1243dSDimitry Andric (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; 1717bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src", 1718bdd1243dSDimitry Andric (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; 1719bdd1243dSDimitry Andric} // Predicates = [HasLaGlobalWithPcrel] 1720bdd1243dSDimitry Andric 1721bdd1243dSDimitry Andriclet Predicates = [HasLaGlobalWithAbs] in { 1722bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; 1723bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src", 1724bdd1243dSDimitry Andric (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; 1725bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src", 1726bdd1243dSDimitry Andric (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; 1727bdd1243dSDimitry Andric} // Predicates = [HasLaGlobalWithAbs] 1728bdd1243dSDimitry Andric 1729bdd1243dSDimitry Andriclet Predicates = [HasLaLocalWithAbs] in { 1730bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $src", 1731bdd1243dSDimitry Andric (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; 1732bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $tmp, $src", 1733bdd1243dSDimitry Andric (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; 1734bdd1243dSDimitry Andric} // Predicates = [HasLaLocalWithAbs] 1735bdd1243dSDimitry Andric 1736753f127fSDimitry Andric/// BSTRINS and BSTRPICK 173781ad6265SDimitry Andric 1738753f127fSDimitry Andriclet Predicates = [IsLA32] in { 1739753f127fSDimitry Andricdef : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd), 1740753f127fSDimitry Andric (BSTRINS_W GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; 174181ad6265SDimitry Andricdef : Pat<(loongarch_bstrpick GPR:$rj, uimm5:$msbd, uimm5:$lsbd), 174281ad6265SDimitry Andric (BSTRPICK_W GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; 1743753f127fSDimitry Andric} // Predicates = [IsLA32] 174481ad6265SDimitry Andric 1745753f127fSDimitry Andriclet Predicates = [IsLA64] in { 1746753f127fSDimitry Andricdef : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 1747753f127fSDimitry Andric (BSTRINS_D GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; 174881ad6265SDimitry Andricdef : Pat<(loongarch_bstrpick GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 174981ad6265SDimitry Andric (BSTRPICK_D GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; 1750753f127fSDimitry Andric} // Predicates = [IsLA64] 1751753f127fSDimitry Andric 1752bdd1243dSDimitry Andric/// Byte-swapping and bit-reversal 1753bdd1243dSDimitry Andric 1754bdd1243dSDimitry Andricdef : Pat<(loongarch_revb_2h GPR:$rj), (REVB_2H GPR:$rj)>; 1755bdd1243dSDimitry Andricdef : Pat<(loongarch_bitrev_4b GPR:$rj), (BITREV_4B GPR:$rj)>; 1756bdd1243dSDimitry Andric 1757bdd1243dSDimitry Andriclet Predicates = [IsLA32] in { 1758bdd1243dSDimitry Andricdef : Pat<(bswap GPR:$rj), (ROTRI_W (REVB_2H GPR:$rj), 16)>; 1759bdd1243dSDimitry Andricdef : Pat<(bitreverse GPR:$rj), (BITREV_W GPR:$rj)>; 1760bdd1243dSDimitry Andricdef : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_4B GPR:$rj)>; 1761bdd1243dSDimitry Andricdef : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_4B GPR:$rj)>; 1762bdd1243dSDimitry Andric} // Predicates = [IsLA32] 1763bdd1243dSDimitry Andric 1764bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1765bdd1243dSDimitry Andricdef : Pat<(loongarch_revb_2w GPR:$rj), (REVB_2W GPR:$rj)>; 1766bdd1243dSDimitry Andricdef : Pat<(bswap GPR:$rj), (REVB_D GPR:$rj)>; 1767bdd1243dSDimitry Andricdef : Pat<(loongarch_bitrev_w GPR:$rj), (BITREV_W GPR:$rj)>; 1768bdd1243dSDimitry Andricdef : Pat<(bitreverse GPR:$rj), (BITREV_D GPR:$rj)>; 1769bdd1243dSDimitry Andricdef : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_8B GPR:$rj)>; 1770bdd1243dSDimitry Andricdef : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_8B GPR:$rj)>; 1771bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1772bdd1243dSDimitry Andric 1773753f127fSDimitry Andric/// Loads 1774753f127fSDimitry Andric 1775753f127fSDimitry Andricmulticlass LdPat<PatFrag LoadOp, LAInst Inst, ValueType vt = GRLenVT> { 1776753f127fSDimitry Andric def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>; 177706c3fb27SDimitry Andric def : Pat<(vt (LoadOp (AddrConstant GPR:$rj, simm12:$imm12))), 177806c3fb27SDimitry Andric (Inst GPR:$rj, simm12:$imm12)>; 1779bdd1243dSDimitry Andric def : Pat<(vt (LoadOp (AddLike BaseAddr:$rj, simm12:$imm12))), 1780753f127fSDimitry Andric (Inst BaseAddr:$rj, simm12:$imm12)>; 1781753f127fSDimitry Andric} 1782753f127fSDimitry Andric 1783753f127fSDimitry Andricdefm : LdPat<sextloadi8, LD_B>; 1784753f127fSDimitry Andricdefm : LdPat<extloadi8, LD_B>; 1785753f127fSDimitry Andricdefm : LdPat<sextloadi16, LD_H>; 1786753f127fSDimitry Andricdefm : LdPat<extloadi16, LD_H>; 1787753f127fSDimitry Andricdefm : LdPat<load, LD_W>, Requires<[IsLA32]>; 1788753f127fSDimitry Andricdefm : LdPat<zextloadi8, LD_BU>; 1789753f127fSDimitry Andricdefm : LdPat<zextloadi16, LD_HU>; 1790753f127fSDimitry Andriclet Predicates = [IsLA64] in { 1791753f127fSDimitry Andricdefm : LdPat<sextloadi32, LD_W, i64>; 1792753f127fSDimitry Andricdefm : LdPat<extloadi32, LD_W, i64>; 1793753f127fSDimitry Andricdefm : LdPat<zextloadi32, LD_WU, i64>; 1794753f127fSDimitry Andricdefm : LdPat<load, LD_D, i64>; 1795753f127fSDimitry Andric} // Predicates = [IsLA64] 1796753f127fSDimitry Andric 1797bdd1243dSDimitry Andric// LA64 register-register-addressed loads 1798bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1799bdd1243dSDimitry Andricclass RegRegLdPat<PatFrag LoadOp, LAInst Inst, ValueType vt> 1800bdd1243dSDimitry Andric : Pat<(vt (LoadOp (add NonFIBaseAddr:$rj, GPR:$rk))), 1801bdd1243dSDimitry Andric (Inst NonFIBaseAddr:$rj, GPR:$rk)>; 1802bdd1243dSDimitry Andric 1803bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi8, LDX_B, i64>; 1804bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi8, LDX_B, i64>; 1805bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi8, LDX_BU, i64>; 1806bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi16, LDX_H, i64>; 1807bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi16, LDX_H, i64>; 1808bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi16, LDX_HU, i64>; 1809bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi32, LDX_W, i64>; 1810bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi32, LDX_W, i64>; 1811bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi32, LDX_WU, i64>; 1812bdd1243dSDimitry Andricdef : RegRegLdPat<load, LDX_D, i64>; 1813bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1814bdd1243dSDimitry Andric 1815753f127fSDimitry Andric/// Stores 1816753f127fSDimitry Andric 1817753f127fSDimitry Andricmulticlass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy, 1818753f127fSDimitry Andric ValueType vt> { 1819753f127fSDimitry Andric def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj), 1820753f127fSDimitry Andric (Inst StTy:$rd, BaseAddr:$rj, 0)>; 182106c3fb27SDimitry Andric def : Pat<(StoreOp (vt StTy:$rs2), (AddrConstant GPR:$rj, simm12:$imm12)), 182206c3fb27SDimitry Andric (Inst StTy:$rs2, GPR:$rj, simm12:$imm12)>; 1823bdd1243dSDimitry Andric def : Pat<(StoreOp (vt StTy:$rd), (AddLike BaseAddr:$rj, simm12:$imm12)), 1824753f127fSDimitry Andric (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>; 1825753f127fSDimitry Andric} 1826753f127fSDimitry Andric 1827753f127fSDimitry Andricdefm : StPat<truncstorei8, ST_B, GPR, GRLenVT>; 1828753f127fSDimitry Andricdefm : StPat<truncstorei16, ST_H, GPR, GRLenVT>; 1829753f127fSDimitry Andricdefm : StPat<store, ST_W, GPR, i32>, Requires<[IsLA32]>; 1830753f127fSDimitry Andriclet Predicates = [IsLA64] in { 1831753f127fSDimitry Andricdefm : StPat<truncstorei32, ST_W, GPR, i64>; 1832753f127fSDimitry Andricdefm : StPat<store, ST_D, GPR, i64>; 1833753f127fSDimitry Andric} // Predicates = [IsLA64] 1834753f127fSDimitry Andric 1835bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1836bdd1243dSDimitry Andricdef : Pat<(i64 (sextloadi32 (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))), 1837bdd1243dSDimitry Andric (LDPTR_W BaseAddr:$rj, simm14_lsl2:$imm14)>; 1838bdd1243dSDimitry Andricdef : Pat<(i64 (load (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))), 1839bdd1243dSDimitry Andric (LDPTR_D BaseAddr:$rj, simm14_lsl2:$imm14)>; 1840bdd1243dSDimitry Andricdef : Pat<(truncstorei32 (i64 GPR:$rd), 1841bdd1243dSDimitry Andric (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)), 1842bdd1243dSDimitry Andric (STPTR_W GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>; 1843bdd1243dSDimitry Andricdef : Pat<(store (i64 GPR:$rd), (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)), 1844bdd1243dSDimitry Andric (STPTR_D GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>; 1845bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1846bdd1243dSDimitry Andric 1847bdd1243dSDimitry Andric// LA64 register-register-addressed stores 1848bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 1849bdd1243dSDimitry Andricclass RegRegStPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy, 1850bdd1243dSDimitry Andric ValueType vt> 1851bdd1243dSDimitry Andric : Pat<(StoreOp (vt StTy:$rd), (add NonFIBaseAddr:$rj, GPR:$rk)), 1852bdd1243dSDimitry Andric (Inst StTy:$rd, NonFIBaseAddr:$rj, GPR:$rk)>; 1853bdd1243dSDimitry Andric 1854bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei8, STX_B, GPR, i64>; 1855bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei16, STX_H, GPR, i64>; 1856bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei32, STX_W, GPR, i64>; 1857bdd1243dSDimitry Andricdef : RegRegStPat<store, STX_D, GPR, i64>; 1858bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1859bdd1243dSDimitry Andric 1860753f127fSDimitry Andric/// Atomic loads and stores 1861753f127fSDimitry Andric 18625f757f3fSDimitry Andric// DBAR hint encoding for LA664 and later micro-architectures, paraphrased from 18635f757f3fSDimitry Andric// the Linux patch revealing it [1]: 18645f757f3fSDimitry Andric// 18655f757f3fSDimitry Andric// - Bit 4: kind of constraint (0: completion, 1: ordering) 18665f757f3fSDimitry Andric// - Bit 3: barrier for previous read (0: true, 1: false) 18675f757f3fSDimitry Andric// - Bit 2: barrier for previous write (0: true, 1: false) 18685f757f3fSDimitry Andric// - Bit 1: barrier for succeeding read (0: true, 1: false) 18695f757f3fSDimitry Andric// - Bit 0: barrier for succeeding write (0: true, 1: false) 18705f757f3fSDimitry Andric// 18715f757f3fSDimitry Andric// Hint 0x700: barrier for "read after read" from the same address, which is 18725f757f3fSDimitry Andric// e.g. needed by LL-SC loops on older models. (DBAR 0x700 behaves the same as 18735f757f3fSDimitry Andric// nop if such reordering is disabled on supporting newer models.) 18745f757f3fSDimitry Andric// 18755f757f3fSDimitry Andric// [1]: https://lore.kernel.org/loongarch/20230516124536.535343-1-chenhuacai@loongson.cn/ 18765f757f3fSDimitry Andric// 18775f757f3fSDimitry Andric// Implementations without support for the finer-granularity hints simply treat 18785f757f3fSDimitry Andric// all as the full barrier (DBAR 0), so we can unconditionally start emiting the 18795f757f3fSDimitry Andric// more precise hints right away. 18805f757f3fSDimitry Andric 18815f757f3fSDimitry Andricdef : Pat<(atomic_fence 4, timm), (DBAR 0b10100)>; // acquire 18825f757f3fSDimitry Andricdef : Pat<(atomic_fence 5, timm), (DBAR 0b10010)>; // release 18835f757f3fSDimitry Andricdef : Pat<(atomic_fence 6, timm), (DBAR 0b10000)>; // acqrel 18845f757f3fSDimitry Andricdef : Pat<(atomic_fence 7, timm), (DBAR 0b10000)>; // seqcst 1885753f127fSDimitry Andric 1886753f127fSDimitry Andricdefm : LdPat<atomic_load_8, LD_B>; 1887753f127fSDimitry Andricdefm : LdPat<atomic_load_16, LD_H>; 1888753f127fSDimitry Andricdefm : LdPat<atomic_load_32, LD_W>; 1889753f127fSDimitry Andric 1890bdd1243dSDimitry Andricclass release_seqcst_store<PatFrag base> 18915f757f3fSDimitry Andric : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{ 1892bdd1243dSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 1893bdd1243dSDimitry Andric return isReleaseOrStronger(Ordering); 1894bdd1243dSDimitry Andric}]>; 1895bdd1243dSDimitry Andric 1896bdd1243dSDimitry Andricclass unordered_monotonic_store<PatFrag base> 18975f757f3fSDimitry Andric : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{ 1898bdd1243dSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering(); 1899bdd1243dSDimitry Andric return !isReleaseOrStronger(Ordering); 1900bdd1243dSDimitry Andric}]>; 1901bdd1243dSDimitry Andric 1902bdd1243dSDimitry Andricdef atomic_store_release_seqcst_32 : release_seqcst_store<atomic_store_32>; 1903bdd1243dSDimitry Andricdef atomic_store_release_seqcst_64 : release_seqcst_store<atomic_store_64>; 1904bdd1243dSDimitry Andricdef atomic_store_unordered_monotonic_32 1905bdd1243dSDimitry Andric : unordered_monotonic_store<atomic_store_32>; 1906bdd1243dSDimitry Andricdef atomic_store_unordered_monotonic_64 1907bdd1243dSDimitry Andric : unordered_monotonic_store<atomic_store_64>; 1908bdd1243dSDimitry Andric 19095f757f3fSDimitry Andricdefm : StPat<atomic_store_8, ST_B, GPR, GRLenVT>; 19105f757f3fSDimitry Andricdefm : StPat<atomic_store_16, ST_H, GPR, GRLenVT>; 19115f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i32>, 1912bdd1243dSDimitry Andric Requires<[IsLA32]>; 1913bdd1243dSDimitry Andric 1914bdd1243dSDimitry Andricdef PseudoAtomicStoreW 19155f757f3fSDimitry Andric : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>, 191606c3fb27SDimitry Andric PseudoInstExpansion<(AMSWAP__DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>; 1917bdd1243dSDimitry Andric 1918bdd1243dSDimitry Andricdef : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk), 1919bdd1243dSDimitry Andric (PseudoAtomicStoreW GPR:$rj, GPR:$rk)>; 1920bdd1243dSDimitry Andric 1921753f127fSDimitry Andriclet Predicates = [IsLA64] in { 1922bdd1243dSDimitry Andricdef PseudoAtomicStoreD 19235f757f3fSDimitry Andric : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>, 192406c3fb27SDimitry Andric PseudoInstExpansion<(AMSWAP__DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>; 1925bdd1243dSDimitry Andric 1926bdd1243dSDimitry Andricdef : Pat<(atomic_store_release_seqcst_64 GPR:$rj, GPR:$rk), 1927bdd1243dSDimitry Andric (PseudoAtomicStoreD GPR:$rj, GPR:$rk)>; 1928bdd1243dSDimitry Andric 1929753f127fSDimitry Andricdefm : LdPat<atomic_load_64, LD_D>; 19305f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i64>; 19315f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_64, ST_D, GPR, i64>; 1932bdd1243dSDimitry Andric} // Predicates = [IsLA64] 1933bdd1243dSDimitry Andric 1934bdd1243dSDimitry Andric/// Atomic Ops 1935bdd1243dSDimitry Andric 1936bdd1243dSDimitry Andricclass PseudoMaskedAM 1937bdd1243dSDimitry Andric : Pseudo<(outs GPR:$res, GPR:$scratch), 1938bdd1243dSDimitry Andric (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> { 1939bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 1940bdd1243dSDimitry Andric let mayLoad = 1; 1941bdd1243dSDimitry Andric let mayStore = 1; 1942bdd1243dSDimitry Andric let hasSideEffects = 0; 1943bdd1243dSDimitry Andric let Size = 36; 1944bdd1243dSDimitry Andric} 1945bdd1243dSDimitry Andric 1946bdd1243dSDimitry Andricdef PseudoMaskedAtomicSwap32 : PseudoMaskedAM; 1947bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAM; 1948bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadSub32 : PseudoMaskedAM; 1949bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadNand32 : PseudoMaskedAM; 1950bdd1243dSDimitry Andric 1951bdd1243dSDimitry Andricclass PseudoAM : Pseudo<(outs GPR:$res, GPR:$scratch), 1952bdd1243dSDimitry Andric (ins GPR:$addr, GPR:$incr, grlenimm:$ordering)> { 1953bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 1954bdd1243dSDimitry Andric let mayLoad = 1; 1955bdd1243dSDimitry Andric let mayStore = 1; 1956bdd1243dSDimitry Andric let hasSideEffects = 0; 1957bdd1243dSDimitry Andric let Size = 24; 1958bdd1243dSDimitry Andric} 1959bdd1243dSDimitry Andric 1960bdd1243dSDimitry Andricdef PseudoAtomicSwap32 : PseudoAM; 1961bdd1243dSDimitry Andricdef PseudoAtomicLoadNand32 : PseudoAM; 1962bdd1243dSDimitry Andricdef PseudoAtomicLoadNand64 : PseudoAM; 1963bdd1243dSDimitry Andricdef PseudoAtomicLoadAdd32 : PseudoAM; 1964bdd1243dSDimitry Andricdef PseudoAtomicLoadSub32 : PseudoAM; 1965bdd1243dSDimitry Andricdef PseudoAtomicLoadAnd32 : PseudoAM; 1966bdd1243dSDimitry Andricdef PseudoAtomicLoadOr32 : PseudoAM; 1967bdd1243dSDimitry Andricdef PseudoAtomicLoadXor32 : PseudoAM; 1968bdd1243dSDimitry Andric 1969bdd1243dSDimitry Andricmulticlass PseudoBinPat<string Op, Pseudo BinInst> { 1970bdd1243dSDimitry Andric def : Pat<(!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$incr), 1971bdd1243dSDimitry Andric (BinInst GPR:$addr, GPR:$incr, 2)>; 1972bdd1243dSDimitry Andric def : Pat<(!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$incr), 1973bdd1243dSDimitry Andric (BinInst GPR:$addr, GPR:$incr, 4)>; 1974bdd1243dSDimitry Andric def : Pat<(!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$incr), 1975bdd1243dSDimitry Andric (BinInst GPR:$addr, GPR:$incr, 5)>; 1976bdd1243dSDimitry Andric def : Pat<(!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$incr), 1977bdd1243dSDimitry Andric (BinInst GPR:$addr, GPR:$incr, 6)>; 1978bdd1243dSDimitry Andric def : Pat<(!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$incr), 1979bdd1243dSDimitry Andric (BinInst GPR:$addr, GPR:$incr, 7)>; 1980bdd1243dSDimitry Andric} 1981bdd1243dSDimitry Andric 1982bdd1243dSDimitry Andricclass PseudoMaskedAMUMinUMax 1983bdd1243dSDimitry Andric : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 1984bdd1243dSDimitry Andric (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> { 1985bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 1986bdd1243dSDimitry Andric "@earlyclobber $scratch2"; 1987bdd1243dSDimitry Andric let mayLoad = 1; 1988bdd1243dSDimitry Andric let mayStore = 1; 1989bdd1243dSDimitry Andric let hasSideEffects = 0; 1990bdd1243dSDimitry Andric let Size = 48; 1991bdd1243dSDimitry Andric} 1992bdd1243dSDimitry Andric 1993bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMUMinUMax; 1994bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMUMinUMax; 1995bdd1243dSDimitry Andric 1996bdd1243dSDimitry Andricclass PseudoMaskedAMMinMax 1997bdd1243dSDimitry Andric : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), 1998bdd1243dSDimitry Andric (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$sextshamt, 1999bdd1243dSDimitry Andric grlenimm:$ordering)> { 2000bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," 2001bdd1243dSDimitry Andric "@earlyclobber $scratch2"; 2002bdd1243dSDimitry Andric let mayLoad = 1; 2003bdd1243dSDimitry Andric let mayStore = 1; 2004bdd1243dSDimitry Andric let hasSideEffects = 0; 2005bdd1243dSDimitry Andric let Size = 56; 2006bdd1243dSDimitry Andric} 2007bdd1243dSDimitry Andric 2008bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMMinMax; 2009bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax; 2010bdd1243dSDimitry Andric 2011bdd1243dSDimitry Andric/// Compare and exchange 2012bdd1243dSDimitry Andric 2013bdd1243dSDimitry Andricclass PseudoCmpXchg 2014bdd1243dSDimitry Andric : Pseudo<(outs GPR:$res, GPR:$scratch), 20155f757f3fSDimitry Andric (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order)> { 2016bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 2017bdd1243dSDimitry Andric let mayLoad = 1; 2018bdd1243dSDimitry Andric let mayStore = 1; 2019bdd1243dSDimitry Andric let hasSideEffects = 0; 2020bdd1243dSDimitry Andric let Size = 36; 2021bdd1243dSDimitry Andric} 2022bdd1243dSDimitry Andric 2023bdd1243dSDimitry Andricdef PseudoCmpXchg32 : PseudoCmpXchg; 2024bdd1243dSDimitry Andricdef PseudoCmpXchg64 : PseudoCmpXchg; 2025bdd1243dSDimitry Andric 2026bdd1243dSDimitry Andricdef PseudoMaskedCmpXchg32 2027bdd1243dSDimitry Andric : Pseudo<(outs GPR:$res, GPR:$scratch), 2028bdd1243dSDimitry Andric (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, 20295f757f3fSDimitry Andric grlenimm:$fail_order)> { 2030bdd1243dSDimitry Andric let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; 2031bdd1243dSDimitry Andric let mayLoad = 1; 2032bdd1243dSDimitry Andric let mayStore = 1; 2033bdd1243dSDimitry Andric let hasSideEffects = 0; 2034bdd1243dSDimitry Andric let Size = 44; 2035bdd1243dSDimitry Andric} 2036bdd1243dSDimitry Andric 2037bdd1243dSDimitry Andricclass PseudoMaskedAMMinMaxPat<Intrinsic intrin, Pseudo AMInst> 2038bdd1243dSDimitry Andric : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 2039bdd1243dSDimitry Andric timm:$ordering), 2040bdd1243dSDimitry Andric (AMInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, 2041bdd1243dSDimitry Andric timm:$ordering)>; 2042bdd1243dSDimitry Andric 2043bdd1243dSDimitry Andricclass AtomicPat<Intrinsic intrin, Pseudo AMInst> 2044bdd1243dSDimitry Andric : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering), 2045bdd1243dSDimitry Andric (AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>; 2046bdd1243dSDimitry Andric 20475f757f3fSDimitry Andric// These atomic cmpxchg PatFrags only care about the failure ordering. 20485f757f3fSDimitry Andric// The PatFrags defined by multiclass `ternary_atomic_op_ord` in 20495f757f3fSDimitry Andric// TargetSelectionDAG.td care about the merged memory ordering that is the 20505f757f3fSDimitry Andric// stronger one between success and failure. But for LoongArch LL-SC we only 20515f757f3fSDimitry Andric// need to care about the failure ordering as explained in PR #67391. So we 20525f757f3fSDimitry Andric// define these PatFrags that will be used to define cmpxchg pats below. 20535f757f3fSDimitry Andricmulticlass ternary_atomic_op_failure_ord { 20545f757f3fSDimitry Andric def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 20555f757f3fSDimitry Andric (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{ 20565f757f3fSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering(); 20575f757f3fSDimitry Andric return Ordering == AtomicOrdering::Monotonic; 20585f757f3fSDimitry Andric }]>; 20595f757f3fSDimitry Andric def NAME#_failure_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 20605f757f3fSDimitry Andric (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{ 20615f757f3fSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering(); 20625f757f3fSDimitry Andric return Ordering == AtomicOrdering::Acquire; 20635f757f3fSDimitry Andric }]>; 20645f757f3fSDimitry Andric def NAME#_failure_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 20655f757f3fSDimitry Andric (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{ 20665f757f3fSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering(); 20675f757f3fSDimitry Andric return Ordering == AtomicOrdering::Release; 20685f757f3fSDimitry Andric }]>; 20695f757f3fSDimitry Andric def NAME#_failure_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 20705f757f3fSDimitry Andric (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{ 20715f757f3fSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering(); 20725f757f3fSDimitry Andric return Ordering == AtomicOrdering::AcquireRelease; 20735f757f3fSDimitry Andric }]>; 20745f757f3fSDimitry Andric def NAME#_failure_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 20755f757f3fSDimitry Andric (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{ 20765f757f3fSDimitry Andric AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering(); 20775f757f3fSDimitry Andric return Ordering == AtomicOrdering::SequentiallyConsistent; 20785f757f3fSDimitry Andric }]>; 20795f757f3fSDimitry Andric} 20805f757f3fSDimitry Andric 20810fca6ea1SDimitry Andricdefm atomic_cmp_swap_i32 : ternary_atomic_op_failure_ord; 20820fca6ea1SDimitry Andricdefm atomic_cmp_swap_i64 : ternary_atomic_op_failure_ord; 20835f757f3fSDimitry Andric 2084bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 2085bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64, 2086bdd1243dSDimitry Andric PseudoMaskedAtomicSwap32>; 20870fca6ea1SDimitry Andricdef : Pat<(atomic_swap_i32 GPR:$addr, GPR:$incr), 208806c3fb27SDimitry Andric (AMSWAP__DB_W GPR:$incr, GPR:$addr)>; 20890fca6ea1SDimitry Andricdef : Pat<(atomic_swap_i64 GPR:$addr, GPR:$incr), 209006c3fb27SDimitry Andric (AMSWAP__DB_D GPR:$incr, GPR:$addr)>; 20910fca6ea1SDimitry Andricdef : Pat<(atomic_load_add_i64 GPR:$rj, GPR:$rk), 209206c3fb27SDimitry Andric (AMADD__DB_D GPR:$rk, GPR:$rj)>; 2093bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_add_i64, 2094bdd1243dSDimitry Andric PseudoMaskedAtomicLoadAdd32>; 20950fca6ea1SDimitry Andricdef : Pat<(atomic_load_sub_i32 GPR:$rj, GPR:$rk), 209606c3fb27SDimitry Andric (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>; 20970fca6ea1SDimitry Andricdef : Pat<(atomic_load_sub_i64 GPR:$rj, GPR:$rk), 209806c3fb27SDimitry Andric (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>; 2099bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_sub_i64, 2100bdd1243dSDimitry Andric PseudoMaskedAtomicLoadSub32>; 21010fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_nand_i64", PseudoAtomicLoadNand64>; 2102bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_nand_i64, 2103bdd1243dSDimitry Andric PseudoMaskedAtomicLoadNand32>; 21040fca6ea1SDimitry Andricdef : Pat<(atomic_load_add_i32 GPR:$rj, GPR:$rk), 210506c3fb27SDimitry Andric (AMADD__DB_W GPR:$rk, GPR:$rj)>; 21060fca6ea1SDimitry Andricdef : Pat<(atomic_load_and_i32 GPR:$rj, GPR:$rk), 210706c3fb27SDimitry Andric (AMAND__DB_W GPR:$rk, GPR:$rj)>; 21080fca6ea1SDimitry Andricdef : Pat<(atomic_load_and_i64 GPR:$rj, GPR:$rk), 210906c3fb27SDimitry Andric (AMAND__DB_D GPR:$rk, GPR:$rj)>; 21100fca6ea1SDimitry Andricdef : Pat<(atomic_load_or_i32 GPR:$rj, GPR:$rk), 211106c3fb27SDimitry Andric (AMOR__DB_W GPR:$rk, GPR:$rj)>; 21120fca6ea1SDimitry Andricdef : Pat<(atomic_load_or_i64 GPR:$rj, GPR:$rk), 211306c3fb27SDimitry Andric (AMOR__DB_D GPR:$rk, GPR:$rj)>; 21140fca6ea1SDimitry Andricdef : Pat<(atomic_load_xor_i32 GPR:$rj, GPR:$rk), 211506c3fb27SDimitry Andric (AMXOR__DB_W GPR:$rk, GPR:$rj)>; 21160fca6ea1SDimitry Andricdef : Pat<(atomic_load_xor_i64 GPR:$rj, GPR:$rk), 211706c3fb27SDimitry Andric (AMXOR__DB_D GPR:$rk, GPR:$rj)>; 2118bdd1243dSDimitry Andric 21190fca6ea1SDimitry Andricdef : Pat<(atomic_load_umin_i32 GPR:$rj, GPR:$rk), 212006c3fb27SDimitry Andric (AMMIN__DB_WU GPR:$rk, GPR:$rj)>; 21210fca6ea1SDimitry Andricdef : Pat<(atomic_load_umin_i64 GPR:$rj, GPR:$rk), 212206c3fb27SDimitry Andric (AMMIN__DB_DU GPR:$rk, GPR:$rj)>; 21230fca6ea1SDimitry Andricdef : Pat<(atomic_load_umax_i32 GPR:$rj, GPR:$rk), 212406c3fb27SDimitry Andric (AMMAX__DB_WU GPR:$rk, GPR:$rj)>; 21250fca6ea1SDimitry Andricdef : Pat<(atomic_load_umax_i64 GPR:$rj, GPR:$rk), 212606c3fb27SDimitry Andric (AMMAX__DB_DU GPR:$rk, GPR:$rj)>; 2127bdd1243dSDimitry Andric 21280fca6ea1SDimitry Andricdef : Pat<(atomic_load_min_i32 GPR:$rj, GPR:$rk), 212906c3fb27SDimitry Andric (AMMIN__DB_W GPR:$rk, GPR:$rj)>; 21300fca6ea1SDimitry Andricdef : Pat<(atomic_load_min_i64 GPR:$rj, GPR:$rk), 213106c3fb27SDimitry Andric (AMMIN__DB_D GPR:$rk, GPR:$rj)>; 21320fca6ea1SDimitry Andricdef : Pat<(atomic_load_max_i32 GPR:$rj, GPR:$rk), 213306c3fb27SDimitry Andric (AMMAX__DB_W GPR:$rk, GPR:$rj)>; 21340fca6ea1SDimitry Andricdef : Pat<(atomic_load_max_i64 GPR:$rj, GPR:$rk), 213506c3fb27SDimitry Andric (AMMAX__DB_D GPR:$rk, GPR:$rj)>; 2136bdd1243dSDimitry Andric 2137bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_umax_i64, 2138bdd1243dSDimitry Andric PseudoMaskedAtomicLoadUMax32>; 2139bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64, 2140bdd1243dSDimitry Andric PseudoMaskedAtomicLoadUMin32>; 2141bdd1243dSDimitry Andric 21425f757f3fSDimitry Andric// Ordering constants must be kept in sync with the AtomicOrdering enum in 21435f757f3fSDimitry Andric// AtomicOrdering.h. 21445f757f3fSDimitry Andricmulticlass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst, 21455f757f3fSDimitry Andric ValueType vt = GRLenVT> { 21465f757f3fSDimitry Andric def : Pat<(vt (!cast<PatFrag>(Op#"_failure_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)), 21475f757f3fSDimitry Andric (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>; 21485f757f3fSDimitry Andric def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acquire") GPR:$addr, GPR:$cmp, GPR:$new)), 21495f757f3fSDimitry Andric (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>; 21505f757f3fSDimitry Andric def : Pat<(vt (!cast<PatFrag>(Op#"_failure_release") GPR:$addr, GPR:$cmp, GPR:$new)), 21515f757f3fSDimitry Andric (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>; 21525f757f3fSDimitry Andric def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)), 21535f757f3fSDimitry Andric (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>; 21545f757f3fSDimitry Andric def : Pat<(vt (!cast<PatFrag>(Op#"_failure_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)), 21555f757f3fSDimitry Andric (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>; 21565f757f3fSDimitry Andric} 21575f757f3fSDimitry Andric 21580fca6ea1SDimitry Andricdefm : PseudoCmpXchgPat<"atomic_cmp_swap_i32", PseudoCmpXchg32>; 21590fca6ea1SDimitry Andricdefm : PseudoCmpXchgPat<"atomic_cmp_swap_i64", PseudoCmpXchg64, i64>; 2160bdd1243dSDimitry Andricdef : Pat<(int_loongarch_masked_cmpxchg_i64 21615f757f3fSDimitry Andric GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order), 2162bdd1243dSDimitry Andric (PseudoMaskedCmpXchg32 21635f757f3fSDimitry Andric GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order)>; 2164bdd1243dSDimitry Andric 2165bdd1243dSDimitry Andricdef : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64, 2166bdd1243dSDimitry Andric PseudoMaskedAtomicLoadMax32>; 2167bdd1243dSDimitry Andricdef : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_min_i64, 2168bdd1243dSDimitry Andric PseudoMaskedAtomicLoadMin32>; 2169bdd1243dSDimitry Andric} // Predicates = [IsLA64] 2170bdd1243dSDimitry Andric 21710fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_nand_i32", PseudoAtomicLoadNand32>; 2172bdd1243dSDimitry Andric 2173bdd1243dSDimitry Andriclet Predicates = [IsLA32] in { 2174bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i32, 2175bdd1243dSDimitry Andric PseudoMaskedAtomicSwap32>; 21760fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_swap_i32", PseudoAtomicSwap32>; 2177bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_add_i32, 2178bdd1243dSDimitry Andric PseudoMaskedAtomicLoadAdd32>; 2179bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_sub_i32, 2180bdd1243dSDimitry Andric PseudoMaskedAtomicLoadSub32>; 2181bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_nand_i32, 2182bdd1243dSDimitry Andric PseudoMaskedAtomicLoadNand32>; 21830fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_add_i32", PseudoAtomicLoadAdd32>; 21840fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_sub_i32", PseudoAtomicLoadSub32>; 21850fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_and_i32", PseudoAtomicLoadAnd32>; 21860fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_or_i32", PseudoAtomicLoadOr32>; 21870fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_xor_i32", PseudoAtomicLoadXor32>; 2188bdd1243dSDimitry Andric} // Predicates = [IsLA32] 2189bdd1243dSDimitry Andric 2190bdd1243dSDimitry Andric/// Intrinsics 2191bdd1243dSDimitry Andric 2192bdd1243dSDimitry Andricdef : Pat<(int_loongarch_cacop_d timm:$op, i64:$rj, timm:$imm12), 21935f757f3fSDimitry Andric (CACOP timm:$op, GPR:$rj, timm:$imm12)>; 2194bdd1243dSDimitry Andricdef : Pat<(int_loongarch_cacop_w i32:$op, i32:$rj, i32:$imm12), 21955f757f3fSDimitry Andric (CACOP timm:$op, GPR:$rj, timm:$imm12)>; 2196bdd1243dSDimitry Andricdef : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>; 2197bdd1243dSDimitry Andricdef : Pat<(loongarch_ibar uimm15:$imm15), (IBAR uimm15:$imm15)>; 2198bdd1243dSDimitry Andricdef : Pat<(loongarch_break uimm15:$imm15), (BREAK uimm15:$imm15)>; 2199bdd1243dSDimitry Andricdef : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>; 2200bdd1243dSDimitry Andric 2201bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 2202bdd1243dSDimitry Andric// CRC Check Instructions 2203bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_b_w, CRC_W_B_W>; 2204bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_h_w, CRC_W_H_W>; 2205bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_w_w, CRC_W_W_W>; 2206bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>; 2207bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_b_w, CRCC_W_B_W>; 2208bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_h_w, CRCC_W_H_W>; 2209bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_w_w, CRCC_W_W_W>; 2210bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_d_w, CRCC_W_D_W>; 2211753f127fSDimitry Andric} // Predicates = [IsLA64] 2212753f127fSDimitry Andric 2213753f127fSDimitry Andric/// Other pseudo-instructions 2214753f127fSDimitry Andric 2215753f127fSDimitry Andric// Pessimistically assume the stack pointer will be clobbered 2216753f127fSDimitry Andriclet Defs = [R3], Uses = [R3] in { 2217753f127fSDimitry Andricdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 2218753f127fSDimitry Andric [(callseq_start timm:$amt1, timm:$amt2)]>; 2219753f127fSDimitry Andricdef ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 2220753f127fSDimitry Andric [(callseq_end timm:$amt1, timm:$amt2)]>; 2221753f127fSDimitry Andric} // Defs = [R3], Uses = [R3] 222281ad6265SDimitry Andric 222381ad6265SDimitry Andric//===----------------------------------------------------------------------===// 222481ad6265SDimitry Andric// Assembler Pseudo Instructions 222581ad6265SDimitry Andric//===----------------------------------------------------------------------===// 222681ad6265SDimitry Andric 222781ad6265SDimitry Andricdef : InstAlias<"nop", (ANDI R0, R0, 0)>; 222881ad6265SDimitry Andricdef : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>; 2229bdd1243dSDimitry Andric// `ret` is supported since binutils commit 20f2e2686c79a5ac (version 2.40 and 2230bdd1243dSDimitry Andric// later). 2231bdd1243dSDimitry Andricdef : InstAlias<"ret", (JIRL R0, R1, 0)>; 2232bdd1243dSDimitry Andricdef : InstAlias<"jr $rj", (JIRL R0, GPR:$rj, 0)>; 2233bdd1243dSDimitry Andric 2234bdd1243dSDimitry Andric// Branches implemented with alias. 2235bdd1243dSDimitry Andric// Always output the canonical mnemonic for the pseudo branch instructions. 2236bdd1243dSDimitry Andric// The GNU tools emit the canonical mnemonic for the branch pseudo instructions 2237bdd1243dSDimitry Andric// as well (e.g. "bgt" will be recognised by the assembler but never printed by 2238bdd1243dSDimitry Andric// objdump). Match this behaviour by setting a zero weight. 2239bdd1243dSDimitry Andricdef : InstAlias<"bgt $rj, $rd, $imm16", 2240bdd1243dSDimitry Andric (BLT GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2241bdd1243dSDimitry Andricdef : InstAlias<"bgtu $rj, $rd, $imm16", 2242bdd1243dSDimitry Andric (BLTU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2243bdd1243dSDimitry Andricdef : InstAlias<"ble $rj, $rd, $imm16", 2244bdd1243dSDimitry Andric (BGE GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2245bdd1243dSDimitry Andricdef : InstAlias<"bleu $rj, $rd, $imm16", 2246bdd1243dSDimitry Andric (BGEU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2247bdd1243dSDimitry Andricdef : InstAlias<"bltz $rd, $imm16", 2248bdd1243dSDimitry Andric (BLT GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>; 2249bdd1243dSDimitry Andricdef : InstAlias<"bgtz $rj, $imm16", 2250bdd1243dSDimitry Andric (BLT R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2251bdd1243dSDimitry Andricdef : InstAlias<"blez $rj, $imm16", 2252bdd1243dSDimitry Andric (BGE R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>; 2253bdd1243dSDimitry Andricdef : InstAlias<"bgez $rd, $imm16", 2254bdd1243dSDimitry Andric (BGE GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>; 2255bdd1243dSDimitry Andric 2256bdd1243dSDimitry Andric// Load immediate. 2257bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, 2258bdd1243dSDimitry Andric isAsmParserOnly = 1 in { 2259bdd1243dSDimitry Andricdef PseudoLI_W : Pseudo<(outs GPR:$rd), (ins imm32:$imm), [], 2260bdd1243dSDimitry Andric "li.w", "$rd, $imm">; 22610fca6ea1SDimitry Andricdef PseudoLI_D : Pseudo<(outs GPR:$rd), (ins imm64:$imm), [], 2262bdd1243dSDimitry Andric "li.d", "$rd, $imm">, Requires<[IsLA64]>; 2263bdd1243dSDimitry Andric} 226481ad6265SDimitry Andric 226581ad6265SDimitry Andric//===----------------------------------------------------------------------===// 226681ad6265SDimitry Andric// Basic Floating-Point Instructions 226781ad6265SDimitry Andric//===----------------------------------------------------------------------===// 226881ad6265SDimitry Andric 226981ad6265SDimitry Andricinclude "LoongArchFloat32InstrInfo.td" 227081ad6265SDimitry Andricinclude "LoongArchFloat64InstrInfo.td" 227181ad6265SDimitry Andric 2272bdd1243dSDimitry Andriclet Predicates = [HasBasicF], usesCustomInserter = 1 in { 2273bdd1243dSDimitry Andric def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src), 2274bdd1243dSDimitry Andric [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>; 2275bdd1243dSDimitry Andric def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr), 2276bdd1243dSDimitry Andric [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>; 2277bdd1243dSDimitry Andric} 2278bdd1243dSDimitry Andric 227981ad6265SDimitry Andric//===----------------------------------------------------------------------===// 228081ad6265SDimitry Andric// Privilege Instructions 228181ad6265SDimitry Andric//===----------------------------------------------------------------------===// 228281ad6265SDimitry Andric 228381ad6265SDimitry Andric// CSR Access Instructions 228406c3fb27SDimitry Andriclet hasSideEffects = 1 in 228506c3fb27SDimitry Andricdef CSRRD : FmtCSR<0x04000000, (outs GPR:$rd), (ins uimm14:$csr_num), 228606c3fb27SDimitry Andric "$rd, $csr_num">; 228706c3fb27SDimitry Andriclet hasSideEffects = 1, Constraints = "$rd = $dst" in { 228806c3fb27SDimitry Andricdef CSRWR : FmtCSR<0x04000020, (outs GPR:$dst), 228906c3fb27SDimitry Andric (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">; 229006c3fb27SDimitry Andricdef CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst), 229181ad6265SDimitry Andric (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), 229206c3fb27SDimitry Andric "$rd, $rj, $csr_num">; 229306c3fb27SDimitry Andric} // hasSideEffects = 1, Constraints = "$rd = $dst" 229481ad6265SDimitry Andric 229581ad6265SDimitry Andric// IOCSR Access Instructions 229606c3fb27SDimitry Andricdef IOCSRRD_B : IOCSRRD<0x06480000>; 229706c3fb27SDimitry Andricdef IOCSRRD_H : IOCSRRD<0x06480400>; 229806c3fb27SDimitry Andricdef IOCSRRD_W : IOCSRRD<0x06480800>; 229906c3fb27SDimitry Andricdef IOCSRWR_B : IOCSRWR<0x06481000>; 230006c3fb27SDimitry Andricdef IOCSRWR_H : IOCSRWR<0x06481400>; 230106c3fb27SDimitry Andricdef IOCSRWR_W : IOCSRWR<0x06481800>; 230281ad6265SDimitry Andriclet Predicates = [IsLA64] in { 230306c3fb27SDimitry Andricdef IOCSRRD_D : IOCSRRD<0x06480c00>; 230406c3fb27SDimitry Andricdef IOCSRWR_D : IOCSRWR<0x06481c00>; 230581ad6265SDimitry Andric} // Predicates = [IsLA64] 230681ad6265SDimitry Andric 230781ad6265SDimitry Andric// TLB Maintenance Instructions 230806c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { 230906c3fb27SDimitry Andricdef TLBSRCH : FmtI32<0x06482800>; 231006c3fb27SDimitry Andricdef TLBRD : FmtI32<0x06482c00>; 231106c3fb27SDimitry Andricdef TLBWR : FmtI32<0x06483000>; 231206c3fb27SDimitry Andricdef TLBFILL : FmtI32<0x06483400>; 231306c3fb27SDimitry Andricdef TLBCLR : FmtI32<0x06482000>; 231406c3fb27SDimitry Andricdef TLBFLUSH : FmtI32<0x06482400>; 231506c3fb27SDimitry Andricdef INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), 231681ad6265SDimitry Andric "$op, $rj, $rk">; 231706c3fb27SDimitry Andric} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 231881ad6265SDimitry Andric 231981ad6265SDimitry Andric// Software Page Walking Instructions 232006c3fb27SDimitry Andricdef LDDIR : Fmt2RI8<0x06400000, (outs GPR:$rd), 232106c3fb27SDimitry Andric (ins GPR:$rj, uimm8:$imm8), "$rd, $rj, $imm8">; 232206c3fb27SDimitry Andricdef LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "$rj, $seq">; 232381ad6265SDimitry Andric 232481ad6265SDimitry Andric 232581ad6265SDimitry Andric// Other Miscellaneous Instructions 232606c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 232706c3fb27SDimitry Andricdef ERTN : FmtI32<0x06483800>; 232806c3fb27SDimitry Andricdef DBCL : MISC_I15<0x002a8000>; 232906c3fb27SDimitry Andricdef IDLE : MISC_I15<0x06488000>; 2330bdd1243dSDimitry Andric 2331bdd1243dSDimitry Andric//===----------------------------------------------------------------------===// 2332bdd1243dSDimitry Andric// Privilege Intrinsics 2333bdd1243dSDimitry Andric//===----------------------------------------------------------------------===// 2334bdd1243dSDimitry Andric 2335bdd1243dSDimitry Andricdef : Pat<(loongarch_csrrd uimm14:$imm14), (CSRRD uimm14:$imm14)>; 2336bdd1243dSDimitry Andricdef : Pat<(loongarch_csrwr GPR:$rd, uimm14:$imm14), 2337bdd1243dSDimitry Andric (CSRWR GPR:$rd, uimm14:$imm14)>; 2338bdd1243dSDimitry Andricdef : Pat<(loongarch_csrxchg GPR:$rd, GPR:$rj, uimm14:$imm14), 2339bdd1243dSDimitry Andric (CSRXCHG GPR:$rd, GPR:$rj, uimm14:$imm14)>; 2340bdd1243dSDimitry Andric 2341bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_b GPR:$rj), (IOCSRRD_B GPR:$rj)>; 2342bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_h GPR:$rj), (IOCSRRD_H GPR:$rj)>; 2343bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_w GPR:$rj), (IOCSRRD_W GPR:$rj)>; 2344bdd1243dSDimitry Andric 2345bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_b GPR:$rd, GPR:$rj), (IOCSRWR_B GPR:$rd, GPR:$rj)>; 2346bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_h GPR:$rd, GPR:$rj), (IOCSRWR_H GPR:$rd, GPR:$rj)>; 2347bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_w GPR:$rd, GPR:$rj), (IOCSRWR_W GPR:$rd, GPR:$rj)>; 2348bdd1243dSDimitry Andric 2349bdd1243dSDimitry Andricdef : Pat<(loongarch_cpucfg GPR:$rj), (CPUCFG GPR:$rj)>; 2350bdd1243dSDimitry Andric 2351bdd1243dSDimitry Andriclet Predicates = [IsLA64] in { 2352bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_d GPR:$rj), (IOCSRRD_D GPR:$rj)>; 2353bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_d GPR:$rd, GPR:$rj), (IOCSRWR_D GPR:$rd, GPR:$rj)>; 2354bdd1243dSDimitry Andricdef : Pat<(int_loongarch_asrtle_d GPR:$rj, GPR:$rk), 2355bdd1243dSDimitry Andric (ASRTLE_D GPR:$rj, GPR:$rk)>; 2356bdd1243dSDimitry Andricdef : Pat<(int_loongarch_asrtgt_d GPR:$rj, GPR:$rk), 2357bdd1243dSDimitry Andric (ASRTGT_D GPR:$rj, GPR:$rk)>; 2358bdd1243dSDimitry Andricdef : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8), 23595f757f3fSDimitry Andric (LDDIR GPR:$rj, timm:$imm8)>; 2360bdd1243dSDimitry Andricdef : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8), 23615f757f3fSDimitry Andric (LDPTE GPR:$rj, timm:$imm8)>; 2362bdd1243dSDimitry Andric} // Predicates = [IsLA64] 236306c3fb27SDimitry Andric 236406c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 236506c3fb27SDimitry Andric// LSX Instructions 236606c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 236706c3fb27SDimitry Andricinclude "LoongArchLSXInstrInfo.td" 236806c3fb27SDimitry Andric 236906c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 237006c3fb27SDimitry Andric// LASX Instructions 237106c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 237206c3fb27SDimitry Andricinclude "LoongArchLASXInstrInfo.td" 237306c3fb27SDimitry Andric 237406c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 237506c3fb27SDimitry Andric// LVZ Instructions 237606c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 237706c3fb27SDimitry Andricinclude "LoongArchLVZInstrInfo.td" 237806c3fb27SDimitry Andric 237906c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 238006c3fb27SDimitry Andric// LBT Instructions 238106c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 238206c3fb27SDimitry Andricinclude "LoongArchLBTInstrInfo.td" 2383