diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
download | src-06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e.tar.gz src-06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e.zip |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 1009 |
1 files changed, 661 insertions, 348 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 75b2adc729d0..ac391ef471b1 100644 --- a/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -75,21 +75,21 @@ def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>; def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>; def loongarch_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>; def loongarch_crc_w_b_w - : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW>; + : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; def loongarch_crc_w_h_w - : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW>; + : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; def loongarch_crc_w_w_w - : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW>; + : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; def loongarch_crc_w_d_w - : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW>; -def loongarch_crcc_w_b_w - : SDNode<"LoongArchISD::CRCC_W_B_W", SDT_LoongArchIntBinOpW>; -def loongarch_crcc_w_h_w - : SDNode<"LoongArchISD::CRCC_W_H_W", SDT_LoongArchIntBinOpW>; -def loongarch_crcc_w_w_w - : SDNode<"LoongArchISD::CRCC_W_W_W", SDT_LoongArchIntBinOpW>; -def loongarch_crcc_w_d_w - : SDNode<"LoongArchISD::CRCC_W_D_W", SDT_LoongArchIntBinOpW>; + : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +def loongarch_crcc_w_b_w : SDNode<"LoongArchISD::CRCC_W_B_W", + SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +def loongarch_crcc_w_h_w : SDNode<"LoongArchISD::CRCC_W_H_W", + SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +def loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W", + SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +def loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W", + SDT_LoongArchIntBinOpW, [SDNPHasChain]>; def loongarch_bstrins : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>; def loongarch_bstrpick @@ -106,9 +106,11 @@ def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI, [SDNPHasChain, SDNPSideEffect]>; def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI, [SDNPHasChain, SDNPSideEffect]>; -def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", SDT_LoongArchMovfcsr2gr>; -def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR", SDT_LoongArchMovgr2fcsr, - [SDNPHasChain, SDNPSideEffect]>; +def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", + SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>; +def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR", + SDT_LoongArchMovgr2fcsr, + [SDNPHasChain, SDNPSideEffect]>; def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI, [SDNPHasChain, SDNPSideEffect]>; def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd, @@ -139,7 +141,7 @@ def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D", SDT_LoongArchIocsrwr, [SDNPHasChain, SDNPSideEffect]>; def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp, - [SDNPHasChain, SDNPSideEffect]>; + [SDNPHasChain]>; //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. @@ -180,6 +182,10 @@ def imm32 : Operand<GRLenVT> { let ParserMatchClass = ImmAsmOperand<"", 32, "">; } +def uimm1 : Operand<GRLenVT> { + let ParserMatchClass = UImmAsmOperand<1>; +} + def uimm2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<2>; } @@ -195,6 +201,10 @@ def uimm3 : Operand<GRLenVT> { let ParserMatchClass = UImmAsmOperand<3>; } +def uimm4 : Operand<GRLenVT> { + let ParserMatchClass = UImmAsmOperand<4>; +} + def uimm5 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5>; } @@ -203,6 +213,10 @@ def uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<6>; } +def uimm7 : Operand<GRLenVT> { + let ParserMatchClass = UImmAsmOperand<7>; +} + def uimm8 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<8>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<8>; } @@ -230,6 +244,46 @@ def uimm15 : Operand<GRLenVT>, let ParserMatchClass = UImmAsmOperand<15>; } +def simm5 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<5>; + let DecoderMethod = "decodeSImmOperand<5>"; +} + +def simm8 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<8>; + let DecoderMethod = "decodeSImmOperand<8>"; +} + +foreach I = [1, 2, 3] in { +def simm8_lsl # I : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<8, "lsl" # I>; + let EncoderMethod = "getImmOpValueAsr<" # I # ">"; + let DecoderMethod = "decodeSImmOperand<8," # I # ">"; +} +} + +def simm9_lsl3 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<9, "lsl3">; + let EncoderMethod = "getImmOpValueAsr<3>"; + let DecoderMethod = "decodeSImmOperand<9, 3>"; +} + +def simm10 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<10>; +} + +def simm10_lsl2 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<10, "lsl2">; + let EncoderMethod = "getImmOpValueAsr<2>"; + let DecoderMethod = "decodeSImmOperand<10, 2>"; +} + +def simm11_lsl1 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<11, "lsl1">; + let EncoderMethod = "getImmOpValueAsr<1>"; + let DecoderMethod = "decodeSImmOperand<11, 1>"; +} + class SImm12Operand : Operand<GRLenVT>, ImmLeaf <GRLenVT, [{return isInt<12>(Imm);}]> { let DecoderMethod = "decodeSImmOperand<12>"; @@ -247,10 +301,15 @@ def simm12_lu52id : SImm12Operand { let ParserMatchClass = SImmAsmOperand<12, "lu52id">; } +def simm13 : Operand<GRLenVT> { + let ParserMatchClass = SImmAsmOperand<13>; + let DecoderMethod = "decodeSImmOperand<13>"; +} + def simm14_lsl2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isShiftedInt<14,2>(Imm);}]> { let ParserMatchClass = SImmAsmOperand<14, "lsl2">; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<14, 2>"; } @@ -262,13 +321,13 @@ def simm16 : Operand<GRLenVT> { def simm16_lsl2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isInt<16>(Imm>>2);}]> { let ParserMatchClass = SImmAsmOperand<16, "lsl2">; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<16, 2>"; } def simm16_lsl2_br : Operand<OtherVT> { let ParserMatchClass = SImmAsmOperand<16, "lsl2">; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<16, 2>"; } @@ -294,7 +353,7 @@ def simm20_lu32id : SImm20Operand { def simm21_lsl2 : Operand<OtherVT> { let ParserMatchClass = SImmAsmOperand<21, "lsl2">; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<21, 2>"; } @@ -309,7 +368,7 @@ def SImm26OperandB: AsmOperandClass { // A symbol or an imm used in B/PseudoBR. def simm26_b : Operand<OtherVT> { let ParserMatchClass = SImm26OperandB; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<26, 2>"; } @@ -324,10 +383,21 @@ def SImm26OperandBL: AsmOperandClass { // A symbol or an imm used in BL/PseudoCALL/PseudoTAIL. def simm26_symbol : Operand<GRLenVT> { let ParserMatchClass = SImm26OperandBL; - let EncoderMethod = "getImmOpValueAsr2"; + let EncoderMethod = "getImmOpValueAsr<2>"; let DecoderMethod = "decodeSImmOperand<26, 2>"; } +// A 32-bit signed immediate with the lowest 16 bits zeroed, suitable for +// direct use with `addu16i.d`. +def simm16_lsl16 : Operand<GRLenVT>, + ImmLeaf<GRLenVT, [{return isShiftedInt<16, 16>(Imm);}]>; + +// A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for +// use in additions. +def simm32_hi16_lo12: Operand<GRLenVT>, ImmLeaf<GRLenVT, [{ + return isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm)); +}]>; + def BareSymbol : AsmOperandClass { let Name = "BareSymbol"; let RenderMethod = "addImmOperands"; @@ -363,7 +433,28 @@ def ImmSubFrom32 : SDNodeXForm<imm, [{ N->getValueType(0)); }]>; +// Return the lowest 12 bits of the signed immediate. +def LO12: SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(SignExtend64<12>(N->getSExtValue()), + SDLoc(N), N->getValueType(0)); +}]>; + +// Return the higher 16 bits of the signed immediate. +def HI16 : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getSExtValue() >> 16, SDLoc(N), + N->getValueType(0)); +}]>; + +// Return the higher 16 bits of the signed immediate, adjusted for use within an +// `addu16i.d + addi` pair. +def HI16ForAddu16idAddiPair: SDNodeXForm<imm, [{ + auto Imm = N->getSExtValue(); + return CurDAG->getTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16, + SDLoc(N), N->getValueType(0)); +}]>; + def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; +def AddrConstant : ComplexPattern<iPTR, 2, "SelectAddrConstant">; def NonFIBaseAddr : ComplexPattern<iPTR, 1, "selectNonFIBaseAddr">; def fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa), @@ -371,226 +462,295 @@ def fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa), return N->getFlags().hasNoSignedZeros(); }]>; +// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), +// in which imm = imm0 + imm1, and both imm0 & imm1 are simm12. +def AddiPair : PatLeaf<(imm), [{ + if (!N->hasOneUse()) + return false; + // The immediate operand must be in range [-4096,-2049] or [2048,4094]. + int64_t Imm = N->getSExtValue(); + return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); +}]>; + +// Return -2048 if immediate is negative or 2047 if positive. +def AddiPairImmLarge : SDNodeXForm<imm, [{ + int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047; + return CurDAG->getTargetConstant(Imm, SDLoc(N), + N->getValueType(0)); +}]>; + +// Return imm - (imm < 0 ? -2048 : 2047). +def AddiPairImmSmall : SDNodeXForm<imm, [{ + int64_t Imm = N->getSExtValue(); + int64_t Adj = Imm < 0 ? -2048 : 2047; + return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N), + N->getValueType(0)); +}]>; + +// Check if (mul r, imm) can be optimized to (SLLI (ALSL r, r, i0), i1), +// in which imm = (1 + (1 << i0)) << i1. +def AlslSlliImm : PatLeaf<(imm), [{ + if (!N->hasOneUse()) + return false; + uint64_t Imm = N->getZExtValue(); + unsigned I1 = llvm::countr_zero(Imm); + uint64_t Rem = Imm >> I1; + return Rem == 3 || Rem == 5 || Rem == 9 || Rem == 17; +}]>; + +def AlslSlliImmI1 : SDNodeXForm<imm, [{ + uint64_t Imm = N->getZExtValue(); + unsigned I1 = llvm::countr_zero(Imm); + return CurDAG->getTargetConstant(I1, SDLoc(N), + N->getValueType(0)); +}]>; + +def AlslSlliImmI0 : SDNodeXForm<imm, [{ + uint64_t Imm = N->getZExtValue(); + unsigned I1 = llvm::countr_zero(Imm); + uint64_t I0; + switch (Imm >> I1) { + case 3: I0 = 1; break; + case 5: I0 = 2; break; + case 9: I0 = 3; break; + default: I0 = 4; break; + } + return CurDAG->getTargetConstant(I0, SDLoc(N), + N->getValueType(0)); +}]>; + //===----------------------------------------------------------------------===// // Instruction Formats //===----------------------------------------------------------------------===// include "LoongArchInstrFormats.td" include "LoongArchFloatInstrFormats.td" +include "LoongArchLSXInstrFormats.td" +include "LoongArchLASXInstrFormats.td" +include "LoongArchLBTInstrFormats.td" //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// -class ALU_3R<bits<17> op, string opstr> - : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), opstr, "$rd, $rj, $rk">; -class ALU_2R<bits<22> op, string opstr> - : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), opstr, "$rd, $rj">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +class ALU_3R<bits<32> op> + : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">; +class ALU_2R<bits<32> op> + : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">; -class ALU_3RI2<bits<15> op, string opstr, Operand ImmOpnd> - : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2), opstr, +class ALU_3RI2<bits<32> op, Operand ImmOpnd> + : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2), "$rd, $rj, $rk, $imm2">; -class ALU_3RI3<bits<14> op, string opstr, Operand ImmOpnd> - : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3), opstr, +class ALU_3RI3<bits<32> op, Operand ImmOpnd> + : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3), "$rd, $rj, $rk, $imm3">; -class ALU_2RI5<bits<17> op, string opstr, Operand ImmOpnd> - : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5), opstr, +class ALU_2RI5<bits<32> op, Operand ImmOpnd> + : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5), "$rd, $rj, $imm5">; -class ALU_2RI6<bits<16> op, string opstr, Operand ImmOpnd> - : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6), opstr, +class ALU_2RI6<bits<32> op, Operand ImmOpnd> + : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6), "$rd, $rj, $imm6">; -class ALU_2RI12<bits<10> op, string opstr, Operand ImmOpnd> - : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12), opstr, +class ALU_2RI12<bits<32> op, Operand ImmOpnd> + : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12), "$rd, $rj, $imm12">; -class ALU_2RI16<bits<6> op, string opstr, Operand ImmOpnd> - : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16), opstr, +class ALU_2RI16<bits<32> op, Operand ImmOpnd> + : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16), "$rd, $rj, $imm16">; -class ALU_1RI20<bits<7> op, string opstr, Operand ImmOpnd> - : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), opstr, "$rd, $imm20">; +class ALU_1RI20<bits<32> op, Operand ImmOpnd> + : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), "$rd, $imm20">; +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 -class MISC_I15<bits<17> op, string opstr> - : FmtI15<op, (outs), (ins uimm15:$imm15), opstr, "$imm15">; +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class MISC_I15<bits<32> op> + : FmtI15<op, (outs), (ins uimm15:$imm15), "$imm15">; -class RDTIME_2R<bits<22> op, string opstr> - : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), opstr, "$rd, $rj">; +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class RDTIME_2R<bits<32> op> + : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), "$rd, $rj">; -class BrCC_2RI16<bits<6> op, string opstr> - : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16), opstr, +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +class BrCC_2RI16<bits<32> op> + : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16), "$rj, $rd, $imm16"> { let isBranch = 1; let isTerminator = 1; } -class BrCCZ_1RI21<bits<6> op, string opstr> - : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21), opstr, +class BrCCZ_1RI21<bits<32> op> + : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21), "$rj, $imm21"> { let isBranch = 1; let isTerminator = 1; } -class Br_I26<bits<6> op, string opstr> - : FmtI26<op, (outs), (ins simm26_b:$imm26), opstr, "$imm26"> { +class Br_I26<bits<32> op> + : FmtI26<op, (outs), (ins simm26_b:$imm26), "$imm26"> { let isBranch = 1; let isTerminator = 1; } +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 -let mayLoad = 1 in { -class LOAD_3R<bits<17> op, string opstr> - : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), opstr, "$rd, $rj, $rk">; -class LOAD_2RI12<bits<10> op, string opstr> - : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12_addlike:$imm12), opstr, +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +class LOAD_3R<bits<32> op> + : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">; +class LOAD_2RI12<bits<32> op> + : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12_addlike:$imm12), "$rd, $rj, $imm12">; -class LOAD_2RI14<bits<8> op, string opstr> - : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), opstr, +class LOAD_2RI14<bits<32> op> + : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), "$rd, $rj, $imm14">; -} // mayLoad = 1 +} // hasSideEffects = 0, mayLoad = 1, mayStore = 0 -let mayStore = 1 in { -class STORE_3R<bits<17> op, string opstr> - : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk), opstr, +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { +class STORE_3R<bits<32> op> + : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk), "$rd, $rj, $rk">; -class STORE_2RI12<bits<10> op, string opstr> - : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12_addlike:$imm12), opstr, +class STORE_2RI12<bits<32> op> + : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12_addlike:$imm12), "$rd, $rj, $imm12">; -class STORE_2RI14<bits<8> op, string opstr> - : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), opstr, +class STORE_2RI14<bits<32> op> + : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), "$rd, $rj, $imm14">; -} // mayStore = 1 +} // hasSideEffects = 0, mayLoad = 0, mayStore = 1 -let mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in -class AM_3R<bits<17> op, string opstr> - : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj), opstr, +let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in +class AM_3R<bits<32> op> + : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj), "$rd, $rk, $rj">; -let mayLoad = 1 in -class LLBase<bits<8> op, string opstr> - : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), opstr, +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class LLBase<bits<32> op> + : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14), "$rd, $rj, $imm14">; -let mayStore = 1, Constraints = "$rd = $dst" in -class SCBase<bits<8> op, string opstr> +let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in +class SCBase<bits<32> op> : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14), - opstr, "$rd, $rj, $imm14">; + "$rd, $rj, $imm14">; -class IOCSRRD<bits<22> op, string opstr> - : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), opstr, "$rd, $rj">; +let hasSideEffects = 1 in +class IOCSRRD<bits<32> op> + : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">; -class IOCSRWR<bits<22> op, string opstr> - : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), opstr, "$rd, $rj">; +let hasSideEffects = 1 in +class IOCSRWR<bits<32> op> + : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), "$rd, $rj">; //===----------------------------------------------------------------------===// // Basic Integer Instructions //===----------------------------------------------------------------------===// // Arithmetic Operation Instructions -def ADD_W : ALU_3R<0b00000000000100000, "add.w">; -def SUB_W : ALU_3R<0b00000000000100010, "sub.w">; -def ADDI_W : ALU_2RI12<0b0000001010, "addi.w", simm12_addlike>; -def ALSL_W : ALU_3RI2<0b000000000000010, "alsl.w", uimm2_plus1>; -def LU12I_W : ALU_1RI20<0b0001010, "lu12i.w", simm20_lu12iw>; -def SLT : ALU_3R<0b00000000000100100, "slt">; -def SLTU : ALU_3R<0b00000000000100101, "sltu">; -def SLTI : ALU_2RI12<0b0000001000, "slti", simm12>; -def SLTUI : ALU_2RI12<0b0000001001, "sltui", simm12>; -def PCADDI : ALU_1RI20<0b0001100, "pcaddi", simm20>; -def PCADDU12I : ALU_1RI20<0b0001110, "pcaddu12i", simm20>; -def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20_pcalau12i>; -def AND : ALU_3R<0b00000000000101001, "and">; -def OR : ALU_3R<0b00000000000101010, "or">; -def NOR : ALU_3R<0b00000000000101000, "nor">; -def XOR : ALU_3R<0b00000000000101011, "xor">; -def ANDN : ALU_3R<0b00000000000101101, "andn">; -def ORN : ALU_3R<0b00000000000101100, "orn">; -def ANDI : ALU_2RI12<0b0000001101, "andi", uimm12>; -def ORI : ALU_2RI12<0b0000001110, "ori", uimm12_ori>; -def XORI : ALU_2RI12<0b0000001111, "xori", uimm12>; -def MUL_W : ALU_3R<0b00000000000111000, "mul.w">; -def MULH_W : ALU_3R<0b00000000000111001, "mulh.w">; -def MULH_WU : ALU_3R<0b00000000000111010, "mulh.wu">; +def ADD_W : ALU_3R<0x00100000>; +def SUB_W : ALU_3R<0x00110000>; +def ADDI_W : ALU_2RI12<0x02800000, simm12_addlike>; +def ALSL_W : ALU_3RI2<0x00040000, uimm2_plus1>; +def LU12I_W : ALU_1RI20<0x14000000, simm20_lu12iw>; +def SLT : ALU_3R<0x00120000>; +def SLTU : ALU_3R<0x00128000>; +def SLTI : ALU_2RI12<0x02000000, simm12>; +def SLTUI : ALU_2RI12<0x02400000, simm12>; +def PCADDI : ALU_1RI20<0x18000000, simm20>; +def PCADDU12I : ALU_1RI20<0x1c000000, simm20>; +def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>; +def AND : ALU_3R<0x00148000>; +def OR : ALU_3R<0x00150000>; +def NOR : ALU_3R<0x00140000>; +def XOR : ALU_3R<0x00158000>; +def ANDN : ALU_3R<0x00168000>; +def ORN : ALU_3R<0x00160000>; +def ANDI : ALU_2RI12<0x03400000, uimm12>; +def ORI : ALU_2RI12<0x03800000, uimm12_ori>; +def XORI : ALU_2RI12<0x03c00000, uimm12>; +def MUL_W : ALU_3R<0x001c0000>; +def MULH_W : ALU_3R<0x001c8000>; +def MULH_WU : ALU_3R<0x001d0000>; let usesCustomInserter = true in { -def DIV_W : ALU_3R<0b00000000001000000, "div.w">; -def MOD_W : ALU_3R<0b00000000001000001, "mod.w">; -def DIV_WU : ALU_3R<0b00000000001000010, "div.wu">; -def MOD_WU : ALU_3R<0b00000000001000011, "mod.wu">; +def DIV_W : ALU_3R<0x00200000>; +def MOD_W : ALU_3R<0x00208000>; +def DIV_WU : ALU_3R<0x00210000>; +def MOD_WU : ALU_3R<0x00218000>; } // usesCustomInserter = true // Bit-shift Instructions -def SLL_W : ALU_3R<0b00000000000101110, "sll.w">; -def SRL_W : ALU_3R<0b00000000000101111, "srl.w">; -def SRA_W : ALU_3R<0b00000000000110000, "sra.w">; -def ROTR_W : ALU_3R<0b00000000000110110, "rotr.w">; +def SLL_W : ALU_3R<0x00170000>; +def SRL_W : ALU_3R<0x00178000>; +def SRA_W : ALU_3R<0x00180000>; +def ROTR_W : ALU_3R<0x001b0000>; -def SLLI_W : ALU_2RI5<0b00000000010000001, "slli.w", uimm5>; -def SRLI_W : ALU_2RI5<0b00000000010001001, "srli.w", uimm5>; -def SRAI_W : ALU_2RI5<0b00000000010010001, "srai.w", uimm5>; -def ROTRI_W : ALU_2RI5<0b00000000010011001, "rotri.w", uimm5>; +def SLLI_W : ALU_2RI5<0x00408000, uimm5>; +def SRLI_W : ALU_2RI5<0x00448000, uimm5>; +def SRAI_W : ALU_2RI5<0x00488000, uimm5>; +def ROTRI_W : ALU_2RI5<0x004c8000, uimm5>; // Bit-manipulation Instructions -def EXT_W_B : ALU_2R<0b0000000000000000010111, "ext.w.b">; -def EXT_W_H : ALU_2R<0b0000000000000000010110, "ext.w.h">; -def CLO_W : ALU_2R<0b0000000000000000000100, "clo.w">; -def CLZ_W : ALU_2R<0b0000000000000000000101, "clz.w">; -def CTO_W : ALU_2R<0b0000000000000000000110, "cto.w">; -def CTZ_W : ALU_2R<0b0000000000000000000111, "ctz.w">; -def BYTEPICK_W : ALU_3RI2<0b000000000000100, "bytepick.w", uimm2>; -def REVB_2H : ALU_2R<0b0000000000000000001100, "revb.2h">; -def BITREV_4B : ALU_2R<0b0000000000000000010010, "bitrev.4b">; -def BITREV_W : ALU_2R<0b0000000000000000010100, "bitrev.w">; +def EXT_W_B : ALU_2R<0x00005c00>; +def EXT_W_H : ALU_2R<0x00005800>; +def CLO_W : ALU_2R<0x00001000>; +def CLZ_W : ALU_2R<0x00001400>; +def CTO_W : ALU_2R<0x00001800>; +def CTZ_W : ALU_2R<0x00001c00>; +def BYTEPICK_W : ALU_3RI2<0x00080000, uimm2>; +def REVB_2H : ALU_2R<0x00003000>; +def BITREV_4B : ALU_2R<0x00004800>; +def BITREV_W : ALU_2R<0x00005000>; let Constraints = "$rd = $dst" in { -def BSTRINS_W : FmtBSTR_W<0b000000000110, (outs GPR:$dst), +def BSTRINS_W : FmtBSTR_W<0x00600000, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw), - "bstrins.w", "$rd, $rj, $msbw, $lsbw">; + "$rd, $rj, $msbw, $lsbw">; } -def BSTRPICK_W : FmtBSTR_W<0b000000000111, (outs GPR:$rd), +def BSTRPICK_W : FmtBSTR_W<0x00608000, (outs GPR:$rd), (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw), - "bstrpick.w", "$rd, $rj, $msbw, $lsbw">; -def MASKEQZ : ALU_3R<0b00000000000100110, "maskeqz">; -def MASKNEZ : ALU_3R<0b00000000000100111, "masknez">; + "$rd, $rj, $msbw, $lsbw">; +def MASKEQZ : ALU_3R<0x00130000>; +def MASKNEZ : ALU_3R<0x00138000>; // Branch Instructions -def BEQ : BrCC_2RI16<0b010110, "beq">; -def BNE : BrCC_2RI16<0b010111, "bne">; -def BLT : BrCC_2RI16<0b011000, "blt">; -def BGE : BrCC_2RI16<0b011001, "bge">; -def BLTU : BrCC_2RI16<0b011010, "bltu">; -def BGEU : BrCC_2RI16<0b011011, "bgeu">; -def BEQZ : BrCCZ_1RI21<0b010000, "beqz">; -def BNEZ : BrCCZ_1RI21<0b010001, "bnez">; -def B : Br_I26<0b010100, "b">; - -let isCall = 1, Defs=[R1] in -def BL : FmtI26<0b010101, (outs), (ins simm26_symbol:$imm26), "bl", "$imm26">; -def JIRL : Fmt2RI16<0b010011, (outs GPR:$rd), - (ins GPR:$rj, simm16_lsl2:$imm16), "jirl", - "$rd, $rj, $imm16">; +def BEQ : BrCC_2RI16<0x58000000>; +def BNE : BrCC_2RI16<0x5c000000>; +def BLT : BrCC_2RI16<0x60000000>; +def BGE : BrCC_2RI16<0x64000000>; +def BLTU : BrCC_2RI16<0x68000000>; +def BGEU : BrCC_2RI16<0x6c000000>; +def BEQZ : BrCCZ_1RI21<0x40000000>; +def BNEZ : BrCCZ_1RI21<0x44000000>; +def B : Br_I26<0x50000000>; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, Defs=[R1] in +def BL : FmtI26<0x54000000, (outs), (ins simm26_symbol:$imm26), "$imm26">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def JIRL : Fmt2RI16<0x4c000000, (outs GPR:$rd), + (ins GPR:$rj, simm16_lsl2:$imm16), "$rd, $rj, $imm16">; // Common Memory Access Instructions -def LD_B : LOAD_2RI12<0b0010100000, "ld.b">; -def LD_H : LOAD_2RI12<0b0010100001, "ld.h">; -def LD_W : LOAD_2RI12<0b0010100010, "ld.w">; -def LD_BU : LOAD_2RI12<0b0010101000, "ld.bu">; -def LD_HU : LOAD_2RI12<0b0010101001, "ld.hu">; -def ST_B : STORE_2RI12<0b0010100100, "st.b">; -def ST_H : STORE_2RI12<0b0010100101, "st.h">; -def ST_W : STORE_2RI12<0b0010100110, "st.w">; -def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), "preld", +def LD_B : LOAD_2RI12<0x28000000>; +def LD_H : LOAD_2RI12<0x28400000>; +def LD_W : LOAD_2RI12<0x28800000>; +def LD_BU : LOAD_2RI12<0x2a000000>; +def LD_HU : LOAD_2RI12<0x2a400000>; +def ST_B : STORE_2RI12<0x29000000>; +def ST_H : STORE_2RI12<0x29400000>; +def ST_W : STORE_2RI12<0x29800000>; +let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in +def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), "$imm5, $rj, $imm12">; // Atomic Memory Access Instructions -def LL_W : LLBase<0b00100000, "ll.w">; -def SC_W : SCBase<0b00100001, "sc.w">; +def LL_W : LLBase<0x20000000>; +def SC_W : SCBase<0x21000000>; // Barrier Instructions -def DBAR : MISC_I15<0b00111000011100100, "dbar">; -def IBAR : MISC_I15<0b00111000011100101, "ibar">; +def DBAR : MISC_I15<0x38720000>; +def IBAR : MISC_I15<0x38728000>; // Other Miscellaneous Instructions -def SYSCALL : MISC_I15<0b00000000001010110, "syscall">; -def BREAK : MISC_I15<0b00000000001010100, "break">; -def RDTIMEL_W : RDTIME_2R<0b0000000000000000011000, "rdtimel.w">; -def RDTIMEH_W : RDTIME_2R<0b0000000000000000011001, "rdtimeh.w">; -def CPUCFG : ALU_2R<0b0000000000000000011011, "cpucfg">; +def SYSCALL : MISC_I15<0x002b0000>; +def BREAK : MISC_I15<0x002a0000>; +def RDTIMEL_W : RDTIME_2R<0x00006000>; +def RDTIMEH_W : RDTIME_2R<0x00006400>; +def CPUCFG : ALU_2R<0x00006c00>; // Cache Maintenance Instructions -def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), "cacop", +def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), "$op, $rj, $imm12">; /// LA64 instructions @@ -598,159 +758,161 @@ def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), "cacop", let Predicates = [IsLA64] in { // Arithmetic Operation Instructions for 64-bits -def ADD_D : ALU_3R<0b00000000000100001, "add.d">; -def SUB_D : ALU_3R<0b00000000000100011, "sub.d">; -def ADDI_D : ALU_2RI12<0b0000001011, "addi.d", simm12_addlike>; -def ADDU16I_D : ALU_2RI16<0b000100, "addu16i.d", simm16>; -def ALSL_WU : ALU_3RI2<0b000000000000011, "alsl.wu", uimm2_plus1>; -def ALSL_D : ALU_3RI2<0b000000000010110, "alsl.d", uimm2_plus1>; +def ADD_D : ALU_3R<0x00108000>; +def SUB_D : ALU_3R<0x00118000>; +def ADDI_D : ALU_2RI12<0x02c00000, simm12_addlike>; +def ADDU16I_D : ALU_2RI16<0x10000000, simm16>; +def ALSL_WU : ALU_3RI2<0x00060000, uimm2_plus1>; +def ALSL_D : ALU_3RI2<0x002c0000, uimm2_plus1>; let Constraints = "$rd = $dst" in { -def LU32I_D : Fmt1RI20<0b0001011, (outs GPR:$dst), - (ins GPR:$rd, simm20_lu32id:$imm20), "lu32i.d", +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def LU32I_D : Fmt1RI20<0x16000000, (outs GPR:$dst), + (ins GPR:$rd, simm20_lu32id:$imm20), "$rd, $imm20">; } -def LU52I_D : ALU_2RI12<0b0000001100, "lu52i.d", simm12_lu52id>; -def PCADDU18I : ALU_1RI20<0b0001111, "pcaddu18i", simm20>; -def MUL_D : ALU_3R<0b00000000000111011, "mul.d">; -def MULH_D : ALU_3R<0b00000000000111100, "mulh.d">; -def MULH_DU : ALU_3R<0b00000000000111101, "mulh.du">; -def MULW_D_W : ALU_3R<0b00000000000111110, "mulw.d.w">; -def MULW_D_WU : ALU_3R<0b00000000000111111, "mulw.d.wu">; +def LU52I_D : ALU_2RI12<0x03000000, simm12_lu52id>; +def PCADDU18I : ALU_1RI20<0x1e000000, simm20>; +def MUL_D : ALU_3R<0x001d8000>; +def MULH_D : ALU_3R<0x001e0000>; +def MULH_DU : ALU_3R<0x001e8000>; +def MULW_D_W : ALU_3R<0x001f0000>; +def MULW_D_WU : ALU_3R<0x001f8000>; let usesCustomInserter = true in { -def DIV_D : ALU_3R<0b00000000001000100, "div.d">; -def MOD_D : ALU_3R<0b00000000001000101, "mod.d">; -def DIV_DU : ALU_3R<0b00000000001000110, "div.du">; -def MOD_DU : ALU_3R<0b00000000001000111, "mod.du">; +def DIV_D : ALU_3R<0x00220000>; +def MOD_D : ALU_3R<0x00228000>; +def DIV_DU : ALU_3R<0x00230000>; +def MOD_DU : ALU_3R<0x00238000>; } // usesCustomInserter = true // Bit-shift Instructions for 64-bits -def SLL_D : ALU_3R<0b00000000000110001, "sll.d">; -def SRL_D : ALU_3R<0b00000000000110010, "srl.d">; -def SRA_D : ALU_3R<0b00000000000110011, "sra.d">; -def ROTR_D : ALU_3R<0b00000000000110111, "rotr.d">; -def SLLI_D : ALU_2RI6<0b0000000001000001, "slli.d", uimm6>; -def SRLI_D : ALU_2RI6<0b0000000001000101, "srli.d", uimm6>; -def SRAI_D : ALU_2RI6<0b0000000001001001, "srai.d", uimm6>; -def ROTRI_D : ALU_2RI6<0b0000000001001101, "rotri.d", uimm6>; +def SLL_D : ALU_3R<0x00188000>; +def SRL_D : ALU_3R<0x00190000>; +def SRA_D : ALU_3R<0x00198000>; +def ROTR_D : ALU_3R<0x001b8000>; +def SLLI_D : ALU_2RI6<0x00410000, uimm6>; +def SRLI_D : ALU_2RI6<0x00450000, uimm6>; +def SRAI_D : ALU_2RI6<0x00490000, uimm6>; +def ROTRI_D : ALU_2RI6<0x004d0000, uimm6>; // Bit-manipulation Instructions for 64-bits -def CLO_D : ALU_2R<0b0000000000000000001000, "clo.d">; -def CLZ_D : ALU_2R<0b0000000000000000001001, "clz.d">; -def CTO_D : ALU_2R<0b0000000000000000001010, "cto.d">; -def CTZ_D : ALU_2R<0b0000000000000000001011, "ctz.d">; -def BYTEPICK_D : ALU_3RI3<0b00000000000011, "bytepick.d", uimm3>; -def REVB_4H : ALU_2R<0b0000000000000000001101, "revb.4h">; -def REVB_2W : ALU_2R<0b0000000000000000001110, "revb.2w">; -def REVB_D : ALU_2R<0b0000000000000000001111, "revb.d">; -def REVH_2W : ALU_2R<0b0000000000000000010000, "revh.2w">; -def REVH_D : ALU_2R<0b0000000000000000010001, "revh.d">; -def BITREV_8B : ALU_2R<0b0000000000000000010011, "bitrev.8b">; -def BITREV_D : ALU_2R<0b0000000000000000010101, "bitrev.d">; +def CLO_D : ALU_2R<0x00002000>; +def CLZ_D : ALU_2R<0x00002400>; +def CTO_D : ALU_2R<0x00002800>; +def CTZ_D : ALU_2R<0x00002c00>; +def BYTEPICK_D : ALU_3RI3<0x000c0000, uimm3>; +def REVB_4H : ALU_2R<0x00003400>; +def REVB_2W : ALU_2R<0x00003800>; +def REVB_D : ALU_2R<0x00003c00>; +def REVH_2W : ALU_2R<0x00004000>; +def REVH_D : ALU_2R<0x00004400>; +def BITREV_8B : ALU_2R<0x00004c00>; +def BITREV_D : ALU_2R<0x00005400>; let Constraints = "$rd = $dst" in { -def BSTRINS_D : FmtBSTR_D<0b0000000010, (outs GPR:$dst), +def BSTRINS_D : FmtBSTR_D<0x00800000, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), - "bstrins.d", "$rd, $rj, $msbd, $lsbd">; + "$rd, $rj, $msbd, $lsbd">; } -def BSTRPICK_D : FmtBSTR_D<0b0000000011, (outs GPR:$rd), +def BSTRPICK_D : FmtBSTR_D<0x00c00000, (outs GPR:$rd), (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd), - "bstrpick.d", "$rd, $rj, $msbd, $lsbd">; + "$rd, $rj, $msbd, $lsbd">; // Common Memory Access Instructions for 64-bits -def LD_WU : LOAD_2RI12<0b0010101010, "ld.wu">; -def LD_D : LOAD_2RI12<0b0010100011, "ld.d">; -def ST_D : STORE_2RI12<0b0010100111, "st.d">; -def LDX_B : LOAD_3R<0b00111000000000000, "ldx.b">; -def LDX_H : LOAD_3R<0b00111000000001000, "ldx.h">; -def LDX_W : LOAD_3R<0b00111000000010000, "ldx.w">; -def LDX_D : LOAD_3R<0b00111000000011000, "ldx.d">; -def LDX_BU : LOAD_3R<0b00111000001000000, "ldx.bu">; -def LDX_HU : LOAD_3R<0b00111000001001000, "ldx.hu">; -def LDX_WU : LOAD_3R<0b00111000001010000, "ldx.wu">; -def STX_B : STORE_3R<0b00111000000100000, "stx.b">; -def STX_H : STORE_3R<0b00111000000101000, "stx.h">; -def STX_W : STORE_3R<0b00111000000110000, "stx.w">; -def STX_D : STORE_3R<0b00111000000111000, "stx.d">; -def LDPTR_W : LOAD_2RI14<0b00100100, "ldptr.w">; -def LDPTR_D : LOAD_2RI14<0b00100110, "ldptr.d">; -def STPTR_W : STORE_2RI14<0b00100101, "stptr.w">; -def STPTR_D : STORE_2RI14<0b00100111, "stptr.d">; -def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), "preldx", +def LD_WU : LOAD_2RI12<0x2a800000>; +def LD_D : LOAD_2RI12<0x28c00000>; +def ST_D : STORE_2RI12<0x29c00000>; +def LDX_B : LOAD_3R<0x38000000>; +def LDX_H : LOAD_3R<0x38040000>; +def LDX_W : LOAD_3R<0x38080000>; +def LDX_D : LOAD_3R<0x380c0000>; +def LDX_BU : LOAD_3R<0x38200000>; +def LDX_HU : LOAD_3R<0x38240000>; +def LDX_WU : LOAD_3R<0x38280000>; +def STX_B : STORE_3R<0x38100000>; +def STX_H : STORE_3R<0x38140000>; +def STX_W : STORE_3R<0x38180000>; +def STX_D : STORE_3R<0x381c0000>; +def LDPTR_W : LOAD_2RI14<0x24000000>; +def LDPTR_D : LOAD_2RI14<0x26000000>; +def STPTR_W : STORE_2RI14<0x25000000>; +def STPTR_D : STORE_2RI14<0x27000000>; +let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in +def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), "$imm5, $rj, $rk">; // Bound Check Memory Access Instructions -def LDGT_B : LOAD_3R<0b00111000011110000, "ldgt.b">; -def LDGT_H : LOAD_3R<0b00111000011110001, "ldgt.h">; -def LDGT_W : LOAD_3R<0b00111000011110010, "ldgt.w">; -def LDGT_D : LOAD_3R<0b00111000011110011, "ldgt.d">; -def LDLE_B : LOAD_3R<0b00111000011110100, "ldle.b">; -def LDLE_H : LOAD_3R<0b00111000011110101, "ldle.h">; -def LDLE_W : LOAD_3R<0b00111000011110110, "ldle.w">; -def LDLE_D : LOAD_3R<0b00111000011110111, "ldle.d">; -def STGT_B : STORE_3R<0b00111000011111000, "stgt.b">; -def STGT_H : STORE_3R<0b00111000011111001, "stgt.h">; -def STGT_W : STORE_3R<0b00111000011111010, "stgt.w">; -def STGT_D : STORE_3R<0b00111000011111011, "stgt.d">; -def STLE_B : STORE_3R<0b00111000011111100, "stle.b">; -def STLE_H : STORE_3R<0b00111000011111101, "stle.h">; -def STLE_W : STORE_3R<0b00111000011111110, "stle.w">; -def STLE_D : STORE_3R<0b00111000011111111, "stle.d">; +def LDGT_B : LOAD_3R<0x38780000>; +def LDGT_H : LOAD_3R<0x38788000>; +def LDGT_W : LOAD_3R<0x38790000>; +def LDGT_D : LOAD_3R<0x38798000>; +def LDLE_B : LOAD_3R<0x387a0000>; +def LDLE_H : LOAD_3R<0x387a8000>; +def LDLE_W : LOAD_3R<0x387b0000>; +def LDLE_D : LOAD_3R<0x387b8000>; +def STGT_B : STORE_3R<0x387c0000>; +def STGT_H : STORE_3R<0x387c8000>; +def STGT_W : STORE_3R<0x387d0000>; +def STGT_D : STORE_3R<0x387d8000>; +def STLE_B : STORE_3R<0x387e0000>; +def STLE_H : STORE_3R<0x387e8000>; +def STLE_W : STORE_3R<0x387f0000>; +def STLE_D : STORE_3R<0x387f8000>; // Atomic Memory Access Instructions for 64-bits -def AMSWAP_W : AM_3R<0b00111000011000000, "amswap.w">; -def AMSWAP_D : AM_3R<0b00111000011000001, "amswap.d">; -def AMADD_W : AM_3R<0b00111000011000010, "amadd.w">; -def AMADD_D : AM_3R<0b00111000011000011, "amadd.d">; -def AMAND_W : AM_3R<0b00111000011000100, "amand.w">; -def AMAND_D : AM_3R<0b00111000011000101, "amand.d">; -def AMOR_W : AM_3R<0b00111000011000110, "amor.w">; -def AMOR_D : AM_3R<0b00111000011000111, "amor.d">; -def AMXOR_W : AM_3R<0b00111000011001000, "amxor.w">; -def AMXOR_D : AM_3R<0b00111000011001001, "amxor.d">; -def AMMAX_W : AM_3R<0b00111000011001010, "ammax.w">; -def AMMAX_D : AM_3R<0b00111000011001011, "ammax.d">; -def AMMIN_W : AM_3R<0b00111000011001100, "ammin.w">; -def AMMIN_D : AM_3R<0b00111000011001101, "ammin.d">; -def AMMAX_WU : AM_3R<0b00111000011001110, "ammax.wu">; -def AMMAX_DU : AM_3R<0b00111000011001111, "ammax.du">; -def AMMIN_WU : AM_3R<0b00111000011010000, "ammin.wu">; -def AMMIN_DU : AM_3R<0b00111000011010001, "ammin.du">; -def AMSWAP_DB_W : AM_3R<0b00111000011010010, "amswap_db.w">; -def AMSWAP_DB_D : AM_3R<0b00111000011010011, "amswap_db.d">; -def AMADD_DB_W : AM_3R<0b00111000011010100, "amadd_db.w">; -def AMADD_DB_D : AM_3R<0b00111000011010101, "amadd_db.d">; -def AMAND_DB_W : AM_3R<0b00111000011010110, "amand_db.w">; -def AMAND_DB_D : AM_3R<0b00111000011010111, "amand_db.d">; -def AMOR_DB_W : AM_3R<0b00111000011011000, "amor_db.w">; -def AMOR_DB_D : AM_3R<0b00111000011011001, "amor_db.d">; -def AMXOR_DB_W : AM_3R<0b00111000011011010, "amxor_db.w">; -def AMXOR_DB_D : AM_3R<0b00111000011011011, "amxor_db.d">; -def AMMAX_DB_W : AM_3R<0b00111000011011100, "ammax_db.w">; -def AMMAX_DB_D : AM_3R<0b00111000011011101, "ammax_db.d">; -def AMMIN_DB_W : AM_3R<0b00111000011011110, "ammin_db.w">; -def AMMIN_DB_D : AM_3R<0b00111000011011111, "ammin_db.d">; -def AMMAX_DB_WU : AM_3R<0b00111000011100000, "ammax_db.wu">; -def AMMAX_DB_DU : AM_3R<0b00111000011100001, "ammax_db.du">; -def AMMIN_DB_WU : AM_3R<0b00111000011100010, "ammin_db.wu">; -def AMMIN_DB_DU : AM_3R<0b00111000011100011, "ammin_db.du">; -def LL_D : LLBase<0b00100010, "ll.d">; -def SC_D : SCBase<0b00100011, "sc.d">; +def AMSWAP_W : AM_3R<0x38600000>; +def AMSWAP_D : AM_3R<0x38608000>; +def AMADD_W : AM_3R<0x38610000>; +def AMADD_D : AM_3R<0x38618000>; +def AMAND_W : AM_3R<0x38620000>; +def AMAND_D : AM_3R<0x38628000>; +def AMOR_W : AM_3R<0x38630000>; +def AMOR_D : AM_3R<0x38638000>; +def AMXOR_W : AM_3R<0x38640000>; +def AMXOR_D : AM_3R<0x38648000>; +def AMMAX_W : AM_3R<0x38650000>; +def AMMAX_D : AM_3R<0x38658000>; +def AMMIN_W : AM_3R<0x38660000>; +def AMMIN_D : AM_3R<0x38668000>; +def AMMAX_WU : AM_3R<0x38670000>; +def AMMAX_DU : AM_3R<0x38678000>; +def AMMIN_WU : AM_3R<0x38680000>; +def AMMIN_DU : AM_3R<0x38688000>; +def AMSWAP__DB_W : AM_3R<0x38690000>; +def AMSWAP__DB_D : AM_3R<0x38698000>; +def AMADD__DB_W : AM_3R<0x386a0000>; +def AMADD__DB_D : AM_3R<0x386a8000>; +def AMAND__DB_W : AM_3R<0x386b0000>; +def AMAND__DB_D : AM_3R<0x386b8000>; +def AMOR__DB_W : AM_3R<0x386c0000>; +def AMOR__DB_D : AM_3R<0x386c8000>; +def AMXOR__DB_W : AM_3R<0x386d0000>; +def AMXOR__DB_D : AM_3R<0x386d8000>; +def AMMAX__DB_W : AM_3R<0x386e0000>; +def AMMAX__DB_D : AM_3R<0x386e8000>; +def AMMIN__DB_W : AM_3R<0x386f0000>; +def AMMIN__DB_D : AM_3R<0x386f8000>; +def AMMAX__DB_WU : AM_3R<0x38700000>; +def AMMAX__DB_DU : AM_3R<0x38708000>; +def AMMIN__DB_WU : AM_3R<0x38710000>; +def AMMIN__DB_DU : AM_3R<0x38718000>; +def LL_D : LLBase<0x22000000>; +def SC_D : SCBase<0x23000000>; // CRC Check Instructions -def CRC_W_B_W : ALU_3R<0b00000000001001000, "crc.w.b.w">; -def CRC_W_H_W : ALU_3R<0b00000000001001001, "crc.w.h.w">; -def CRC_W_W_W : ALU_3R<0b00000000001001010, "crc.w.w.w">; -def CRC_W_D_W : ALU_3R<0b00000000001001011, "crc.w.d.w">; -def CRCC_W_B_W : ALU_3R<0b00000000001001100, "crcc.w.b.w">; -def CRCC_W_H_W : ALU_3R<0b00000000001001101, "crcc.w.h.w">; -def CRCC_W_W_W : ALU_3R<0b00000000001001110, "crcc.w.w.w">; -def CRCC_W_D_W : ALU_3R<0b00000000001001111, "crcc.w.d.w">; +def CRC_W_B_W : ALU_3R<0x00240000>; +def CRC_W_H_W : ALU_3R<0x00248000>; +def CRC_W_W_W : ALU_3R<0x00250000>; +def CRC_W_D_W : ALU_3R<0x00258000>; +def CRCC_W_B_W : ALU_3R<0x00260000>; +def CRCC_W_H_W : ALU_3R<0x00268000>; +def CRCC_W_W_W : ALU_3R<0x00270000>; +def CRCC_W_D_W : ALU_3R<0x00278000>; // Other Miscellaneous Instructions for 64-bits -def ASRTLE_D : FmtASRT<0b00000000000000010, (outs), (ins GPR:$rj, GPR:$rk), - "asrtle.d", "$rj, $rk">; -def ASRTGT_D : FmtASRT<0b00000000000000011, (outs), (ins GPR:$rj, GPR:$rk), - "asrtgt.d", "$rj, $rk">; -def RDTIME_D : RDTIME_2R<0b0000000000000000011010, "rdtime.d">; +def ASRTLE_D : FmtASRT<0x00010000, (outs), (ins GPR:$rj, GPR:$rk), + "$rj, $rk">; +def ASRTGT_D : FmtASRT<0x00018000, (outs), (ins GPR:$rj, GPR:$rk), + "$rj, $rk">; +def RDTIME_D : RDTIME_2R<0x00006800>; } // Predicates = [IsLA64] //===----------------------------------------------------------------------===// @@ -802,6 +964,13 @@ class shiftopw<SDPatternOperator operator> : PatFrag<(ops node:$val, node:$count), (operator node:$val, (i64 (shiftMask32 node:$count)))>; +def mul_const_oneuse : PatFrag<(ops node:$A, node:$B), + (mul node:$A, node:$B), [{ + if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1))) + return N1C->hasOneUse(); + return false; +}]>; + let Predicates = [IsLA32] in { def : PatGprGpr<add, ADD_W>; def : PatGprImm<add, ADDI_W, simm12>; @@ -815,6 +984,13 @@ def : PatGprGpr<mulhs, MULH_W>; def : PatGprGpr<mulhu, MULH_WU>; def : PatGprGpr<rotr, ROTR_W>; def : PatGprImm<rotr, ROTRI_W, uimm5>; + +foreach Idx = 1...3 in { + defvar ShamtA = !mul(8, Idx); + defvar ShamtB = !mul(8, !sub(4, Idx)); + def : Pat<(or (shl GPR:$rk, (i32 ShamtA)), (srl GPR:$rj, (i32 ShamtB))), + (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; +} } // Predicates = [IsLA32] let Predicates = [IsLA64] in { @@ -850,6 +1026,109 @@ def : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))), def : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)), (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))), (MULW_D_WU GPR:$rj, GPR:$rk)>; + +def : Pat<(add GPR:$rj, simm16_lsl16:$imm), + (ADDU16I_D GPR:$rj, (HI16 $imm))>; +def : Pat<(add GPR:$rj, simm32_hi16_lo12:$imm), + (ADDI_D (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), + (LO12 $imm))>; +def : Pat<(sext_inreg (add GPR:$rj, simm32_hi16_lo12:$imm), i32), + (ADDI_W (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), + (LO12 $imm))>; + +let Predicates = [IsLA32] in { +def : Pat<(add GPR:$rj, (AddiPair:$im)), + (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), + (AddiPairImmSmall AddiPair:$im))>; +} // Predicates = [IsLA32] + +let Predicates = [IsLA64] in { +def : Pat<(add GPR:$rj, (AddiPair:$im)), + (ADDI_D (ADDI_D GPR:$rj, (AddiPairImmLarge AddiPair:$im)), + (AddiPairImmSmall AddiPair:$im))>; +def : Pat<(sext_inreg (add GPR:$rj, (AddiPair:$im)), i32), + (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), + (AddiPairImmSmall AddiPair:$im))>; +} // Predicates = [IsLA64] + +let Predicates = [IsLA32] in { +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); + def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), + GPR:$r, (i32 Idx1))>; + } +} +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar Cb = !add(1, !shl(1, Idx0)); + defvar CImm = !add(Cb, !shl(Cb, Idx1)); + def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), + (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>; + } +} +} // Predicates = [IsLA32] + +let Predicates = [IsLA64] in { +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); + def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), + GPR:$r, (i64 Idx1))>; + def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), + (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), + GPR:$r, (i64 Idx1))>; + } +} +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar Cb = !add(1, !shl(1, Idx0)); + defvar CImm = !add(Cb, !shl(Cb, Idx1)); + def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), + (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; + def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), + (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), + (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; + } +} +} // Predicates = [IsLA64] + +let Predicates = [IsLA32] in { +def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), + (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), + (AlslSlliImmI1 AlslSlliImm:$im))>; +} // Predicates = [IsLA32] + +let Predicates = [IsLA64] in { +def : Pat<(sext_inreg (mul GPR:$rj, (AlslSlliImm:$im)), i32), + (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), + (AlslSlliImmI1 AlslSlliImm:$im))>; +def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), + (SLLI_D (ALSL_D GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), + (AlslSlliImmI1 AlslSlliImm:$im))>; +} // Predicates = [IsLA64] + +foreach Idx = 1...7 in { + defvar ShamtA = !mul(8, Idx); + defvar ShamtB = !mul(8, !sub(8, Idx)); + def : Pat<(or (shl GPR:$rk, (i64 ShamtA)), (srl GPR:$rj, (i64 ShamtB))), + (BYTEPICK_D GPR:$rj, GPR:$rk, Idx)>; +} + +foreach Idx = 1...3 in { + defvar ShamtA = !mul(8, Idx); + defvar ShamtB = !mul(8, !sub(4, Idx)); + // NOTE: the srl node would already be transformed into a loongarch_bstrpick + // by the time this pattern gets to execute, hence the weird construction. + def : Pat<(sext_inreg (or (shl GPR:$rk, (i64 ShamtA)), + (loongarch_bstrpick GPR:$rj, (i64 31), + (i64 ShamtB))), i32), + (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; +} } // Predicates = [IsLA64] def : PatGprGpr<and, AND>; @@ -916,6 +1195,8 @@ def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), let Predicates = [IsLA64] in { def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), (ALSL_D GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; +def : Pat<(sext_inreg (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), i32), + (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; def : Pat<(loongarch_bstrpick (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), (i64 31), (i64 0)), (ALSL_WU GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; @@ -991,6 +1272,8 @@ def : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>; /// Select +def : Pat<(select GPR:$cond, GPR:$t, 0), (MASKEQZ GPR:$t, GPR:$cond)>; +def : Pat<(select GPR:$cond, 0, GPR:$f), (MASKNEZ GPR:$f, GPR:$cond)>; def : Pat<(select GPR:$cond, GPR:$t, GPR:$f), (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>; @@ -1050,7 +1333,7 @@ def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj), [(loongarch_call GPR:$rj)]>, PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>; -let isCall = 1, Defs = [R1] in +let isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, PseudoInstExpansion<(JIRL R1, GPR:$rj, simm16_lsl2:$imm16)>; @@ -1072,11 +1355,13 @@ def PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj), [(loongarch_tail GPRT:$rj)]>, PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>; -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, + hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in def PseudoB_TAIL : Pseudo<(outs), (ins simm26_b:$imm26)>, PseudoInstExpansion<(B simm26_b:$imm26)>; -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, + hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in def PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>; @@ -1219,6 +1504,8 @@ def : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_8B GPR:$rj)>; multiclass LdPat<PatFrag LoadOp, LAInst Inst, ValueType vt = GRLenVT> { def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>; + def : Pat<(vt (LoadOp (AddrConstant GPR:$rj, simm12:$imm12))), + (Inst GPR:$rj, simm12:$imm12)>; def : Pat<(vt (LoadOp (AddLike BaseAddr:$rj, simm12:$imm12))), (Inst BaseAddr:$rj, simm12:$imm12)>; } @@ -1261,6 +1548,8 @@ multiclass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy, ValueType vt> { def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj), (Inst StTy:$rd, BaseAddr:$rj, 0)>; + def : Pat<(StoreOp (vt StTy:$rs2), (AddrConstant GPR:$rj, simm12:$imm12)), + (Inst StTy:$rs2, GPR:$rj, simm12:$imm12)>; def : Pat<(StoreOp (vt StTy:$rd), (AddLike BaseAddr:$rj, simm12:$imm12)), (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>; } @@ -1342,7 +1631,7 @@ defm : AtomicStPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i32>, def PseudoAtomicStoreW : Pseudo<(outs GPR:$dst), (ins GPR:$rj, GPR:$rk)>, - PseudoInstExpansion<(AMSWAP_DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>; + PseudoInstExpansion<(AMSWAP__DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>; def : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk), (PseudoAtomicStoreW GPR:$rj, GPR:$rk)>; @@ -1350,7 +1639,7 @@ def : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk), let Predicates = [IsLA64] in { def PseudoAtomicStoreD : Pseudo<(outs GPR:$dst), (ins GPR:$rj, GPR:$rk)>, - PseudoInstExpansion<(AMSWAP_DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>; + PseudoInstExpansion<(AMSWAP__DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>; def : Pat<(atomic_store_release_seqcst_64 GPR:$rj, GPR:$rk), (PseudoAtomicStoreD GPR:$rj, GPR:$rk)>; @@ -1477,54 +1766,54 @@ let Predicates = [IsLA64] in { def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64, PseudoMaskedAtomicSwap32>; def : Pat<(atomic_swap_32 GPR:$addr, GPR:$incr), - (AMSWAP_DB_W GPR:$incr, GPR:$addr)>; + (AMSWAP__DB_W GPR:$incr, GPR:$addr)>; def : Pat<(atomic_swap_64 GPR:$addr, GPR:$incr), - (AMSWAP_DB_D GPR:$incr, GPR:$addr)>; + (AMSWAP__DB_D GPR:$incr, GPR:$addr)>; def : Pat<(atomic_load_add_64 GPR:$rj, GPR:$rk), - (AMADD_DB_D GPR:$rk, GPR:$rj)>; + (AMADD__DB_D GPR:$rk, GPR:$rj)>; def : AtomicPat<int_loongarch_masked_atomicrmw_add_i64, PseudoMaskedAtomicLoadAdd32>; def : Pat<(atomic_load_sub_32 GPR:$rj, GPR:$rk), - (AMADD_DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>; + (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>; def : Pat<(atomic_load_sub_64 GPR:$rj, GPR:$rk), - (AMADD_DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>; + (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>; def : AtomicPat<int_loongarch_masked_atomicrmw_sub_i64, PseudoMaskedAtomicLoadSub32>; defm : PseudoBinPat<"atomic_load_nand_64", PseudoAtomicLoadNand64>; def : AtomicPat<int_loongarch_masked_atomicrmw_nand_i64, PseudoMaskedAtomicLoadNand32>; def : Pat<(atomic_load_add_32 GPR:$rj, GPR:$rk), - (AMADD_DB_W GPR:$rk, GPR:$rj)>; + (AMADD__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_and_32 GPR:$rj, GPR:$rk), - (AMAND_DB_W GPR:$rk, GPR:$rj)>; + (AMAND__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_and_64 GPR:$rj, GPR:$rk), - (AMAND_DB_D GPR:$rk, GPR:$rj)>; + (AMAND__DB_D GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_or_32 GPR:$rj, GPR:$rk), - (AMOR_DB_W GPR:$rk, GPR:$rj)>; + (AMOR__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_or_64 GPR:$rj, GPR:$rk), - (AMOR_DB_D GPR:$rk, GPR:$rj)>; + (AMOR__DB_D GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_xor_32 GPR:$rj, GPR:$rk), - (AMXOR_DB_W GPR:$rk, GPR:$rj)>; + (AMXOR__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_xor_64 GPR:$rj, GPR:$rk), - (AMXOR_DB_D GPR:$rk, GPR:$rj)>; + (AMXOR__DB_D GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_umin_32 GPR:$rj, GPR:$rk), - (AMMIN_DB_WU GPR:$rk, GPR:$rj)>; + (AMMIN__DB_WU GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_umin_64 GPR:$rj, GPR:$rk), - (AMMIN_DB_DU GPR:$rk, GPR:$rj)>; + (AMMIN__DB_DU GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_umax_32 GPR:$rj, GPR:$rk), - (AMMAX_DB_WU GPR:$rk, GPR:$rj)>; + (AMMAX__DB_WU GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_umax_64 GPR:$rj, GPR:$rk), - (AMMAX_DB_DU GPR:$rk, GPR:$rj)>; + (AMMAX__DB_DU GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_min_32 GPR:$rj, GPR:$rk), - (AMMIN_DB_W GPR:$rk, GPR:$rj)>; + (AMMIN__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_min_64 GPR:$rj, GPR:$rk), - (AMMIN_DB_D GPR:$rk, GPR:$rj)>; + (AMMIN__DB_D GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_max_32 GPR:$rj, GPR:$rk), - (AMMAX_DB_W GPR:$rk, GPR:$rj)>; + (AMMAX__DB_W GPR:$rk, GPR:$rj)>; def : Pat<(atomic_load_max_64 GPR:$rj, GPR:$rk), - (AMMAX_DB_D GPR:$rk, GPR:$rj)>; + (AMMAX__DB_D GPR:$rk, GPR:$rj)>; def : AtomicPat<int_loongarch_masked_atomicrmw_umax_i64, PseudoMaskedAtomicLoadUMax32>; @@ -1659,48 +1948,52 @@ let Predicates = [HasBasicF], usesCustomInserter = 1 in { //===----------------------------------------------------------------------===// // CSR Access Instructions -def CSRRD : FmtCSR<0b0000010000000, (outs GPR:$rd), (ins uimm14:$csr_num), - "csrrd", "$rd, $csr_num">; -let Constraints = "$rd = $dst" in { -def CSRWR : FmtCSR<0b0000010000001, (outs GPR:$dst), - (ins GPR:$rd, uimm14:$csr_num), "csrwr", "$rd, $csr_num">; -def CSRXCHG : FmtCSRXCHG<0b00000100, (outs GPR:$dst), +let hasSideEffects = 1 in +def CSRRD : FmtCSR<0x04000000, (outs GPR:$rd), (ins uimm14:$csr_num), + "$rd, $csr_num">; +let hasSideEffects = 1, Constraints = "$rd = $dst" in { +def CSRWR : FmtCSR<0x04000020, (outs GPR:$dst), + (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">; +def CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), - "csrxchg", "$rd, $rj, $csr_num">; -} // Constraints = "$rd = $dst" + "$rd, $rj, $csr_num">; +} // hasSideEffects = 1, Constraints = "$rd = $dst" // IOCSR Access Instructions -def IOCSRRD_B : IOCSRRD<0b0000011001001000000000, "iocsrrd.b">; -def IOCSRRD_H : IOCSRRD<0b0000011001001000000001, "iocsrrd.h">; -def IOCSRRD_W : IOCSRRD<0b0000011001001000000010, "iocsrrd.w">; -def IOCSRWR_B : IOCSRWR<0b0000011001001000000100, "iocsrwr.b">; -def IOCSRWR_H : IOCSRWR<0b0000011001001000000101, "iocsrwr.h">; -def IOCSRWR_W : IOCSRWR<0b0000011001001000000110, "iocsrwr.w">; +def IOCSRRD_B : IOCSRRD<0x06480000>; +def IOCSRRD_H : IOCSRRD<0x06480400>; +def IOCSRRD_W : IOCSRRD<0x06480800>; +def IOCSRWR_B : IOCSRWR<0x06481000>; +def IOCSRWR_H : IOCSRWR<0x06481400>; +def IOCSRWR_W : IOCSRWR<0x06481800>; let Predicates = [IsLA64] in { -def IOCSRRD_D : IOCSRRD<0b0000011001001000000011, "iocsrrd.d">; -def IOCSRWR_D : IOCSRWR<0b0000011001001000000111, "iocsrwr.d">; +def IOCSRRD_D : IOCSRRD<0x06480c00>; +def IOCSRWR_D : IOCSRWR<0x06481c00>; } // Predicates = [IsLA64] // TLB Maintenance Instructions -def TLBSRCH : FmtI32<0b00000110010010000010100000000000, "tlbsrch">; -def TLBRD : FmtI32<0b00000110010010000010110000000000, "tlbrd">; -def TLBWR : FmtI32<0b00000110010010000011000000000000, "tlbwr">; -def TLBFILL : FmtI32<0b00000110010010000011010000000000, "tlbfill">; -def TLBCLR : FmtI32<0b00000110010010000010000000000000, "tlbclr">; -def TLBFLUSH : FmtI32<0b00000110010010000010010000000000, "tlbflush">; -def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), "invtlb", +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { +def TLBSRCH : FmtI32<0x06482800>; +def TLBRD : FmtI32<0x06482c00>; +def TLBWR : FmtI32<0x06483000>; +def TLBFILL : FmtI32<0x06483400>; +def TLBCLR : FmtI32<0x06482000>; +def TLBFLUSH : FmtI32<0x06482400>; +def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), "$op, $rj, $rk">; +} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 // Software Page Walking Instructions -def LDDIR : Fmt2RI8<0b00000110010000, (outs GPR:$rd), - (ins GPR:$rj, uimm8:$imm8), "lddir", "$rd, $rj, $imm8">; -def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "ldpte", "$rj, $seq">; +def LDDIR : Fmt2RI8<0x06400000, (outs GPR:$rd), + (ins GPR:$rj, uimm8:$imm8), "$rd, $rj, $imm8">; +def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "$rj, $seq">; // Other Miscellaneous Instructions -def ERTN : FmtI32<0b00000110010010000011100000000000, "ertn">; -def DBCL : MISC_I15<0b00000000001010101, "dbcl">; -def IDLE : MISC_I15<0b00000110010010001, "idle">; +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +def ERTN : FmtI32<0x06483800>; +def DBCL : MISC_I15<0x002a8000>; +def IDLE : MISC_I15<0x06488000>; //===----------------------------------------------------------------------===// // Privilege Intrinsics @@ -1734,3 +2027,23 @@ def : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8), def : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8), (LDPTE GPR:$rj, uimm8:$imm8)>; } // Predicates = [IsLA64] + +//===----------------------------------------------------------------------===// +// LSX Instructions +//===----------------------------------------------------------------------===// +include "LoongArchLSXInstrInfo.td" + +//===----------------------------------------------------------------------===// +// LASX Instructions +//===----------------------------------------------------------------------===// +include "LoongArchLASXInstrInfo.td" + +//===----------------------------------------------------------------------===// +// LVZ Instructions +//===----------------------------------------------------------------------===// +include "LoongArchLVZInstrInfo.td" + +//===----------------------------------------------------------------------===// +// LBT Instructions +//===----------------------------------------------------------------------===// +include "LoongArchLBTInstrInfo.td" |