1//== LoongArchInstrInfo.td - Target Description for LoongArch -*- tablegen -*-// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the LoongArch instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// LoongArch specific DAG Nodes. 15//===----------------------------------------------------------------------===// 16 17// Target-independent type requirements, but with target-specific formats. 18def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 19 SDTCisVT<1, i32>]>; 20def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 21 SDTCisVT<1, i32>]>; 22 23// Target-dependent type requirements. 24def SDT_LoongArchCall : SDTypeProfile<0, -1, [SDTCisVT<0, GRLenVT>]>; 25def SDT_LoongArchIntBinOpW : SDTypeProfile<1, 2, [ 26 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64> 27]>; 28 29def SDT_LoongArchBStrIns: SDTypeProfile<1, 4, [ 30 SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>, 31 SDTCisSameAs<3, 4> 32]>; 33 34def SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [ 35 SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3> 36]>; 37 38// TODO: Add LoongArch specific DAG Nodes 39// Target-independent nodes, but with target-specific formats. 40def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 41 [SDNPHasChain, SDNPOutGlue]>; 42def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 43 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 44 45// Target-dependent nodes. 46def loongarch_call : SDNode<"LoongArchISD::CALL", SDT_LoongArchCall, 47 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 48 SDNPVariadic]>; 49def loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone, 50 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 51def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>; 52def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>; 53def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>; 54def loongarch_bstrins 55 : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>; 56def loongarch_bstrpick 57 : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>; 58 59//===----------------------------------------------------------------------===// 60// Operand and SDNode transformation definitions. 61//===----------------------------------------------------------------------===// 62 63class ImmAsmOperand<string prefix, int width, string suffix> 64 : AsmOperandClass { 65 let Name = prefix # "Imm" # width # suffix; 66 let DiagnosticType = !strconcat("Invalid", Name); 67 let RenderMethod = "addImmOperands"; 68} 69 70class SImmAsmOperand<int width, string suffix = ""> 71 : ImmAsmOperand<"S", width, suffix> { 72} 73 74class UImmAsmOperand<int width, string suffix = ""> 75 : ImmAsmOperand<"U", width, suffix> { 76} 77 78def uimm2 : Operand<GRLenVT> { 79 let ParserMatchClass = UImmAsmOperand<2>; 80} 81 82def uimm2_plus1 : Operand<GRLenVT> { 83 let ParserMatchClass = UImmAsmOperand<2, "plus1">; 84 let EncoderMethod = "getImmOpValueSub1"; 85 let DecoderMethod = "decodeUImmOperand<2, 1>"; 86} 87 88def uimm3 : Operand<GRLenVT> { 89 let ParserMatchClass = UImmAsmOperand<3>; 90} 91 92def uimm5 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<5>(Imm);}]> { 93 let ParserMatchClass = UImmAsmOperand<5>; 94} 95 96def uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> { 97 let ParserMatchClass = UImmAsmOperand<6>; 98} 99 100def uimm8 : Operand<GRLenVT> { 101 let ParserMatchClass = UImmAsmOperand<8>; 102} 103 104def uimm12 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<12>(Imm);}]> { 105 let ParserMatchClass = UImmAsmOperand<12>; 106} 107 108def uimm14 : Operand<GRLenVT> { 109 let ParserMatchClass = UImmAsmOperand<14>; 110} 111 112def uimm15 : Operand<GRLenVT> { 113 let ParserMatchClass = UImmAsmOperand<15>; 114} 115 116def simm12 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isInt<12>(Imm);}]> { 117 let ParserMatchClass = SImmAsmOperand<12>; 118 let DecoderMethod = "decodeSImmOperand<12>"; 119} 120 121def simm14_lsl2 : Operand<GRLenVT> { 122 let ParserMatchClass = SImmAsmOperand<14, "lsl2">; 123 let EncoderMethod = "getImmOpValueAsr2"; 124 let DecoderMethod = "decodeSImmOperand<14, 2>"; 125} 126 127def simm16 : Operand<GRLenVT> { 128 let ParserMatchClass = SImmAsmOperand<16>; 129 let DecoderMethod = "decodeSImmOperand<16>"; 130} 131 132def simm16_lsl2 : Operand<GRLenVT>, 133 ImmLeaf<GRLenVT, [{return isInt<16>(Imm>>2);}]> { 134 let ParserMatchClass = SImmAsmOperand<16, "lsl2">; 135 let EncoderMethod = "getImmOpValueAsr2"; 136 let DecoderMethod = "decodeSImmOperand<16, 2>"; 137} 138 139def simm16_lsl2_br : Operand<OtherVT> { 140 let ParserMatchClass = SImmAsmOperand<16, "lsl2">; 141 let EncoderMethod = "getImmOpValueAsr2"; 142 let DecoderMethod = "decodeSImmOperand<16, 2>"; 143} 144 145def simm20 : Operand<GRLenVT> { 146 let ParserMatchClass = SImmAsmOperand<20>; 147 let DecoderMethod = "decodeSImmOperand<20>"; 148} 149 150def simm21_lsl2 : Operand<OtherVT> { 151 let ParserMatchClass = SImmAsmOperand<21, "lsl2">; 152 let EncoderMethod = "getImmOpValueAsr2"; 153 let DecoderMethod = "decodeSImmOperand<21, 2>"; 154} 155 156def simm26_lsl2 : Operand<OtherVT> { 157 let ParserMatchClass = SImmAsmOperand<26, "lsl2">; 158 let EncoderMethod = "getImmOpValueAsr2"; 159 let DecoderMethod = "decodeSImmOperand<26, 2>"; 160} 161 162// Standalone (codegen-only) immleaf patterns. 163 164// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048]. 165def simm12_plus1 : ImmLeaf<GRLenVT, 166 [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>; 167 168// Return the negation of an immediate value. 169def NegImm : SDNodeXForm<imm, [{ 170 return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), 171 N->getValueType(0)); 172}]>; 173 174// FP immediate patterns. 175def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; 176def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; 177def fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>; 178 179def CallSymbol: AsmOperandClass { 180 let Name = "CallSymbol"; 181 let RenderMethod = "addImmOperands"; 182 let PredicateMethod = "isImm"; 183} 184 185// A bare symbol used in call only. 186def call_symbol : Operand<iPTR> { 187 let ParserMatchClass = CallSymbol; 188} 189 190def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; 191 192//===----------------------------------------------------------------------===// 193// Instruction Formats 194//===----------------------------------------------------------------------===// 195 196include "LoongArchInstrFormats.td" 197include "LoongArchFloatInstrFormats.td" 198 199//===----------------------------------------------------------------------===// 200// Instruction Class Templates 201//===----------------------------------------------------------------------===// 202 203class ALU_3R<bits<17> op, string opstr> 204 : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), opstr, "$rd, $rj, $rk">; 205class ALU_2R<bits<22> op, string opstr> 206 : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), opstr, "$rd, $rj">; 207 208class ALU_3RI2<bits<15> op, string opstr, Operand ImmOpnd> 209 : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2), opstr, 210 "$rd, $rj, $rk, $imm2">; 211class ALU_3RI3<bits<14> op, string opstr, Operand ImmOpnd> 212 : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3), opstr, 213 "$rd, $rj, $rk, $imm3">; 214class ALU_2RI5<bits<17> op, string opstr, Operand ImmOpnd> 215 : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5), opstr, 216 "$rd, $rj, $imm5">; 217class ALU_2RI6<bits<16> op, string opstr, Operand ImmOpnd> 218 : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6), opstr, 219 "$rd, $rj, $imm6">; 220class ALU_2RI12<bits<10> op, string opstr, Operand ImmOpnd> 221 : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12), opstr, 222 "$rd, $rj, $imm12">; 223class ALU_2RI16<bits<6> op, string opstr, Operand ImmOpnd> 224 : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16), opstr, 225 "$rd, $rj, $imm16">; 226class ALU_1RI20<bits<7> op, string opstr, Operand ImmOpnd> 227 : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), opstr, "$rd, $imm20">; 228 229class MISC_I15<bits<17> op, string opstr> 230 : FmtI15<op, (outs), (ins uimm15:$imm15), opstr, "$imm15">; 231 232class RDTIME_2R<bits<22> op, string opstr> 233 : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), opstr, "$rd, $rj">; 234 235class BrCC_2RI16<bits<6> op, string opstr> 236 : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16), opstr, 237 "$rj, $rd, $imm16"> { 238 let isBranch = 1; 239 let isTerminator = 1; 240} 241class BrCCZ_1RI21<bits<6> op, string opstr> 242 : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21), opstr, 243 "$rj, $imm21"> { 244 let isBranch = 1; 245 let isTerminator = 1; 246} 247class Br_I26<bits<6> op, string opstr> 248 : FmtI26<op, (outs), (ins simm26_lsl2:$imm26), opstr, "$imm26"> { 249 let isBranch = 1; 250 let isTerminator = 1; 251} 252 253let mayLoad = 1 in { 254class LOAD_3R<bits<17> op, string opstr> 255 : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), opstr, "$rd, $rj, $rk">; 256class LOAD_2RI12<bits<10> op, string opstr> 257 : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12:$imm12), opstr, 258 "$rd, $rj, $imm12">; 259class LOAD_2RI14<bits<8> op, string opstr> 260 : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), opstr, 261 "$rd, $rj, $imm14">; 262} // mayLoad = 1 263 264let mayStore = 1 in { 265class STORE_3R<bits<17> op, string opstr> 266 : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk), opstr, 267 "$rd, $rj, $rk">; 268class STORE_2RI12<bits<10> op, string opstr> 269 : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12:$imm12), opstr, 270 "$rd, $rj, $imm12">; 271class STORE_2RI14<bits<8> op, string opstr> 272 : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), opstr, 273 "$rd, $rj, $imm14">; 274} // mayStore = 1 275 276let mayLoad = 1, mayStore = 1 in 277class AM_3R<bits<17> op, string opstr> 278 : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPR:$rj), opstr, "$rd, $rk, $rj">; 279 280let mayLoad = 1 in 281class LLBase<bits<8> op, string opstr> 282 : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), opstr, 283 "$rd, $rj, $imm14">; 284 285let mayStore = 1, Constraints = "$rd = $dst" in 286class SCBase<bits<8> op, string opstr> 287 : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), 288 opstr, "$rd, $rj, $imm14">; 289 290class IOCSRRD<bits<22> op, string opstr> 291 : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), opstr, "$rd, $rj">; 292 293class IOCSRWR<bits<22> op, string opstr> 294 : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), opstr, "$rd, $rj">; 295 296//===----------------------------------------------------------------------===// 297// Basic Integer Instructions 298//===----------------------------------------------------------------------===// 299 300// Arithmetic Operation Instructions 301def ADD_W : ALU_3R<0b00000000000100000, "add.w">; 302def SUB_W : ALU_3R<0b00000000000100010, "sub.w">; 303def ADDI_W : ALU_2RI12<0b0000001010, "addi.w", simm12>; 304def ALSL_W : ALU_3RI2<0b000000000000010, "alsl.w", uimm2_plus1>; 305def LU12I_W : ALU_1RI20<0b0001010, "lu12i.w", simm20>; 306def SLT : ALU_3R<0b00000000000100100, "slt">; 307def SLTU : ALU_3R<0b00000000000100101, "sltu">; 308def SLTI : ALU_2RI12<0b0000001000, "slti", simm12>; 309def SLTUI : ALU_2RI12<0b0000001001, "sltui", simm12>; 310def PCADDI : ALU_1RI20<0b0001100, "pcaddi", simm20>; 311def PCADDU12I : ALU_1RI20<0b0001110, "pcaddu12i", simm20>; 312def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20>; 313def AND : ALU_3R<0b00000000000101001, "and">; 314def OR : ALU_3R<0b00000000000101010, "or">; 315def NOR : ALU_3R<0b00000000000101000, "nor">; 316def XOR : ALU_3R<0b00000000000101011, "xor">; 317def ANDN : ALU_3R<0b00000000000101101, "andn">; 318def ORN : ALU_3R<0b00000000000101100, "orn">; 319def ANDI : ALU_2RI12<0b0000001101, "andi", uimm12>; 320def ORI : ALU_2RI12<0b0000001110, "ori", uimm12>; 321def XORI : ALU_2RI12<0b0000001111, "xori", uimm12>; 322def MUL_W : ALU_3R<0b00000000000111000, "mul.w">; 323def MULH_W : ALU_3R<0b00000000000111001, "mulh.w">; 324def MULH_WU : ALU_3R<0b00000000000111010, "mulh.wu">; 325let usesCustomInserter = true in { 326def DIV_W : ALU_3R<0b00000000001000000, "div.w">; 327def MOD_W : ALU_3R<0b00000000001000001, "mod.w">; 328def DIV_WU : ALU_3R<0b00000000001000010, "div.wu">; 329def MOD_WU : ALU_3R<0b00000000001000011, "mod.wu">; 330} // usesCustomInserter = true 331 332// Bit-shift Instructions 333def SLL_W : ALU_3R<0b00000000000101110, "sll.w">; 334def SRL_W : ALU_3R<0b00000000000101111, "srl.w">; 335def SRA_W : ALU_3R<0b00000000000110000, "sra.w">; 336def ROTR_W : ALU_3R<0b00000000000110110, "rotr.w">; 337 338def SLLI_W : ALU_2RI5<0b00000000010000001, "slli.w", uimm5>; 339def SRLI_W : ALU_2RI5<0b00000000010001001, "srli.w", uimm5>; 340def SRAI_W : ALU_2RI5<0b00000000010010001, "srai.w", uimm5>; 341def ROTRI_W : ALU_2RI5<0b00000000010011001, "rotri.w", uimm5>; 342 343// Bit-manipulation Instructions 344def EXT_W_B : ALU_2R<0b0000000000000000010111, "ext.w.b">; 345def EXT_W_H : ALU_2R<0b0000000000000000010110, "ext.w.h">; 346def CLO_W : ALU_2R<0b0000000000000000000100, "clo.w">; 347def CLZ_W : ALU_2R<0b0000000000000000000101, "clz.w">; 348def CTO_W : ALU_2R<0b0000000000000000000110, "cto.w">; 349def CTZ_W : ALU_2R<0b0000000000000000000111, "ctz.w">; 350def BYTEPICK_W : ALU_3RI2<0b000000000000100, "bytepick.w", uimm2>; 351def REVB_2H : ALU_2R<0b0000000000000000001100, "revb.2h">; 352def BITREV_4B : ALU_2R<0b0000000000000000010010, "bitrev.4b">; 353def BITREV_W : ALU_2R<0b0000000000000000010100, "bitrev.w">; 354let Constraints = "$rd = $dst" in { 355def BSTRINS_W : FmtBSTR_W<0b000000000110, (outs GPR:$dst), 356 (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw), 357 "bstrins.w", "$rd, $rj, $msbw, $lsbw">; 358} 359def BSTRPICK_W : FmtBSTR_W<0b000000000111, (outs GPR:$rd), 360 (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw), 361 "bstrpick.w", "$rd, $rj, $msbw, $lsbw">; 362def MASKEQZ : ALU_3R<0b00000000000100110, "maskeqz">; 363def MASKNEZ : ALU_3R<0b00000000000100111, "masknez">; 364 365// Branch Instructions 366def BEQ : BrCC_2RI16<0b010110, "beq">; 367def BNE : BrCC_2RI16<0b010111, "bne">; 368def BLT : BrCC_2RI16<0b011000, "blt">; 369def BGE : BrCC_2RI16<0b011001, "bge">; 370def BLTU : BrCC_2RI16<0b011010, "bltu">; 371def BGEU : BrCC_2RI16<0b011011, "bgeu">; 372def BEQZ : BrCCZ_1RI21<0b010000, "beqz">; 373def BNEZ : BrCCZ_1RI21<0b010001, "bnez">; 374def B : Br_I26<0b010100, "b">; 375 376let isCall = 1 in 377def BL : FmtI26<0b010101, (outs), (ins simm26_lsl2:$imm26), "bl", "$imm26">; 378def JIRL : Fmt2RI16<0b010011, (outs GPR:$rd), 379 (ins GPR:$rj, simm16_lsl2:$imm16), "jirl", 380 "$rd, $rj, $imm16">; 381 382// Common Memory Access Instructions 383def LD_B : LOAD_2RI12<0b0010100000, "ld.b">; 384def LD_H : LOAD_2RI12<0b0010100001, "ld.h">; 385def LD_W : LOAD_2RI12<0b0010100010, "ld.w">; 386def LD_BU : LOAD_2RI12<0b0010101000, "ld.bu">; 387def LD_HU : LOAD_2RI12<0b0010101001, "ld.hu">; 388def ST_B : STORE_2RI12<0b0010100100, "st.b">; 389def ST_H : STORE_2RI12<0b0010100101, "st.h">; 390def ST_W : STORE_2RI12<0b0010100110, "st.w">; 391def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), "preld", 392 "$imm5, $rj, $imm12">; 393 394// Atomic Memory Access Instructions 395def LL_W : LLBase<0b00100000, "ll.w">; 396def SC_W : SCBase<0b00100001, "sc.w">; 397 398// Barrier Instructions 399def DBAR : MISC_I15<0b00111000011100100, "dbar">; 400def IBAR : MISC_I15<0b00111000011100101, "ibar">; 401 402// Other Miscellaneous Instructions 403def SYSCALL : MISC_I15<0b00000000001010110, "syscall">; 404def BREAK : MISC_I15<0b00000000001010100, "break">; 405def RDTIMEL_W : RDTIME_2R<0b0000000000000000011000, "rdtimel.w">; 406def RDTIMEH_W : RDTIME_2R<0b0000000000000000011001, "rdtimeh.w">; 407def CPUCFG : ALU_2R<0b0000000000000000011011, "cpucfg">; 408 409/// LA64 instructions 410 411let Predicates = [IsLA64] in { 412 413// Arithmetic Operation Instructions for 64-bits 414def ADD_D : ALU_3R<0b00000000000100001, "add.d">; 415def SUB_D : ALU_3R<0b00000000000100011, "sub.d">; 416def ADDI_D : ALU_2RI12<0b0000001011, "addi.d", simm12>; 417def ADDU16I_D : ALU_2RI16<0b000100, "addu16i.d", simm16>; 418def ALSL_WU : ALU_3RI2<0b000000000000011, "alsl.wu", uimm2_plus1>; 419def ALSL_D : ALU_3RI2<0b000000000010110, "alsl.d", uimm2_plus1>; 420let Constraints = "$rd = $dst" in { 421def LU32I_D : Fmt1RI20<0b0001011, (outs GPR:$dst), 422 (ins GPR:$rd, simm20:$imm20), "lu32i.d", 423 "$rd, $imm20">; 424} 425def LU52I_D : ALU_2RI12<0b0000001100, "lu52i.d", simm12>; 426def PCADDU18I : ALU_1RI20<0b0001111, "pcaddu18i", simm20>; 427def MUL_D : ALU_3R<0b00000000000111011, "mul.d">; 428def MULH_D : ALU_3R<0b00000000000111100, "mulh.d">; 429def MULH_DU : ALU_3R<0b00000000000111101, "mulh.du">; 430def MULW_D_W : ALU_3R<0b00000000000111110, "mulw.d.w">; 431def MULW_D_WU : ALU_3R<0b00000000000111111, "mulw.d.wu">; 432let usesCustomInserter = true in { 433def DIV_D : ALU_3R<0b00000000001000100, "div.d">; 434def MOD_D : ALU_3R<0b00000000001000101, "mod.d">; 435def DIV_DU : ALU_3R<0b00000000001000110, "div.du">; 436def MOD_DU : ALU_3R<0b00000000001000111, "mod.du">; 437} // usesCustomInserter = true 438 439// Bit-shift Instructions for 64-bits 440def SLL_D : ALU_3R<0b00000000000110001, "sll.d">; 441def SRL_D : ALU_3R<0b00000000000110010, "srl.d">; 442def SRA_D : ALU_3R<0b00000000000110011, "sra.d">; 443def ROTR_D : ALU_3R<0b00000000000110111, "rotr.d">; 444def SLLI_D : ALU_2RI6<0b0000000001000001, "slli.d", uimm6>; 445def SRLI_D : ALU_2RI6<0b0000000001000101, "srli.d", uimm6>; 446def SRAI_D : ALU_2RI6<0b0000000001001001, "srai.d", uimm6>; 447def ROTRI_D : ALU_2RI6<0b0000000001001101, "rotri.d", uimm6>; 448 449// Bit-manipulation Instructions for 64-bits 450def CLO_D : ALU_2R<0b0000000000000000001000, "clo.d">; 451def CLZ_D : ALU_2R<0b0000000000000000001001, "clz.d">; 452def CTO_D : ALU_2R<0b0000000000000000001010, "cto.d">; 453def CTZ_D : ALU_2R<0b0000000000000000001011, "ctz.d">; 454def BYTEPICK_D : ALU_3RI3<0b00000000000011, "bytepick.d", uimm3>; 455def REVB_4H : ALU_2R<0b0000000000000000001101, "revb.4h">; 456def REVB_2W : ALU_2R<0b0000000000000000001110, "revb.2w">; 457def REVB_D : ALU_2R<0b0000000000000000001111, "revb.d">; 458def REVH_2W : ALU_2R<0b0000000000000000010000, "revh.2w">; 459def REVH_D : ALU_2R<0b0000000000000000010001, "revh.d">; 460def BITREV_8B : ALU_2R<0b0000000000000000010011, "bitrev.8b">; 461def BITREV_D : ALU_2R<0b0000000000000000010101, "bitrev.d">; 462let Constraints = "$rd = $dst" in { 463def BSTRINS_D : FmtBSTR_D<0b0000000010, (outs GPR:$dst), 464 (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 465 "bstrins.d", "$rd, $rj, $msbd, $lsbd">; 466} 467def BSTRPICK_D : FmtBSTR_D<0b0000000011, (outs GPR:$rd), 468 (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 469 "bstrpick.d", "$rd, $rj, $msbd, $lsbd">; 470 471// Common Memory Access Instructions for 64-bits 472def LD_WU : LOAD_2RI12<0b0010101010, "ld.wu">; 473def LD_D : LOAD_2RI12<0b0010100011, "ld.d">; 474def ST_D : STORE_2RI12<0b0010100111, "st.d">; 475def LDX_B : LOAD_3R<0b00111000000000000, "ldx.b">; 476def LDX_H : LOAD_3R<0b00111000000001000, "ldx.h">; 477def LDX_W : LOAD_3R<0b00111000000010000, "ldx.w">; 478def LDX_D : LOAD_3R<0b00111000000011000, "ldx.d">; 479def LDX_BU : LOAD_3R<0b00111000001000000, "ldx.bu">; 480def LDX_HU : LOAD_3R<0b00111000001001000, "ldx.hu">; 481def LDX_WU : LOAD_3R<0b00111000001010000, "ldx.wu">; 482def STX_B : STORE_3R<0b00111000000100000, "stx.b">; 483def STX_H : STORE_3R<0b00111000000101000, "stx.h">; 484def STX_W : STORE_3R<0b00111000000110000, "stx.w">; 485def STX_D : STORE_3R<0b00111000000111000, "stx.d">; 486def LDPTR_W : LOAD_2RI14<0b00100100, "ldptr.w">; 487def LDPTR_D : LOAD_2RI14<0b00100110, "ldptr.d">; 488def STPTR_W : STORE_2RI14<0b00100101, "stptr.w">; 489def STPTR_D : STORE_2RI14<0b00100111, "stptr.d">; 490def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), "preldx", 491 "$imm5, $rj, $rk">; 492 493// Bound Check Memory Access Instructions 494def LDGT_B : LOAD_3R<0b00111000011110000, "ldgt.b">; 495def LDGT_H : LOAD_3R<0b00111000011110001, "ldgt.h">; 496def LDGT_W : LOAD_3R<0b00111000011110010, "ldgt.w">; 497def LDGT_D : LOAD_3R<0b00111000011110011, "ldgt.d">; 498def LDLE_B : LOAD_3R<0b00111000011110100, "ldle.b">; 499def LDLE_H : LOAD_3R<0b00111000011110101, "ldle.h">; 500def LDLE_W : LOAD_3R<0b00111000011110110, "ldle.w">; 501def LDLE_D : LOAD_3R<0b00111000011110111, "ldle.d">; 502def STGT_B : STORE_3R<0b00111000011111000, "stgt.b">; 503def STGT_H : STORE_3R<0b00111000011111001, "stgt.h">; 504def STGT_W : STORE_3R<0b00111000011111010, "stgt.w">; 505def STGT_D : STORE_3R<0b00111000011111011, "stgt.d">; 506def STLE_B : STORE_3R<0b00111000011111100, "stle.b">; 507def STLE_H : STORE_3R<0b00111000011111101, "stle.h">; 508def STLE_W : STORE_3R<0b00111000011111110, "stle.w">; 509def STLE_D : STORE_3R<0b00111000011111111, "stle.d">; 510 511// Atomic Memory Access Instructions for 64-bits 512def AMSWAP_W : AM_3R<0b00111000011000000, "amswap.w">; 513def AMSWAP_D : AM_3R<0b00111000011000001, "amswap.d">; 514def AMADD_W : AM_3R<0b00111000011000010, "amadd.w">; 515def AMADD_D : AM_3R<0b00111000011000011, "amadd.d">; 516def AMAND_W : AM_3R<0b00111000011000100, "amand.w">; 517def AMAND_D : AM_3R<0b00111000011000101, "amand.d">; 518def AMOR_W : AM_3R<0b00111000011000110, "amor.w">; 519def AMOR_D : AM_3R<0b00111000011000111, "amor.d">; 520def AMXOR_W : AM_3R<0b00111000011001000, "amxor.w">; 521def AMXOR_D : AM_3R<0b00111000011001001, "amxor.d">; 522def AMMAX_W : AM_3R<0b00111000011001010, "ammax.w">; 523def AMMAX_D : AM_3R<0b00111000011001011, "ammax.d">; 524def AMMIN_W : AM_3R<0b00111000011001100, "ammin.w">; 525def AMMIN_D : AM_3R<0b00111000011001101, "ammin.d">; 526def AMMAX_WU : AM_3R<0b00111000011001110, "ammax.wu">; 527def AMMAX_DU : AM_3R<0b00111000011001111, "ammax.du">; 528def AMMIN_WU : AM_3R<0b00111000011010000, "ammin.wu">; 529def AMMIN_DU : AM_3R<0b00111000011010001, "ammin.du">; 530def AMSWAP_DB_W : AM_3R<0b00111000011010010, "amswap_db.w">; 531def AMSWAP_DB_D : AM_3R<0b00111000011010011, "amswap_db.d">; 532def AMADD_DB_W : AM_3R<0b00111000011010100, "amadd_db.w">; 533def AMADD_DB_D : AM_3R<0b00111000011010101, "amadd_db.d">; 534def AMAND_DB_W : AM_3R<0b00111000011010110, "amand_db.w">; 535def AMAND_DB_D : AM_3R<0b00111000011010111, "amand_db.d">; 536def AMOR_DB_W : AM_3R<0b00111000011011000, "amor_db.w">; 537def AMOR_DB_D : AM_3R<0b00111000011011001, "amor_db.d">; 538def AMXOR_DB_W : AM_3R<0b00111000011011010, "amxor_db.w">; 539def AMXOR_DB_D : AM_3R<0b00111000011011011, "amxor_db.d">; 540def AMMAX_DB_W : AM_3R<0b00111000011011100, "ammax_db.w">; 541def AMMAX_DB_D : AM_3R<0b00111000011011101, "ammax_db.d">; 542def AMMIN_DB_W : AM_3R<0b00111000011011110, "ammin_db.w">; 543def AMMIN_DB_D : AM_3R<0b00111000011011111, "ammin_db.d">; 544def AMMAX_DB_WU : AM_3R<0b00111000011100000, "ammax_db.wu">; 545def AMMAX_DB_DU : AM_3R<0b00111000011100001, "ammax_db.du">; 546def AMMIN_DB_WU : AM_3R<0b00111000011100010, "ammin_db.wu">; 547def AMMIN_DB_DU : AM_3R<0b00111000011100011, "ammin_db.du">; 548def LL_D : LLBase<0b00100010, "ll.d">; 549def SC_D : SCBase<0b00100011, "sc.d">; 550 551// CRC Check Instructions 552def CRC_W_B_W : ALU_3R<0b00000000001001000, "crc.w.b.w">; 553def CRC_W_H_W : ALU_3R<0b00000000001001001, "crc.w.h.w">; 554def CRC_W_W_W : ALU_3R<0b00000000001001010, "crc.w.w.w">; 555def CRC_W_D_W : ALU_3R<0b00000000001001011, "crc.w.d.w">; 556def CRCC_W_B_W : ALU_3R<0b00000000001001100, "crcc.w.b.w">; 557def CRCC_W_H_W : ALU_3R<0b00000000001001101, "crcc.w.h.w">; 558def CRCC_W_W_W : ALU_3R<0b00000000001001110, "crcc.w.w.w">; 559def CRCC_W_D_W : ALU_3R<0b00000000001001111, "crcc.w.d.w">; 560 561// Other Miscellaneous Instructions for 64-bits 562def ASRTLE_D : FmtASRT<0b00000000000000010, (outs), (ins GPR:$rj, GPR:$rk), 563 "asrtle.d", "$rj, $rk">; 564def ASRTGT_D : FmtASRT<0b00000000000000011, (outs), (ins GPR:$rj, GPR:$rk), 565 "asrtgt.d", "$rj, $rk">; 566def RDTIME_D : RDTIME_2R<0b0000000000000000011010, "rdtime.d">; 567} // Predicates = [IsLA64] 568 569//===----------------------------------------------------------------------===// 570// Pseudo-instructions and codegen patterns 571// 572// Naming convention: For 'generic' pattern classes, we use the naming 573// convention PatTy1Ty2. 574//===----------------------------------------------------------------------===// 575 576/// Generic pattern classes 577 578class PatGprGpr<SDPatternOperator OpNode, LAInst Inst> 579 : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>; 580class PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst> 581 : Pat<(sext_inreg (OpNode GPR:$rj, GPR:$rk), i32), (Inst GPR:$rj, GPR:$rk)>; 582 583class PatGprImm<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd> 584 : Pat<(OpNode GPR:$rj, ImmOpnd:$imm), 585 (Inst GPR:$rj, ImmOpnd:$imm)>; 586class PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd> 587 : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32), 588 (Inst GPR:$rj, ImmOpnd:$imm)>; 589 590/// Simple arithmetic operations 591 592// Match both a plain shift and one where the shift amount is masked (this is 593// typically introduced when the legalizer promotes the shift amount and 594// zero-extends it). For LoongArch, the mask is unnecessary as shifts in the 595// base ISA only read the least significant 5 bits (LA32) or 6 bits (LA64). 596def shiftMaskGRLen 597 : ComplexPattern<GRLenVT, 1, "selectShiftMaskGRLen", [], [], 0>; 598def shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>; 599 600def sexti32 : ComplexPattern<i64, 1, "selectSExti32">; 601def zexti32 : ComplexPattern<i64, 1, "selectZExti32">; 602 603class shiftop<SDPatternOperator operator> 604 : PatFrag<(ops node:$val, node:$count), 605 (operator node:$val, (GRLenVT (shiftMaskGRLen node:$count)))>; 606class shiftopw<SDPatternOperator operator> 607 : PatFrag<(ops node:$val, node:$count), 608 (operator node:$val, (i64 (shiftMask32 node:$count)))>; 609 610let Predicates = [IsLA32] in { 611def : PatGprGpr<add, ADD_W>; 612def : PatGprImm<add, ADDI_W, simm12>; 613def : PatGprGpr<sub, SUB_W>; 614def : PatGprGpr<sdiv, DIV_W>; 615def : PatGprGpr<udiv, DIV_WU>; 616def : PatGprGpr<srem, MOD_W>; 617def : PatGprGpr<urem, MOD_WU>; 618def : PatGprGpr<mul, MUL_W>; 619def : PatGprGpr<mulhs, MULH_W>; 620def : PatGprGpr<mulhu, MULH_WU>; 621} // Predicates = [IsLA32] 622 623let Predicates = [IsLA64] in { 624def : PatGprGpr<add, ADD_D>; 625def : PatGprGpr_32<add, ADD_W>; 626def : PatGprImm<add, ADDI_D, simm12>; 627def : PatGprImm_32<add, ADDI_W, simm12>; 628def : PatGprGpr<sub, SUB_D>; 629def : PatGprGpr_32<sub, SUB_W>; 630def : PatGprGpr<sdiv, DIV_D>; 631def : PatGprGpr<udiv, DIV_DU>; 632def : PatGprGpr<srem, MOD_D>; 633def : PatGprGpr<urem, MOD_DU>; 634// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the 635// product are used. 636def : PatGprGpr<mul, MUL_D>; 637def : PatGprGpr<mulhs, MULH_D>; 638def : PatGprGpr<mulhu, MULH_DU>; 639// Select MULW_D_W for calculating the full 64 bits product of i32xi32 signed 640// multiplication. 641def : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))), 642 (MULW_D_W GPR:$rj, GPR:$rk)>; 643// Select MULW_D_WU for calculating the full 64 bits product of i32xi32 644// unsigned multiplication. 645def : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)), 646 (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))), 647 (MULW_D_WU GPR:$rj, GPR:$rk)>; 648} // Predicates = [IsLA64] 649 650def : PatGprGpr<and, AND>; 651def : PatGprImm<and, ANDI, uimm12>; 652def : PatGprGpr<or, OR>; 653def : PatGprImm<or, ORI, uimm12>; 654def : PatGprGpr<xor, XOR>; 655def : PatGprImm<xor, XORI, uimm12>; 656 657/// Shift 658 659let Predicates = [IsLA32] in { 660def : PatGprGpr<shiftop<shl>, SLL_W>; 661def : PatGprGpr<shiftop<sra>, SRA_W>; 662def : PatGprGpr<shiftop<srl>, SRL_W>; 663def : PatGprImm<shl, SLLI_W, uimm5>; 664def : PatGprImm<sra, SRAI_W, uimm5>; 665def : PatGprImm<srl, SRLI_W, uimm5>; 666} // Predicates = [IsLA32] 667 668let Predicates = [IsLA64] in { 669def : PatGprGpr<shiftopw<loongarch_sll_w>, SLL_W>; 670def : PatGprGpr<shiftopw<loongarch_sra_w>, SRA_W>; 671def : PatGprGpr<shiftopw<loongarch_srl_w>, SRL_W>; 672def : PatGprGpr<shiftop<shl>, SLL_D>; 673def : PatGprGpr<shiftop<sra>, SRA_D>; 674def : PatGprGpr<shiftop<srl>, SRL_D>; 675def : PatGprImm<shl, SLLI_D, uimm6>; 676def : PatGprImm<sra, SRAI_D, uimm6>; 677def : PatGprImm<srl, SRLI_D, uimm6>; 678} // Predicates = [IsLA64] 679 680/// sext and zext 681 682def : Pat<(sext_inreg GPR:$rj, i8), (EXT_W_B GPR:$rj)>; 683def : Pat<(sext_inreg GPR:$rj, i16), (EXT_W_H GPR:$rj)>; 684 685let Predicates = [IsLA64] in { 686def : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>; 687} // Predicates = [IsLA64] 688 689/// Setcc 690 691def : PatGprGpr<setlt, SLT>; 692def : PatGprImm<setlt, SLTI, simm12>; 693def : PatGprGpr<setult, SLTU>; 694def : PatGprImm<setult, SLTUI, simm12>; 695 696// Define pattern expansions for setcc operations that aren't directly 697// handled by a LoongArch instruction. 698def : Pat<(seteq GPR:$rj, 0), (SLTUI GPR:$rj, 1)>; 699def : Pat<(seteq GPR:$rj, GPR:$rk), (SLTUI (XOR GPR:$rj, GPR:$rk), 1)>; 700let Predicates = [IsLA32] in { 701def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), 702 (SLTUI (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; 703} // Predicates = [IsLA32] 704let Predicates = [IsLA64] in { 705def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), 706 (SLTUI (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; 707} // Predicates = [IsLA64] 708def : Pat<(setne GPR:$rj, 0), (SLTU R0, GPR:$rj)>; 709def : Pat<(setne GPR:$rj, GPR:$rk), (SLTU R0, (XOR GPR:$rj, GPR:$rk))>; 710let Predicates = [IsLA32] in { 711def : Pat<(setne GPR:$rj, simm12_plus1:$imm12), 712 (SLTU R0, (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)))>; 713} // Predicates = [IsLA32] 714let Predicates = [IsLA64] in { 715def : Pat<(setne GPR:$rj, simm12_plus1:$imm12), 716 (SLTU R0, (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)))>; 717} // Predicates = [IsLA64] 718def : Pat<(setugt GPR:$rj, GPR:$rk), (SLTU GPR:$rk, GPR:$rj)>; 719def : Pat<(setuge GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rj, GPR:$rk), 1)>; 720def : Pat<(setule GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rk, GPR:$rj), 1)>; 721def : Pat<(setgt GPR:$rj, GPR:$rk), (SLT GPR:$rk, GPR:$rj)>; 722def : Pat<(setge GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rj, GPR:$rk), 1)>; 723def : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>; 724 725/// Select 726 727def : Pat<(select GPR:$cond, GPR:$t, GPR:$f), 728 (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>; 729 730/// Branches and jumps 731 732class BccPat<PatFrag CondOp, LAInst Inst> 733 : Pat<(brcond (GRLenVT (CondOp GPR:$rj, GPR:$rd)), bb:$imm16), 734 (Inst GPR:$rj, GPR:$rd, bb:$imm16)>; 735 736def : BccPat<seteq, BEQ>; 737def : BccPat<setne, BNE>; 738def : BccPat<setlt, BLT>; 739def : BccPat<setge, BGE>; 740def : BccPat<setult, BLTU>; 741def : BccPat<setuge, BGEU>; 742 743class BccSwapPat<PatFrag CondOp, LAInst InstBcc> 744 : Pat<(brcond (GRLenVT (CondOp GPR:$rd, GPR:$rj)), bb:$imm16), 745 (InstBcc GPR:$rj, GPR:$rd, bb:$imm16)>; 746 747// Condition codes that don't have matching LoongArch branch instructions, but 748// are trivially supported by swapping the two input operands. 749def : BccSwapPat<setgt, BLT>; 750def : BccSwapPat<setle, BGE>; 751def : BccSwapPat<setugt, BLTU>; 752def : BccSwapPat<setule, BGEU>; 753 754// An extra pattern is needed for a brcond without a setcc (i.e. where the 755// condition was calculated elsewhere). 756def : Pat<(brcond GPR:$rj, bb:$imm21), (BNEZ GPR:$rj, bb:$imm21)>; 757 758let isBarrier = 1, isBranch = 1, isTerminator = 1 in 759def PseudoBR : Pseudo<(outs), (ins simm26_lsl2:$imm26), [(br bb:$imm26)]>, 760 PseudoInstExpansion<(B simm26_lsl2:$imm26)>; 761 762let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in 763def PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16), []>, 764 PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>; 765 766def : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>; 767def : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)), 768 (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; 769 770let isCall = 1, Defs = [R1] in 771def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), []> { 772 let AsmString = "bl\t$func"; 773} 774 775def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; 776def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; 777 778let isCall = 1, Defs = [R1] in 779def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj), 780 [(loongarch_call GPR:$rj)]>, 781 PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>; 782 783let isBarrier = 1, isReturn = 1, isTerminator = 1 in 784def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>, 785 PseudoInstExpansion<(JIRL R0, R1, 0)>; 786 787/// BSTRINS and BSTRPICK 788 789let Predicates = [IsLA32] in { 790def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd), 791 (BSTRINS_W GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; 792def : Pat<(loongarch_bstrpick GPR:$rj, uimm5:$msbd, uimm5:$lsbd), 793 (BSTRPICK_W GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; 794} // Predicates = [IsLA32] 795 796let Predicates = [IsLA64] in { 797def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 798 (BSTRINS_D GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; 799def : Pat<(loongarch_bstrpick GPR:$rj, uimm6:$msbd, uimm6:$lsbd), 800 (BSTRPICK_D GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; 801} // Predicates = [IsLA64] 802 803/// Loads 804 805multiclass LdPat<PatFrag LoadOp, LAInst Inst, ValueType vt = GRLenVT> { 806 def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>; 807 def : Pat<(vt (LoadOp (add BaseAddr:$rj, simm12:$imm12))), 808 (Inst BaseAddr:$rj, simm12:$imm12)>; 809} 810 811defm : LdPat<sextloadi8, LD_B>; 812defm : LdPat<extloadi8, LD_B>; 813defm : LdPat<sextloadi16, LD_H>; 814defm : LdPat<extloadi16, LD_H>; 815defm : LdPat<load, LD_W>, Requires<[IsLA32]>; 816defm : LdPat<zextloadi8, LD_BU>; 817defm : LdPat<zextloadi16, LD_HU>; 818let Predicates = [IsLA64] in { 819defm : LdPat<sextloadi32, LD_W, i64>; 820defm : LdPat<extloadi32, LD_W, i64>; 821defm : LdPat<zextloadi32, LD_WU, i64>; 822defm : LdPat<load, LD_D, i64>; 823} // Predicates = [IsLA64] 824 825/// Stores 826 827multiclass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy, 828 ValueType vt> { 829 def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj), 830 (Inst StTy:$rd, BaseAddr:$rj, 0)>; 831 def : Pat<(StoreOp (vt StTy:$rd), (add BaseAddr:$rj, simm12:$imm12)), 832 (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>; 833} 834 835defm : StPat<truncstorei8, ST_B, GPR, GRLenVT>; 836defm : StPat<truncstorei16, ST_H, GPR, GRLenVT>; 837defm : StPat<store, ST_W, GPR, i32>, Requires<[IsLA32]>; 838let Predicates = [IsLA64] in { 839defm : StPat<truncstorei32, ST_W, GPR, i64>; 840defm : StPat<store, ST_D, GPR, i64>; 841} // Predicates = [IsLA64] 842 843/// Atomic loads and stores 844 845def : Pat<(atomic_fence timm, timm), (DBAR 0)>; 846 847defm : LdPat<atomic_load_8, LD_B>; 848defm : LdPat<atomic_load_16, LD_H>; 849defm : LdPat<atomic_load_32, LD_W>; 850 851defm : StPat<atomic_store_8, ST_B, GPR, GRLenVT>; 852defm : StPat<atomic_store_16, ST_H, GPR, GRLenVT>; 853defm : StPat<atomic_store_32, ST_W, GPR, i32>, Requires<[IsLA32]>; 854let Predicates = [IsLA64] in { 855defm : LdPat<atomic_load_64, LD_D>; 856defm : StPat<atomic_store_32, ST_W, GPR, i64>; 857defm : StPat<atomic_store_64, ST_D, GPR, i64>; 858} // Predicates = [IsLA64] 859 860/// Other pseudo-instructions 861 862// Pessimistically assume the stack pointer will be clobbered 863let Defs = [R3], Uses = [R3] in { 864def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 865 [(callseq_start timm:$amt1, timm:$amt2)]>; 866def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 867 [(callseq_end timm:$amt1, timm:$amt2)]>; 868} // Defs = [R3], Uses = [R3] 869 870//===----------------------------------------------------------------------===// 871// Assembler Pseudo Instructions 872//===----------------------------------------------------------------------===// 873 874def : InstAlias<"nop", (ANDI R0, R0, 0)>; 875def : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>; 876 877//===----------------------------------------------------------------------===// 878// Basic Floating-Point Instructions 879//===----------------------------------------------------------------------===// 880 881include "LoongArchFloat32InstrInfo.td" 882include "LoongArchFloat64InstrInfo.td" 883 884//===----------------------------------------------------------------------===// 885// Privilege Instructions 886//===----------------------------------------------------------------------===// 887 888// CSR Access Instructions 889def CSRRD : FmtCSR<0b0000010000000, (outs GPR:$rd), (ins uimm14:$csr_num), 890 "csrrd", "$rd, $csr_num">; 891let Constraints = "$rd = $dst" in { 892def CSRWR : FmtCSR<0b0000010000001, (outs GPR:$dst), 893 (ins GPR:$rd, uimm14:$csr_num), "csrwr", "$rd, $csr_num">; 894def CSRXCHG : FmtCSRXCHG<0b00000100, (outs GPR:$dst), 895 (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), 896 "csrxchg", "$rd, $rj, $csr_num">; 897} // Constraints = "$rd = $dst" 898 899// IOCSR Access Instructions 900def IOCSRRD_B : IOCSRRD<0b0000011001001000000000, "iocsrrd.b">; 901def IOCSRRD_H : IOCSRRD<0b0000011001001000000001, "iocsrrd.h">; 902def IOCSRRD_W : IOCSRRD<0b0000011001001000000010, "iocsrrd.w">; 903def IOCSRWR_B : IOCSRWR<0b0000011001001000000100, "iocsrwr.b">; 904def IOCSRWR_H : IOCSRWR<0b0000011001001000000101, "iocsrwr.h">; 905def IOCSRWR_W : IOCSRWR<0b0000011001001000000110, "iocsrwr.w">; 906let Predicates = [IsLA64] in { 907def IOCSRRD_D : IOCSRRD<0b0000011001001000000011, "iocsrrd.d">; 908def IOCSRWR_D : IOCSRWR<0b0000011001001000000111, "iocsrwr.d">; 909} // Predicates = [IsLA64] 910 911// Cache Maintenance Instructions 912def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), "cacop", 913 "$op, $rj, $imm12">; 914 915// TLB Maintenance Instructions 916def TLBSRCH : FmtI32<0b00000110010010000010100000000000, "tlbsrch">; 917def TLBRD : FmtI32<0b00000110010010000010110000000000, "tlbrd">; 918def TLBWR : FmtI32<0b00000110010010000011000000000000, "tlbwr">; 919def TLBFILL : FmtI32<0b00000110010010000011010000000000, "tlbfill">; 920def TLBCLR : FmtI32<0b00000110010010000010000000000000, "tlbclr">; 921def TLBFLUSH : FmtI32<0b00000110010010000010010000000000, "tlbflush">; 922def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), "invtlb", 923 "$op, $rj, $rk">; 924 925// Software Page Walking Instructions 926def LDDIR : Fmt2RI8<0b00000110010000, (outs GPR:$rd), 927 (ins GPR:$rj, uimm8:$imm8), "lddir", "$rd, $rj, $imm8">; 928def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "ldpte", "$rj, $seq">; 929 930 931// Other Miscellaneous Instructions 932def ERTN : FmtI32<0b00000110010010000011100000000000, "ertn">; 933def DBCL : MISC_I15<0b00000000001010101, "dbcl">; 934def IDLE : MISC_I15<0b00000110010010001, "idle">; 935