[llvm] 1aa3b64 - [LoongArch] Add definition for LSX instructions

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 6 20:22:45 PDT 2023


Author: wanglei
Date: 2023-07-07T11:21:53+08:00
New Revision: 1aa3b64ed2781f064a40b0f9bd196a1265f50b3c

URL: https://github.com/llvm/llvm-project/commit/1aa3b64ed2781f064a40b0f9bd196a1265f50b3c
DIFF: https://github.com/llvm/llvm-project/commit/1aa3b64ed2781f064a40b0f9bd196a1265f50b3c.diff

LOG: [LoongArch] Add definition for LSX instructions

This patch adds the definition for the `LSX` registers and instructions.
It also adds handling for new immediate operands in the AsmParser. This
patch ensures that llvm-mc and llvm-objdump correctly handle the `LSX`
instructions.

We expand those pseudo-instructions `vrepli.{b,h,w,d}` in the
MCCodeEmitter. This increases the readability of the output when
generating assembly files.

Reviewed By: SixWeining

Differential Revision: https://reviews.llvm.org/D154183

Added: 
    llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td
    llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td

Modified: 
    llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
    llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
    llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td
    llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index a31d4d45913166..859573317c743b 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -234,12 +234,24 @@ class LoongArchOperand : public MCParsedAsmOperand {
            VK == LoongArchMCExpr::VK_LoongArch_None;
   }
 
+  bool isUImm1() const { return isUImm<1>(); }
   bool isUImm2() const { return isUImm<2>(); }
   bool isUImm2plus1() const { return isUImm<2, 1>(); }
   bool isUImm3() const { return isUImm<3>(); }
+  bool isUImm4() const { return isUImm<4>(); }
+  bool isSImm5() const { return isSImm<5>(); }
   bool isUImm5() const { return isUImm<5>(); }
   bool isUImm6() const { return isUImm<6>(); }
+  bool isUImm7() const { return isUImm<7>(); }
+  bool isSImm8() const { return isSImm<8>(); }
+  bool isSImm8lsl1() const { return isSImm<8, 1>(); }
+  bool isSImm8lsl2() const { return isSImm<8, 2>(); }
+  bool isSImm8lsl3() const { return isSImm<8, 3>(); }
   bool isUImm8() const { return isUImm<8>(); }
+  bool isSImm9lsl3() const { return isSImm<9, 3>(); }
+  bool isSImm10() const { return isSImm<10>(); }
+  bool isSImm10lsl2() const { return isSImm<10, 2>(); }
+  bool isSImm11lsl1() const { return isSImm<11, 1>(); }
   bool isSImm12() const { return isSImm<12>(); }
 
   bool isSImm12addlike() const {
@@ -303,6 +315,7 @@ class LoongArchOperand : public MCParsedAsmOperand {
                      IsValidKind;
   }
 
+  bool isSImm13() const { return isSImm<13>(); }
   bool isUImm14() const { return isUImm<14>(); }
   bool isUImm15() const { return isUImm<15>(); }
 
@@ -1298,6 +1311,9 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                  "$rd must be 
diff erent from both $rk and $rj");
   case Match_RequiresLAORdDifferRj:
     return Error(Operands[1]->getStartLoc(), "$rd must be 
diff erent from $rj");
+  case Match_InvalidUImm1:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
+                                      /*Upper=*/(1 << 1) - 1);
   case Match_InvalidUImm2:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 2) - 1);
@@ -1307,12 +1323,18 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidUImm3:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 3) - 1);
+  case Match_InvalidUImm4:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
+                                      /*Upper=*/(1 << 4) - 1);
   case Match_InvalidUImm5:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 5) - 1);
   case Match_InvalidUImm6:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 6) - 1);
+  case Match_InvalidUImm7:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
+                                      /*Upper=*/(1 << 7) - 1);
   case Match_InvalidUImm8:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 8) - 1);
@@ -1328,6 +1350,39 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidUImm15:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 15) - 1);
+  case Match_InvalidSImm5:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 4),
+                                      /*Upper=*/(1 << 4) - 1);
+  case Match_InvalidSImm8:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 7),
+                                      /*Upper=*/(1 << 7) - 1);
+  case Match_InvalidSImm8lsl1:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 8), /*Upper=*/(1 << 8) - 2,
+        "immediate must be a multiple of 2 in the range");
+  case Match_InvalidSImm8lsl2:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 9), /*Upper=*/(1 << 9) - 4,
+        "immediate must be a multiple of 4 in the range");
+  case Match_InvalidSImm10:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 9),
+                                      /*Upper=*/(1 << 9) - 1);
+  case Match_InvalidSImm8lsl3:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 10), /*Upper=*/(1 << 10) - 8,
+        "immediate must be a multiple of 8 in the range");
+  case Match_InvalidSImm9lsl3:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 8,
+        "immediate must be a multiple of 8 in the range");
+  case Match_InvalidSImm10lsl2:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 4,
+        "immediate must be a multiple of 4 in the range");
+  case Match_InvalidSImm11lsl1:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 2,
+        "immediate must be a multiple of 2 in the range");
   case Match_InvalidSImm12:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 11),
                                       /*Upper=*/(1 << 11) - 1);
@@ -1343,6 +1398,9 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
         /*Upper=*/(1 << 11) - 1,
         "operand must be a symbol with modifier (e.g. %pc64_hi12) or an "
         "integer in the range");
+  case Match_InvalidSImm13:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 12),
+                                      /*Upper=*/(1 << 12) - 1);
   case Match_InvalidSImm14lsl2:
     return generateImmOutOfRangeError(
         Operands, ErrorInfo, /*Lower=*/-(1 << 15), /*Upper=*/(1 << 15) - 4,

diff  --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
index 2335152e5ab170..ddf47b1665a367 100644
--- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
+++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp
@@ -100,6 +100,15 @@ static DecodeStatus DecodeFCSRRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeLSX128RegisterClass(MCInst &Inst, uint64_t RegNo,
+                                              uint64_t Address,
+                                              const MCDisassembler *Decoder) {
+  if (RegNo >= 32)
+    return MCDisassembler::Fail;
+  Inst.addOperand(MCOperand::createReg(LoongArch::VR0 + RegNo));
+  return MCDisassembler::Success;
+}
+
 template <unsigned N, int P = 0>
 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
                                       int64_t Address,

diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 44e4866e7897e8..beb8e0892ccee6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -182,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>;
 }
@@ -197,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>;
 }
@@ -205,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>;
 }
@@ -232,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>";
@@ -249,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>";
 }
 
@@ -264,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>";
 }
 
@@ -296,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>";
 }
 
@@ -311,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>";
 }
 
@@ -326,7 +383,7 @@ 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>";
 }
 
@@ -468,6 +525,7 @@ def AlslSlliImmI0 : SDNodeXForm<imm, [{
 
 include "LoongArchInstrFormats.td"
 include "LoongArchFloatInstrFormats.td"
+include "LoongArchLSXInstrFormats.td"
 
 //===----------------------------------------------------------------------===//
 // Instruction Class Templates
@@ -1950,3 +2008,8 @@ 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"

diff  --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td
new file mode 100644
index 00000000000000..979d38900e190c
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td
@@ -0,0 +1,486 @@
+// LoongArchLSXInstrFormats.td - LoongArch LSX Instr Formats -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//  Describe LoongArch LSX instructions format
+//
+//  opcode       - operation code.
+//  vd/rd/cd     - destination register operand.
+//  {r/v}{j/k}   - source register operand.
+//  immN         - immediate data operand.
+//
+//===----------------------------------------------------------------------===//
+
+// 1RI13-type
+// <opcode | I13 | vd>
+class Fmt1RI13_VI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<13> imm13;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{17-5} = imm13;
+  let Inst{4-0} = vd;
+}
+
+// 2R-type
+// <opcode | vj | vd>
+class Fmt2R_VV<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+               list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | rj | vd>
+class Fmt2R_VR<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+               list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | vj | cd>
+class Fmt2R_CV<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+               list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> vj;
+  bits<3> cd;
+
+  let Inst{31-0} = op;
+  let Inst{9-5} = vj;
+  let Inst{2-0} = cd;
+}
+
+// 2RI1-type
+// <opcode | I1 | vj | vd>
+class Fmt2RI1_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<1> imm1;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{10} = imm1;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I1 | rj | vd>
+class Fmt2RI1_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<1> imm1;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{10} = imm1;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I1 | vj | rd>
+class Fmt2RI1_RVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<1> imm1;
+  bits<5> vj;
+  bits<5> rd;
+
+  let Inst{31-0} = op;
+  let Inst{10} = imm1;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = rd;
+}
+
+// 2RI2-type
+// <opcode | I2 | vj | vd>
+class Fmt2RI2_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<2> imm2;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{11-10} = imm2;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I2 | rj | vd>
+class Fmt2RI2_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<2> imm2;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{11-10} = imm2;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I2 | vj | rd>
+class Fmt2RI2_RVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<2> imm2;
+  bits<5> vj;
+  bits<5> rd;
+
+  let Inst{31-0} = op;
+  let Inst{11-10} = imm2;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = rd;
+}
+
+// 2RI3-type
+// <opcode | I3 | vj | vd>
+class Fmt2RI3_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<3> imm3;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{12-10} = imm3;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I3 | rj | vd>
+class Fmt2RI3_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<3> imm3;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{12-10} = imm3;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I3 | vj | rd>
+class Fmt2RI3_RVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<3> imm3;
+  bits<5> vj;
+  bits<5> rd;
+
+  let Inst{31-0} = op;
+  let Inst{12-10} = imm3;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = rd;
+}
+
+// 2RI4-type
+// <opcode | I4 | vj | vd>
+class Fmt2RI4_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<4> imm4;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{13-10} = imm4;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I4 | rj | vd>
+class Fmt2RI4_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<4> imm4;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{13-10} = imm4;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | I4 | vj | rd>
+class Fmt2RI4_RVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<4> imm4;
+  bits<5> vj;
+  bits<5> rd;
+
+  let Inst{31-0} = op;
+  let Inst{13-10} = imm4;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = rd;
+}
+
+// 2RI5-type
+// <opcode | I5 | vj | vd>
+class Fmt2RI5_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> imm5;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{14-10} = imm5;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI6-type
+// <opcode | I6 | vj | vd>
+class Fmt2RI6_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<6> imm6;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{15-10} = imm6;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI7-type
+// <opcode | I7 | vj | vd>
+class Fmt2RI7_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<7> imm7;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{16-10} = imm7;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI8-type
+// <opcode | I8 | vj | vd>
+class Fmt2RI8_VVI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<8> imm8;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{17-10} = imm8;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI8I1-type
+// <opcode | I1 | I8 | vj | vd>
+class Fmt2RI8I1_VRII<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                     list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<1> imm1;
+  bits<8> imm8;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{18} = imm1;
+  let Inst{17-10} = imm8;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI8I2-type
+// <opcode | I2 | I8 | vj | vd>
+class Fmt2RI8I2_VRII<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                     list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<2> imm2;
+  bits<8> imm8;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{19-18} = imm2;
+  let Inst{17-10} = imm8;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI8I3-type
+// <opcode | I3 | I8 | vj | vd>
+class Fmt2RI8I3_VRII<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                     list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<3> imm3;
+  bits<8> imm8;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{20-18} = imm3;
+  let Inst{17-10} = imm8;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI8I4-type
+// <opcode | I4 | I8 | vj | vd>
+class Fmt2RI8I4_VRII<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                     list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<4> imm4;
+  bits<8> imm8;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{21-18} = imm4;
+  let Inst{17-10} = imm8;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+// 2RI9-type
+// <opcode | I9 | rj | vd>
+class Fmt2RI9_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<9> imm9;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{18-10} = imm9;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI10-type
+// <opcode | I10 | rj | vd>
+class Fmt2RI10_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<10> imm10;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{19-10} = imm10;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI11-type
+// <opcode | I11 | rj | vd>
+class Fmt2RI11_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<11> imm11;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{20-10} = imm11;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 2RI12-type
+// <opcode | I12 | rj | vd>
+class Fmt2RI12_VRI<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                  list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<12> imm12;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{21-10} = imm12;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 3R-type
+// <opcode | vk | vj | vd>
+class Fmt3R_VVV<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> vk;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{14-10} = vk;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | rk | vj | vd>
+class Fmt3R_VVR<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> rk;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{14-10} = rk;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}
+
+// <opcode | rk | rj | vd>
+class Fmt3R_VRR<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> rk;
+  bits<5> rj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{14-10} = rk;
+  let Inst{9-5} = rj;
+  let Inst{4-0} = vd;
+}
+
+// 4R-type
+// <opcode | va | vk | vj | vd>
+class Fmt4R_VVVV<bits<32> op, dag outs, dag ins, string opcstr, string opnstr,
+                 list<dag> pattern = []>
+    : LAInst<outs, ins, opcstr, opnstr, pattern> {
+  bits<5> va;
+  bits<5> vk;
+  bits<5> vj;
+  bits<5> vd;
+
+  let Inst{31-0} = op;
+  let Inst{19-15} = va;
+  let Inst{14-10} = vk;
+  let Inst{9-5} = vj;
+  let Inst{4-0} = vd;
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
new file mode 100644
index 00000000000000..018164a1ccbe2e
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -0,0 +1,1012 @@
+//===- LoongArchLSXInstrInfo.td - LoongArch LSX instructions -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the SIMD extension instructions.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+
+class LSX1RI13_VI<bits<32> op, Operand ImmOpnd = simm13>
+    : Fmt1RI13_VI<op, (outs LSX128:$vd), (ins ImmOpnd:$imm13),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $imm13">;
+
+class LSX2R_VV<bits<32> op>
+    : Fmt2R_VV<op, (outs LSX128:$vd), (ins LSX128:$vj),
+                    !tolower(!subst("_", ".", NAME)), "$vd, $vj">;
+
+class LSX2R_VR<bits<32> op>
+    : Fmt2R_VR<op, (outs LSX128:$vd), (ins GPR:$rj),
+                    !tolower(!subst("_", ".", NAME)), "$vd, $rj">;
+
+class LSX2R_CV<bits<32> op>
+    : Fmt2R_CV<op, (outs CFR:$cd), (ins LSX128:$vj),
+                    !tolower(!subst("_", ".", NAME)), "$cd, $vj">;
+
+class LSX2RI1_VVI<bits<32> op, Operand ImmOpnd = uimm1>
+    : Fmt2RI1_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm1),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm1">;
+
+class LSX2RI1_RVI<bits<32> op, Operand ImmOpnd = uimm1>
+    : Fmt2RI1_RVI<op, (outs GPR:$rd), (ins LSX128:$vj, ImmOpnd:$imm1),
+                  !tolower(!subst("_", ".", NAME)), "$rd, $vj, $imm1">;
+
+class LSX2RI2_VVI<bits<32> op, Operand ImmOpnd = uimm2>
+    : Fmt2RI2_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm2),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm2">;
+
+class LSX2RI2_RVI<bits<32> op, Operand ImmOpnd = uimm2>
+    : Fmt2RI2_RVI<op, (outs GPR:$rd), (ins LSX128:$vj, ImmOpnd:$imm2),
+                  !tolower(!subst("_", ".", NAME)), "$rd, $vj, $imm2">;
+
+class LSX2RI3_VVI<bits<32> op, Operand ImmOpnd = uimm3>
+    : Fmt2RI3_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm3),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm3">;
+
+class LSX2RI3_RVI<bits<32> op, Operand ImmOpnd = uimm3>
+    : Fmt2RI3_RVI<op, (outs GPR:$rd), (ins LSX128:$vj, ImmOpnd:$imm3),
+                  !tolower(!subst("_", ".", NAME)), "$rd, $vj, $imm3">;
+
+class LSX2RI4_VVI<bits<32> op, Operand ImmOpnd = uimm4>
+    : Fmt2RI4_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm4),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm4">;
+
+class LSX2RI4_RVI<bits<32> op, Operand ImmOpnd = uimm4>
+    : Fmt2RI4_RVI<op, (outs GPR:$rd), (ins LSX128:$vj, ImmOpnd:$imm4),
+                  !tolower(!subst("_", ".", NAME)), "$rd, $vj, $imm4">;
+
+class LSX2RI5_VVI<bits<32> op, Operand ImmOpnd = uimm5>
+    : Fmt2RI5_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm5),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm5">;
+
+class LSX2RI6_VVI<bits<32> op, Operand ImmOpnd = uimm6>
+    : Fmt2RI6_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm6),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm6">;
+
+class LSX2RI8_VVI<bits<32> op, Operand ImmOpnd = uimm8>
+    : Fmt2RI8_VVI<op, (outs LSX128:$vd), (ins LSX128:$vj, ImmOpnd:$imm8),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm8">;
+
+class LSX2RI8I1_VRII<bits<32> op, Operand ImmOpnd = simm8,
+                     Operand IdxOpnd = uimm1>
+    : Fmt2RI8I1_VRII<op, (outs),
+                     (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm8, IdxOpnd:$imm1),
+                     !tolower(!subst("_", ".", NAME)),
+                     "$vd, $rj, $imm8, $imm1">;
+class LSX2RI8I2_VRII<bits<32> op, Operand ImmOpnd = simm8,
+                     Operand IdxOpnd = uimm2>
+    : Fmt2RI8I2_VRII<op, (outs),
+                     (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm8, IdxOpnd:$imm2),
+                     !tolower(!subst("_", ".", NAME)),
+                     "$vd, $rj, $imm8, $imm2">;
+class LSX2RI8I3_VRII<bits<32> op, Operand ImmOpnd = simm8,
+                     Operand IdxOpnd = uimm3>
+    : Fmt2RI8I3_VRII<op, (outs),
+                     (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm8, IdxOpnd:$imm3),
+                     !tolower(!subst("_", ".", NAME)),
+                     "$vd, $rj, $imm8, $imm3">;
+class LSX2RI8I4_VRII<bits<32> op, Operand ImmOpnd = simm8,
+                     Operand IdxOpnd = uimm4>
+    : Fmt2RI8I4_VRII<op, (outs),
+                     (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm8, IdxOpnd:$imm4),
+                     !tolower(!subst("_", ".", NAME)),
+                     "$vd, $rj, $imm8, $imm4">;
+
+class LSX2RI9_VRI<bits<32> op, Operand ImmOpnd = simm9_lsl3>
+    : Fmt2RI9_VRI<op, (outs LSX128:$vd), (ins GPR:$rj, ImmOpnd:$imm9),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm9">;
+
+class LSX2RI10_VRI<bits<32> op, Operand ImmOpnd = simm10_lsl2>
+    : Fmt2RI10_VRI<op, (outs LSX128:$vd), (ins GPR:$rj, ImmOpnd:$imm10),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm10">;
+
+class LSX2RI11_VRI<bits<32> op, Operand ImmOpnd = simm11_lsl1>
+    : Fmt2RI11_VRI<op, (outs LSX128:$vd), (ins GPR:$rj, ImmOpnd:$imm11),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm11">;
+
+class LSX2RI12_VRI<bits<32> op, Operand ImmOpnd = simm12>
+    : Fmt2RI12_VRI<op, (outs LSX128:$vd), (ins GPR:$rj, ImmOpnd:$imm12),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm12">;
+
+class LSX3R_VVV<bits<32> op>
+    : Fmt3R_VVV<op, (outs LSX128:$vd), (ins LSX128:$vj, LSX128:$vk),
+                !tolower(!subst("_", ".", NAME)), "$vd, $vj, $vk">;
+
+class LSX3R_VVR<bits<32> op>
+    : Fmt3R_VVR<op, (outs LSX128:$vd), (ins LSX128:$vj, GPR:$rk),
+                !tolower(!subst("_", ".", NAME)), "$vd, $vj, $rk">;
+
+class LSX3R_VRR<bits<32> op>
+    : Fmt3R_VRR<op, (outs LSX128:$vd), (ins GPR:$rj, GPR:$rk),
+                !tolower(!subst("_", ".", NAME)), "$vd, $rj, $rk">;
+
+class LSX4R_VVVV<bits<32> op>
+    : Fmt4R_VVVV<op, (outs LSX128:$vd),
+                 (ins LSX128:$vj, LSX128:$vk, LSX128:$va),
+                 !tolower(!subst("_", ".", NAME)), "$vd, $vj, $vk, $va">;
+
+let Constraints = "$vd = $dst" in {
+
+class LSX2RI1_VVRI<bits<32> op, Operand ImmOpnd = uimm1>
+    : Fmt2RI1_VRI<op, (outs LSX128:$dst), (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm1),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm1">;
+class LSX2RI2_VVRI<bits<32> op, Operand ImmOpnd = uimm2>
+    : Fmt2RI2_VRI<op, (outs LSX128:$dst), (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm2),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm2">;
+class LSX2RI3_VVRI<bits<32> op, Operand ImmOpnd = uimm3>
+    : Fmt2RI3_VRI<op, (outs LSX128:$dst), (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm3),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm3">;
+class LSX2RI4_VVRI<bits<32> op, Operand ImmOpnd = uimm4>
+    : Fmt2RI4_VRI<op, (outs LSX128:$dst), (ins LSX128:$vd, GPR:$rj, ImmOpnd:$imm4),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $rj, $imm4">;
+
+class LSX2RI4_VVVI<bits<32> op, Operand ImmOpnd = uimm4>
+    : Fmt2RI4_VVI<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, ImmOpnd:$imm4),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm4">;
+class LSX2RI5_VVVI<bits<32> op, Operand ImmOpnd = uimm5>
+    : Fmt2RI5_VVI<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, ImmOpnd:$imm5),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm5">;
+class LSX2RI6_VVVI<bits<32> op, Operand ImmOpnd = uimm6>
+    : Fmt2RI6_VVI<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, ImmOpnd:$imm6),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm6">;
+class LSX2RI7_VVVI<bits<32> op, Operand ImmOpnd = uimm7>
+    : Fmt2RI7_VVI<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, ImmOpnd:$imm7),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm7">;
+
+class LSX2RI8_VVVI<bits<32> op, Operand ImmOpnd = uimm8>
+    : Fmt2RI8_VVI<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, ImmOpnd:$imm8),
+                  !tolower(!subst("_", ".", NAME)), "$vd, $vj, $imm8">;
+
+class LSX3R_VVVV<bits<32> op>
+    : Fmt3R_VVV<op, (outs LSX128:$dst), (ins LSX128:$vd, LSX128:$vj, LSX128:$vk),
+                !tolower(!subst("_", ".", NAME)), "$vd, $vj, $vk">;
+
+} // Constraints = "$vd = $dst"
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, Predicates = [HasExtLSX] in {
+
+let mayLoad = 0, mayStore = 0 in {
+
+def VADD_B : LSX3R_VVV<0x700a0000>;
+def VADD_H : LSX3R_VVV<0x700a8000>;
+def VADD_W : LSX3R_VVV<0x700b0000>;
+def VADD_D : LSX3R_VVV<0x700b8000>;
+def VADD_Q : LSX3R_VVV<0x712d0000>;
+
+def VSUB_B : LSX3R_VVV<0x700c0000>;
+def VSUB_H : LSX3R_VVV<0x700c8000>;
+def VSUB_W : LSX3R_VVV<0x700d0000>;
+def VSUB_D : LSX3R_VVV<0x700d8000>;
+def VSUB_Q : LSX3R_VVV<0x712d8000>;
+
+def VADDI_BU : LSX2RI5_VVI<0x728a0000>;
+def VADDI_HU : LSX2RI5_VVI<0x728a8000>;
+def VADDI_WU : LSX2RI5_VVI<0x728b0000>;
+def VADDI_DU : LSX2RI5_VVI<0x728b8000>;
+
+def VSUBI_BU : LSX2RI5_VVI<0x728c0000>;
+def VSUBI_HU : LSX2RI5_VVI<0x728c8000>;
+def VSUBI_WU : LSX2RI5_VVI<0x728d0000>;
+def VSUBI_DU : LSX2RI5_VVI<0x728d8000>;
+
+def VNEG_B : LSX2R_VV<0x729c3000>;
+def VNEG_H : LSX2R_VV<0x729c3400>;
+def VNEG_W : LSX2R_VV<0x729c3800>;
+def VNEG_D : LSX2R_VV<0x729c3c00>;
+
+def VSADD_B : LSX3R_VVV<0x70460000>;
+def VSADD_H : LSX3R_VVV<0x70468000>;
+def VSADD_W : LSX3R_VVV<0x70470000>;
+def VSADD_D : LSX3R_VVV<0x70478000>;
+def VSADD_BU : LSX3R_VVV<0x704a0000>;
+def VSADD_HU : LSX3R_VVV<0x704a8000>;
+def VSADD_WU : LSX3R_VVV<0x704b0000>;
+def VSADD_DU : LSX3R_VVV<0x704b8000>;
+
+def VSSUB_B : LSX3R_VVV<0x70480000>;
+def VSSUB_H : LSX3R_VVV<0x70488000>;
+def VSSUB_W : LSX3R_VVV<0x70490000>;
+def VSSUB_D : LSX3R_VVV<0x70498000>;
+def VSSUB_BU : LSX3R_VVV<0x704c0000>;
+def VSSUB_HU : LSX3R_VVV<0x704c8000>;
+def VSSUB_WU : LSX3R_VVV<0x704d0000>;
+def VSSUB_DU : LSX3R_VVV<0x704d8000>;
+
+def VHADDW_H_B : LSX3R_VVV<0x70540000>;
+def VHADDW_W_H : LSX3R_VVV<0x70548000>;
+def VHADDW_D_W : LSX3R_VVV<0x70550000>;
+def VHADDW_Q_D : LSX3R_VVV<0x70558000>;
+def VHADDW_HU_BU : LSX3R_VVV<0x70580000>;
+def VHADDW_WU_HU : LSX3R_VVV<0x70588000>;
+def VHADDW_DU_WU : LSX3R_VVV<0x70590000>;
+def VHADDW_QU_DU : LSX3R_VVV<0x70598000>;
+
+def VHSUBW_H_B : LSX3R_VVV<0x70560000>;
+def VHSUBW_W_H : LSX3R_VVV<0x70568000>;
+def VHSUBW_D_W : LSX3R_VVV<0x70570000>;
+def VHSUBW_Q_D : LSX3R_VVV<0x70578000>;
+def VHSUBW_HU_BU : LSX3R_VVV<0x705a0000>;
+def VHSUBW_WU_HU : LSX3R_VVV<0x705a8000>;
+def VHSUBW_DU_WU : LSX3R_VVV<0x705b0000>;
+def VHSUBW_QU_DU : LSX3R_VVV<0x705b8000>;
+
+def VADDWEV_H_B : LSX3R_VVV<0x701e0000>;
+def VADDWEV_W_H : LSX3R_VVV<0x701e8000>;
+def VADDWEV_D_W : LSX3R_VVV<0x701f0000>;
+def VADDWEV_Q_D : LSX3R_VVV<0x701f8000>;
+def VADDWOD_H_B : LSX3R_VVV<0x70220000>;
+def VADDWOD_W_H : LSX3R_VVV<0x70228000>;
+def VADDWOD_D_W : LSX3R_VVV<0x70230000>;
+def VADDWOD_Q_D : LSX3R_VVV<0x70238000>;
+
+def VSUBWEV_H_B : LSX3R_VVV<0x70200000>;
+def VSUBWEV_W_H : LSX3R_VVV<0x70208000>;
+def VSUBWEV_D_W : LSX3R_VVV<0x70210000>;
+def VSUBWEV_Q_D : LSX3R_VVV<0x70218000>;
+def VSUBWOD_H_B : LSX3R_VVV<0x70240000>;
+def VSUBWOD_W_H : LSX3R_VVV<0x70248000>;
+def VSUBWOD_D_W : LSX3R_VVV<0x70250000>;
+def VSUBWOD_Q_D : LSX3R_VVV<0x70258000>;
+
+def VADDWEV_H_BU : LSX3R_VVV<0x702e0000>;
+def VADDWEV_W_HU : LSX3R_VVV<0x702e8000>;
+def VADDWEV_D_WU : LSX3R_VVV<0x702f0000>;
+def VADDWEV_Q_DU : LSX3R_VVV<0x702f8000>;
+def VADDWOD_H_BU : LSX3R_VVV<0x70320000>;
+def VADDWOD_W_HU : LSX3R_VVV<0x70328000>;
+def VADDWOD_D_WU : LSX3R_VVV<0x70330000>;
+def VADDWOD_Q_DU : LSX3R_VVV<0x70338000>;
+
+def VSUBWEV_H_BU : LSX3R_VVV<0x70300000>;
+def VSUBWEV_W_HU : LSX3R_VVV<0x70308000>;
+def VSUBWEV_D_WU : LSX3R_VVV<0x70310000>;
+def VSUBWEV_Q_DU : LSX3R_VVV<0x70318000>;
+def VSUBWOD_H_BU : LSX3R_VVV<0x70340000>;
+def VSUBWOD_W_HU : LSX3R_VVV<0x70348000>;
+def VSUBWOD_D_WU : LSX3R_VVV<0x70350000>;
+def VSUBWOD_Q_DU : LSX3R_VVV<0x70358000>;
+
+def VADDWEV_H_BU_B : LSX3R_VVV<0x703e0000>;
+def VADDWEV_W_HU_H : LSX3R_VVV<0x703e8000>;
+def VADDWEV_D_WU_W : LSX3R_VVV<0x703f0000>;
+def VADDWEV_Q_DU_D : LSX3R_VVV<0x703f8000>;
+def VADDWOD_H_BU_B : LSX3R_VVV<0x70400000>;
+def VADDWOD_W_HU_H : LSX3R_VVV<0x70408000>;
+def VADDWOD_D_WU_W : LSX3R_VVV<0x70410000>;
+def VADDWOD_Q_DU_D : LSX3R_VVV<0x70418000>;
+
+def VAVG_B : LSX3R_VVV<0x70640000>;
+def VAVG_H : LSX3R_VVV<0x70648000>;
+def VAVG_W : LSX3R_VVV<0x70650000>;
+def VAVG_D : LSX3R_VVV<0x70658000>;
+def VAVG_BU : LSX3R_VVV<0x70660000>;
+def VAVG_HU : LSX3R_VVV<0x70668000>;
+def VAVG_WU : LSX3R_VVV<0x70670000>;
+def VAVG_DU : LSX3R_VVV<0x70678000>;
+def VAVGR_B : LSX3R_VVV<0x70680000>;
+def VAVGR_H : LSX3R_VVV<0x70688000>;
+def VAVGR_W : LSX3R_VVV<0x70690000>;
+def VAVGR_D : LSX3R_VVV<0x70698000>;
+def VAVGR_BU : LSX3R_VVV<0x706a0000>;
+def VAVGR_HU : LSX3R_VVV<0x706a8000>;
+def VAVGR_WU : LSX3R_VVV<0x706b0000>;
+def VAVGR_DU : LSX3R_VVV<0x706b8000>;
+
+def VABSD_B : LSX3R_VVV<0x70600000>;
+def VABSD_H : LSX3R_VVV<0x70608000>;
+def VABSD_W : LSX3R_VVV<0x70610000>;
+def VABSD_D : LSX3R_VVV<0x70618000>;
+def VABSD_BU : LSX3R_VVV<0x70620000>;
+def VABSD_HU : LSX3R_VVV<0x70628000>;
+def VABSD_WU : LSX3R_VVV<0x70630000>;
+def VABSD_DU : LSX3R_VVV<0x70638000>;
+
+def VADDA_B : LSX3R_VVV<0x705c0000>;
+def VADDA_H : LSX3R_VVV<0x705c8000>;
+def VADDA_W : LSX3R_VVV<0x705d0000>;
+def VADDA_D : LSX3R_VVV<0x705d8000>;
+
+def VMAX_B : LSX3R_VVV<0x70700000>;
+def VMAX_H : LSX3R_VVV<0x70708000>;
+def VMAX_W : LSX3R_VVV<0x70710000>;
+def VMAX_D : LSX3R_VVV<0x70718000>;
+def VMAXI_B : LSX2RI5_VVI<0x72900000, simm5>;
+def VMAXI_H : LSX2RI5_VVI<0x72908000, simm5>;
+def VMAXI_W : LSX2RI5_VVI<0x72910000, simm5>;
+def VMAXI_D : LSX2RI5_VVI<0x72918000, simm5>;
+def VMAX_BU : LSX3R_VVV<0x70740000>;
+def VMAX_HU : LSX3R_VVV<0x70748000>;
+def VMAX_WU : LSX3R_VVV<0x70750000>;
+def VMAX_DU : LSX3R_VVV<0x70758000>;
+def VMAXI_BU : LSX2RI5_VVI<0x72940000>;
+def VMAXI_HU : LSX2RI5_VVI<0x72948000>;
+def VMAXI_WU : LSX2RI5_VVI<0x72950000>;
+def VMAXI_DU : LSX2RI5_VVI<0x72958000>;
+
+def VMIN_B : LSX3R_VVV<0x70720000>;
+def VMIN_H : LSX3R_VVV<0x70728000>;
+def VMIN_W : LSX3R_VVV<0x70730000>;
+def VMIN_D : LSX3R_VVV<0x70738000>;
+def VMINI_B : LSX2RI5_VVI<0x72920000, simm5>;
+def VMINI_H : LSX2RI5_VVI<0x72928000, simm5>;
+def VMINI_W : LSX2RI5_VVI<0x72930000, simm5>;
+def VMINI_D : LSX2RI5_VVI<0x72938000, simm5>;
+def VMIN_BU : LSX3R_VVV<0x70760000>;
+def VMIN_HU : LSX3R_VVV<0x70768000>;
+def VMIN_WU : LSX3R_VVV<0x70770000>;
+def VMIN_DU : LSX3R_VVV<0x70778000>;
+def VMINI_BU : LSX2RI5_VVI<0x72960000>;
+def VMINI_HU : LSX2RI5_VVI<0x72968000>;
+def VMINI_WU : LSX2RI5_VVI<0x72970000>;
+def VMINI_DU : LSX2RI5_VVI<0x72978000>;
+
+def VMUL_B : LSX3R_VVV<0x70840000>;
+def VMUL_H : LSX3R_VVV<0x70848000>;
+def VMUL_W : LSX3R_VVV<0x70850000>;
+def VMUL_D : LSX3R_VVV<0x70858000>;
+
+def VMUH_B : LSX3R_VVV<0x70860000>;
+def VMUH_H : LSX3R_VVV<0x70868000>;
+def VMUH_W : LSX3R_VVV<0x70870000>;
+def VMUH_D : LSX3R_VVV<0x70878000>;
+def VMUH_BU : LSX3R_VVV<0x70880000>;
+def VMUH_HU : LSX3R_VVV<0x70888000>;
+def VMUH_WU : LSX3R_VVV<0x70890000>;
+def VMUH_DU : LSX3R_VVV<0x70898000>;
+
+def VMULWEV_H_B : LSX3R_VVV<0x70900000>;
+def VMULWEV_W_H : LSX3R_VVV<0x70908000>;
+def VMULWEV_D_W : LSX3R_VVV<0x70910000>;
+def VMULWEV_Q_D : LSX3R_VVV<0x70918000>;
+def VMULWOD_H_B : LSX3R_VVV<0x70920000>;
+def VMULWOD_W_H : LSX3R_VVV<0x70928000>;
+def VMULWOD_D_W : LSX3R_VVV<0x70930000>;
+def VMULWOD_Q_D : LSX3R_VVV<0x70938000>;
+def VMULWEV_H_BU : LSX3R_VVV<0x70980000>;
+def VMULWEV_W_HU : LSX3R_VVV<0x70988000>;
+def VMULWEV_D_WU : LSX3R_VVV<0x70990000>;
+def VMULWEV_Q_DU : LSX3R_VVV<0x70998000>;
+def VMULWOD_H_BU : LSX3R_VVV<0x709a0000>;
+def VMULWOD_W_HU : LSX3R_VVV<0x709a8000>;
+def VMULWOD_D_WU : LSX3R_VVV<0x709b0000>;
+def VMULWOD_Q_DU : LSX3R_VVV<0x709b8000>;
+def VMULWEV_H_BU_B : LSX3R_VVV<0x70a00000>;
+def VMULWEV_W_HU_H : LSX3R_VVV<0x70a08000>;
+def VMULWEV_D_WU_W : LSX3R_VVV<0x70a10000>;
+def VMULWEV_Q_DU_D : LSX3R_VVV<0x70a18000>;
+def VMULWOD_H_BU_B : LSX3R_VVV<0x70a20000>;
+def VMULWOD_W_HU_H : LSX3R_VVV<0x70a28000>;
+def VMULWOD_D_WU_W : LSX3R_VVV<0x70a30000>;
+def VMULWOD_Q_DU_D : LSX3R_VVV<0x70a38000>;
+
+def VMADD_B : LSX3R_VVVV<0x70a80000>;
+def VMADD_H : LSX3R_VVVV<0x70a88000>;
+def VMADD_W : LSX3R_VVVV<0x70a90000>;
+def VMADD_D : LSX3R_VVVV<0x70a98000>;
+
+def VMSUB_B : LSX3R_VVVV<0x70aa0000>;
+def VMSUB_H : LSX3R_VVVV<0x70aa8000>;
+def VMSUB_W : LSX3R_VVVV<0x70ab0000>;
+def VMSUB_D : LSX3R_VVVV<0x70ab8000>;
+
+def VMADDWEV_H_B : LSX3R_VVVV<0x70ac0000>;
+def VMADDWEV_W_H : LSX3R_VVVV<0x70ac8000>;
+def VMADDWEV_D_W : LSX3R_VVVV<0x70ad0000>;
+def VMADDWEV_Q_D : LSX3R_VVVV<0x70ad8000>;
+def VMADDWOD_H_B : LSX3R_VVVV<0x70ae0000>;
+def VMADDWOD_W_H : LSX3R_VVVV<0x70ae8000>;
+def VMADDWOD_D_W : LSX3R_VVVV<0x70af0000>;
+def VMADDWOD_Q_D : LSX3R_VVVV<0x70af8000>;
+def VMADDWEV_H_BU : LSX3R_VVVV<0x70b40000>;
+def VMADDWEV_W_HU : LSX3R_VVVV<0x70b48000>;
+def VMADDWEV_D_WU : LSX3R_VVVV<0x70b50000>;
+def VMADDWEV_Q_DU : LSX3R_VVVV<0x70b58000>;
+def VMADDWOD_H_BU : LSX3R_VVVV<0x70b60000>;
+def VMADDWOD_W_HU : LSX3R_VVVV<0x70b68000>;
+def VMADDWOD_D_WU : LSX3R_VVVV<0x70b70000>;
+def VMADDWOD_Q_DU : LSX3R_VVVV<0x70b78000>;
+def VMADDWEV_H_BU_B : LSX3R_VVVV<0x70bc0000>;
+def VMADDWEV_W_HU_H : LSX3R_VVVV<0x70bc8000>;
+def VMADDWEV_D_WU_W : LSX3R_VVVV<0x70bd0000>;
+def VMADDWEV_Q_DU_D : LSX3R_VVVV<0x70bd8000>;
+def VMADDWOD_H_BU_B : LSX3R_VVVV<0x70be0000>;
+def VMADDWOD_W_HU_H : LSX3R_VVVV<0x70be8000>;
+def VMADDWOD_D_WU_W : LSX3R_VVVV<0x70bf0000>;
+def VMADDWOD_Q_DU_D : LSX3R_VVVV<0x70bf8000>;
+
+def VDIV_B : LSX3R_VVV<0x70e00000>;
+def VDIV_H : LSX3R_VVV<0x70e08000>;
+def VDIV_W : LSX3R_VVV<0x70e10000>;
+def VDIV_D : LSX3R_VVV<0x70e18000>;
+def VDIV_BU : LSX3R_VVV<0x70e40000>;
+def VDIV_HU : LSX3R_VVV<0x70e48000>;
+def VDIV_WU : LSX3R_VVV<0x70e50000>;
+def VDIV_DU : LSX3R_VVV<0x70e58000>;
+
+def VMOD_B : LSX3R_VVV<0x70e20000>;
+def VMOD_H : LSX3R_VVV<0x70e28000>;
+def VMOD_W : LSX3R_VVV<0x70e30000>;
+def VMOD_D : LSX3R_VVV<0x70e38000>;
+def VMOD_BU : LSX3R_VVV<0x70e60000>;
+def VMOD_HU : LSX3R_VVV<0x70e68000>;
+def VMOD_WU : LSX3R_VVV<0x70e70000>;
+def VMOD_DU : LSX3R_VVV<0x70e78000>;
+
+def VSAT_B : LSX2RI3_VVI<0x73242000>;
+def VSAT_H : LSX2RI4_VVI<0x73244000>;
+def VSAT_W : LSX2RI5_VVI<0x73248000>;
+def VSAT_D : LSX2RI6_VVI<0x73250000>;
+def VSAT_BU : LSX2RI3_VVI<0x73282000>;
+def VSAT_HU : LSX2RI4_VVI<0x73284000>;
+def VSAT_WU : LSX2RI5_VVI<0x73288000>;
+def VSAT_DU : LSX2RI6_VVI<0x73290000>;
+
+def VEXTH_H_B : LSX2R_VV<0x729ee000>;
+def VEXTH_W_H : LSX2R_VV<0x729ee400>;
+def VEXTH_D_W : LSX2R_VV<0x729ee800>;
+def VEXTH_Q_D : LSX2R_VV<0x729eec00>;
+def VEXTH_HU_BU : LSX2R_VV<0x729ef000>;
+def VEXTH_WU_HU : LSX2R_VV<0x729ef400>;
+def VEXTH_DU_WU : LSX2R_VV<0x729ef800>;
+def VEXTH_QU_DU : LSX2R_VV<0x729efc00>;
+
+def VSIGNCOV_B : LSX3R_VVV<0x712e0000>;
+def VSIGNCOV_H : LSX3R_VVV<0x712e8000>;
+def VSIGNCOV_W : LSX3R_VVV<0x712f0000>;
+def VSIGNCOV_D : LSX3R_VVV<0x712f8000>;
+
+def VMSKLTZ_B : LSX2R_VV<0x729c4000>;
+def VMSKLTZ_H : LSX2R_VV<0x729c4400>;
+def VMSKLTZ_W : LSX2R_VV<0x729c4800>;
+def VMSKLTZ_D : LSX2R_VV<0x729c4c00>;
+
+def VMSKGEZ_B : LSX2R_VV<0x729c5000>;
+
+def VMSKNZ_B : LSX2R_VV<0x729c6000>;
+
+def VLDI : LSX1RI13_VI<0x73e00000>;
+
+def VAND_V : LSX3R_VVV<0x71260000>;
+def VOR_V : LSX3R_VVV<0x71268000>;
+def VXOR_V : LSX3R_VVV<0x71270000>;
+def VNOR_V : LSX3R_VVV<0x71278000>;
+def VANDN_V : LSX3R_VVV<0x71280000>;
+def VORN_V : LSX3R_VVV<0x71288000>;
+
+def VANDI_B : LSX2RI8_VVI<0x73d00000>;
+def VORI_B : LSX2RI8_VVI<0x73d40000>;
+def VXORI_B : LSX2RI8_VVI<0x73d80000>;
+def VNORI_B : LSX2RI8_VVI<0x73dc0000>;
+
+def VSLL_B : LSX3R_VVV<0x70e80000>;
+def VSLL_H : LSX3R_VVV<0x70e88000>;
+def VSLL_W : LSX3R_VVV<0x70e90000>;
+def VSLL_D : LSX3R_VVV<0x70e98000>;
+def VSLLI_B : LSX2RI3_VVI<0x732c2000>;
+def VSLLI_H : LSX2RI4_VVI<0x732c4000>;
+def VSLLI_W : LSX2RI5_VVI<0x732c8000>;
+def VSLLI_D : LSX2RI6_VVI<0x732d0000>;
+
+def VSRL_B : LSX3R_VVV<0x70ea0000>;
+def VSRL_H : LSX3R_VVV<0x70ea8000>;
+def VSRL_W : LSX3R_VVV<0x70eb0000>;
+def VSRL_D : LSX3R_VVV<0x70eb8000>;
+def VSRLI_B : LSX2RI3_VVI<0x73302000>;
+def VSRLI_H : LSX2RI4_VVI<0x73304000>;
+def VSRLI_W : LSX2RI5_VVI<0x73308000>;
+def VSRLI_D : LSX2RI6_VVI<0x73310000>;
+
+def VSRA_B : LSX3R_VVV<0x70ec0000>;
+def VSRA_H : LSX3R_VVV<0x70ec8000>;
+def VSRA_W : LSX3R_VVV<0x70ed0000>;
+def VSRA_D : LSX3R_VVV<0x70ed8000>;
+def VSRAI_B : LSX2RI3_VVI<0x73342000>;
+def VSRAI_H : LSX2RI4_VVI<0x73344000>;
+def VSRAI_W : LSX2RI5_VVI<0x73348000>;
+def VSRAI_D : LSX2RI6_VVI<0x73350000>;
+
+def VROTR_B : LSX3R_VVV<0x70ee0000>;
+def VROTR_H : LSX3R_VVV<0x70ee8000>;
+def VROTR_W : LSX3R_VVV<0x70ef0000>;
+def VROTR_D : LSX3R_VVV<0x70ef8000>;
+def VROTRI_B : LSX2RI3_VVI<0x72a02000>;
+def VROTRI_H : LSX2RI4_VVI<0x72a04000>;
+def VROTRI_W : LSX2RI5_VVI<0x72a08000>;
+def VROTRI_D : LSX2RI6_VVI<0x72a10000>;
+
+def VSLLWIL_H_B : LSX2RI3_VVI<0x73082000>;
+def VSLLWIL_W_H : LSX2RI4_VVI<0x73084000>;
+def VSLLWIL_D_W : LSX2RI5_VVI<0x73088000>;
+def VEXTL_Q_D : LSX2R_VV<0x73090000>;
+def VSLLWIL_HU_BU : LSX2RI3_VVI<0x730c2000>;
+def VSLLWIL_WU_HU : LSX2RI4_VVI<0x730c4000>;
+def VSLLWIL_DU_WU : LSX2RI5_VVI<0x730c8000>;
+def VEXTL_QU_DU : LSX2R_VV<0x730d0000>;
+
+def VSRLR_B : LSX3R_VVV<0x70f00000>;
+def VSRLR_H : LSX3R_VVV<0x70f08000>;
+def VSRLR_W : LSX3R_VVV<0x70f10000>;
+def VSRLR_D : LSX3R_VVV<0x70f18000>;
+def VSRLRI_B : LSX2RI3_VVI<0x72a42000>;
+def VSRLRI_H : LSX2RI4_VVI<0x72a44000>;
+def VSRLRI_W : LSX2RI5_VVI<0x72a48000>;
+def VSRLRI_D : LSX2RI6_VVI<0x72a50000>;
+
+def VSRAR_B : LSX3R_VVV<0x70f20000>;
+def VSRAR_H : LSX3R_VVV<0x70f28000>;
+def VSRAR_W : LSX3R_VVV<0x70f30000>;
+def VSRAR_D : LSX3R_VVV<0x70f38000>;
+def VSRARI_B : LSX2RI3_VVI<0x72a82000>;
+def VSRARI_H : LSX2RI4_VVI<0x72a84000>;
+def VSRARI_W : LSX2RI5_VVI<0x72a88000>;
+def VSRARI_D : LSX2RI6_VVI<0x72a90000>;
+
+def VSRLN_B_H : LSX3R_VVV<0x70f48000>;
+def VSRLN_H_W : LSX3R_VVV<0x70f50000>;
+def VSRLN_W_D : LSX3R_VVV<0x70f58000>;
+def VSRAN_B_H : LSX3R_VVV<0x70f68000>;
+def VSRAN_H_W : LSX3R_VVV<0x70f70000>;
+def VSRAN_W_D : LSX3R_VVV<0x70f78000>;
+
+def VSRLNI_B_H : LSX2RI4_VVVI<0x73404000>;
+def VSRLNI_H_W : LSX2RI5_VVVI<0x73408000>;
+def VSRLNI_W_D : LSX2RI6_VVVI<0x73410000>;
+def VSRLNI_D_Q : LSX2RI7_VVVI<0x73420000>;
+def VSRANI_B_H : LSX2RI4_VVVI<0x73584000>;
+def VSRANI_H_W : LSX2RI5_VVVI<0x73588000>;
+def VSRANI_W_D : LSX2RI6_VVVI<0x73590000>;
+def VSRANI_D_Q : LSX2RI7_VVVI<0x735a0000>;
+
+def VSRLRN_B_H : LSX3R_VVV<0x70f88000>;
+def VSRLRN_H_W : LSX3R_VVV<0x70f90000>;
+def VSRLRN_W_D : LSX3R_VVV<0x70f98000>;
+def VSRARN_B_H : LSX3R_VVV<0x70fa8000>;
+def VSRARN_H_W : LSX3R_VVV<0x70fb0000>;
+def VSRARN_W_D : LSX3R_VVV<0x70fb8000>;
+
+def VSRLRNI_B_H : LSX2RI4_VVVI<0x73444000>;
+def VSRLRNI_H_W : LSX2RI5_VVVI<0x73448000>;
+def VSRLRNI_W_D : LSX2RI6_VVVI<0x73450000>;
+def VSRLRNI_D_Q : LSX2RI7_VVVI<0x73460000>;
+def VSRARNI_B_H : LSX2RI4_VVVI<0x735c4000>;
+def VSRARNI_H_W : LSX2RI5_VVVI<0x735c8000>;
+def VSRARNI_W_D : LSX2RI6_VVVI<0x735d0000>;
+def VSRARNI_D_Q : LSX2RI7_VVVI<0x735e0000>;
+
+def VSSRLN_B_H : LSX3R_VVV<0x70fc8000>;
+def VSSRLN_H_W : LSX3R_VVV<0x70fd0000>;
+def VSSRLN_W_D : LSX3R_VVV<0x70fd8000>;
+def VSSRAN_B_H : LSX3R_VVV<0x70fe8000>;
+def VSSRAN_H_W : LSX3R_VVV<0x70ff0000>;
+def VSSRAN_W_D : LSX3R_VVV<0x70ff8000>;
+def VSSRLN_BU_H : LSX3R_VVV<0x71048000>;
+def VSSRLN_HU_W : LSX3R_VVV<0x71050000>;
+def VSSRLN_WU_D : LSX3R_VVV<0x71058000>;
+def VSSRAN_BU_H : LSX3R_VVV<0x71068000>;
+def VSSRAN_HU_W : LSX3R_VVV<0x71070000>;
+def VSSRAN_WU_D : LSX3R_VVV<0x71078000>;
+
+def VSSRLNI_B_H : LSX2RI4_VVVI<0x73484000>;
+def VSSRLNI_H_W : LSX2RI5_VVVI<0x73488000>;
+def VSSRLNI_W_D : LSX2RI6_VVVI<0x73490000>;
+def VSSRLNI_D_Q : LSX2RI7_VVVI<0x734a0000>;
+def VSSRANI_B_H : LSX2RI4_VVVI<0x73604000>;
+def VSSRANI_H_W : LSX2RI5_VVVI<0x73608000>;
+def VSSRANI_W_D : LSX2RI6_VVVI<0x73610000>;
+def VSSRANI_D_Q : LSX2RI7_VVVI<0x73620000>;
+def VSSRLNI_BU_H : LSX2RI4_VVVI<0x734c4000>;
+def VSSRLNI_HU_W : LSX2RI5_VVVI<0x734c8000>;
+def VSSRLNI_WU_D : LSX2RI6_VVVI<0x734d0000>;
+def VSSRLNI_DU_Q : LSX2RI7_VVVI<0x734e0000>;
+def VSSRANI_BU_H : LSX2RI4_VVVI<0x73644000>;
+def VSSRANI_HU_W : LSX2RI5_VVVI<0x73648000>;
+def VSSRANI_WU_D : LSX2RI6_VVVI<0x73650000>;
+def VSSRANI_DU_Q : LSX2RI7_VVVI<0x73660000>;
+
+def VSSRLRN_B_H : LSX3R_VVV<0x71008000>;
+def VSSRLRN_H_W : LSX3R_VVV<0x71010000>;
+def VSSRLRN_W_D : LSX3R_VVV<0x71018000>;
+def VSSRARN_B_H : LSX3R_VVV<0x71028000>;
+def VSSRARN_H_W : LSX3R_VVV<0x71030000>;
+def VSSRARN_W_D : LSX3R_VVV<0x71038000>;
+def VSSRLRN_BU_H : LSX3R_VVV<0x71088000>;
+def VSSRLRN_HU_W : LSX3R_VVV<0x71090000>;
+def VSSRLRN_WU_D : LSX3R_VVV<0x71098000>;
+def VSSRARN_BU_H : LSX3R_VVV<0x710a8000>;
+def VSSRARN_HU_W : LSX3R_VVV<0x710b0000>;
+def VSSRARN_WU_D : LSX3R_VVV<0x710b8000>;
+
+def VSSRLRNI_B_H : LSX2RI4_VVVI<0x73504000>;
+def VSSRLRNI_H_W : LSX2RI5_VVVI<0x73508000>;
+def VSSRLRNI_W_D : LSX2RI6_VVVI<0x73510000>;
+def VSSRLRNI_D_Q : LSX2RI7_VVVI<0x73520000>;
+def VSSRARNI_B_H : LSX2RI4_VVVI<0x73684000>;
+def VSSRARNI_H_W : LSX2RI5_VVVI<0x73688000>;
+def VSSRARNI_W_D : LSX2RI6_VVVI<0x73690000>;
+def VSSRARNI_D_Q : LSX2RI7_VVVI<0x736a0000>;
+def VSSRLRNI_BU_H : LSX2RI4_VVVI<0x73544000>;
+def VSSRLRNI_HU_W : LSX2RI5_VVVI<0x73548000>;
+def VSSRLRNI_WU_D : LSX2RI6_VVVI<0x73550000>;
+def VSSRLRNI_DU_Q : LSX2RI7_VVVI<0x73560000>;
+def VSSRARNI_BU_H : LSX2RI4_VVVI<0x736c4000>;
+def VSSRARNI_HU_W : LSX2RI5_VVVI<0x736c8000>;
+def VSSRARNI_WU_D : LSX2RI6_VVVI<0x736d0000>;
+def VSSRARNI_DU_Q : LSX2RI7_VVVI<0x736e0000>;
+
+def VCLO_B : LSX2R_VV<0x729c0000>;
+def VCLO_H : LSX2R_VV<0x729c0400>;
+def VCLO_W : LSX2R_VV<0x729c0800>;
+def VCLO_D : LSX2R_VV<0x729c0c00>;
+def VCLZ_B : LSX2R_VV<0x729c1000>;
+def VCLZ_H : LSX2R_VV<0x729c1400>;
+def VCLZ_W : LSX2R_VV<0x729c1800>;
+def VCLZ_D : LSX2R_VV<0x729c1c00>;
+
+def VPCNT_B : LSX2R_VV<0x729c2000>;
+def VPCNT_H : LSX2R_VV<0x729c2400>;
+def VPCNT_W : LSX2R_VV<0x729c2800>;
+def VPCNT_D : LSX2R_VV<0x729c2c00>;
+
+def VBITCLR_B : LSX3R_VVV<0x710c0000>;
+def VBITCLR_H : LSX3R_VVV<0x710c8000>;
+def VBITCLR_W : LSX3R_VVV<0x710d0000>;
+def VBITCLR_D : LSX3R_VVV<0x710d8000>;
+def VBITCLRI_B : LSX2RI3_VVI<0x73102000>;
+def VBITCLRI_H : LSX2RI4_VVI<0x73104000>;
+def VBITCLRI_W : LSX2RI5_VVI<0x73108000>;
+def VBITCLRI_D : LSX2RI6_VVI<0x73110000>;
+
+def VBITSET_B : LSX3R_VVV<0x710e0000>;
+def VBITSET_H : LSX3R_VVV<0x710e8000>;
+def VBITSET_W : LSX3R_VVV<0x710f0000>;
+def VBITSET_D : LSX3R_VVV<0x710f8000>;
+def VBITSETI_B : LSX2RI3_VVI<0x73142000>;
+def VBITSETI_H : LSX2RI4_VVI<0x73144000>;
+def VBITSETI_W : LSX2RI5_VVI<0x73148000>;
+def VBITSETI_D : LSX2RI6_VVI<0x73150000>;
+
+def VBITREV_B : LSX3R_VVV<0x71100000>;
+def VBITREV_H : LSX3R_VVV<0x71108000>;
+def VBITREV_W : LSX3R_VVV<0x71110000>;
+def VBITREV_D : LSX3R_VVV<0x71118000>;
+def VBITREVI_B : LSX2RI3_VVI<0x73182000>;
+def VBITREVI_H : LSX2RI4_VVI<0x73184000>;
+def VBITREVI_W : LSX2RI5_VVI<0x73188000>;
+def VBITREVI_D : LSX2RI6_VVI<0x73190000>;
+
+def VFRSTP_B : LSX3R_VVVV<0x712b0000>;
+def VFRSTP_H : LSX3R_VVVV<0x712b8000>;
+def VFRSTPI_B : LSX2RI5_VVVI<0x729a0000>;
+def VFRSTPI_H : LSX2RI5_VVVI<0x729a8000>;
+
+def VFADD_S : LSX3R_VVV<0x71308000>;
+def VFADD_D : LSX3R_VVV<0x71310000>;
+def VFSUB_S : LSX3R_VVV<0x71328000>;
+def VFSUB_D : LSX3R_VVV<0x71330000>;
+def VFMUL_S : LSX3R_VVV<0x71388000>;
+def VFMUL_D : LSX3R_VVV<0x71390000>;
+def VFDIV_S : LSX3R_VVV<0x713a8000>;
+def VFDIV_D : LSX3R_VVV<0x713b0000>;
+
+def VFMADD_S : LSX4R_VVVV<0x09100000>;
+def VFMADD_D : LSX4R_VVVV<0x09200000>;
+def VFMSUB_S : LSX4R_VVVV<0x09500000>;
+def VFMSUB_D : LSX4R_VVVV<0x09600000>;
+def VFNMADD_S : LSX4R_VVVV<0x09900000>;
+def VFNMADD_D : LSX4R_VVVV<0x09a00000>;
+def VFNMSUB_S : LSX4R_VVVV<0x09d00000>;
+def VFNMSUB_D : LSX4R_VVVV<0x09e00000>;
+
+def VFMAX_S : LSX3R_VVV<0x713c8000>;
+def VFMAX_D : LSX3R_VVV<0x713d0000>;
+def VFMIN_S : LSX3R_VVV<0x713e8000>;
+def VFMIN_D : LSX3R_VVV<0x713f0000>;
+
+def VFMAXA_S : LSX3R_VVV<0x71408000>;
+def VFMAXA_D : LSX3R_VVV<0x71410000>;
+def VFMINA_S : LSX3R_VVV<0x71428000>;
+def VFMINA_D : LSX3R_VVV<0x71430000>;
+
+def VFLOGB_S : LSX2R_VV<0x729cc400>;
+def VFLOGB_D : LSX2R_VV<0x729cc800>;
+
+def VFCLASS_S : LSX2R_VV<0x729cd400>;
+def VFCLASS_D : LSX2R_VV<0x729cd800>;
+
+def VFSQRT_S : LSX2R_VV<0x729ce400>;
+def VFSQRT_D : LSX2R_VV<0x729ce800>;
+def VFRECIP_S : LSX2R_VV<0x729cf400>;
+def VFRECIP_D : LSX2R_VV<0x729cf800>;
+def VFRSQRT_S : LSX2R_VV<0x729d0400>;
+def VFRSQRT_D : LSX2R_VV<0x729d0800>;
+
+def VFCVTL_S_H : LSX2R_VV<0x729de800>;
+def VFCVTH_S_H : LSX2R_VV<0x729dec00>;
+def VFCVTL_D_S : LSX2R_VV<0x729df000>;
+def VFCVTH_D_S : LSX2R_VV<0x729df400>;
+def VFCVT_H_S : LSX3R_VVV<0x71460000>;
+def VFCVT_S_D : LSX3R_VVV<0x71468000>;
+
+def VFRINTRNE_S : LSX2R_VV<0x729d7400>;
+def VFRINTRNE_D : LSX2R_VV<0x729d7800>;
+def VFRINTRZ_S : LSX2R_VV<0x729d6400>;
+def VFRINTRZ_D : LSX2R_VV<0x729d6800>;
+def VFRINTRP_S : LSX2R_VV<0x729d5400>;
+def VFRINTRP_D : LSX2R_VV<0x729d5800>;
+def VFRINTRM_S : LSX2R_VV<0x729d4400>;
+def VFRINTRM_D : LSX2R_VV<0x729d4800>;
+def VFRINT_S : LSX2R_VV<0x729d3400>;
+def VFRINT_D : LSX2R_VV<0x729d3800>;
+
+def VFTINTRNE_W_S : LSX2R_VV<0x729e5000>;
+def VFTINTRNE_L_D : LSX2R_VV<0x729e5400>;
+def VFTINTRZ_W_S : LSX2R_VV<0x729e4800>;
+def VFTINTRZ_L_D : LSX2R_VV<0x729e4c00>;
+def VFTINTRP_W_S : LSX2R_VV<0x729e4000>;
+def VFTINTRP_L_D : LSX2R_VV<0x729e4400>;
+def VFTINTRM_W_S : LSX2R_VV<0x729e3800>;
+def VFTINTRM_L_D : LSX2R_VV<0x729e3c00>;
+def VFTINT_W_S : LSX2R_VV<0x729e3000>;
+def VFTINT_L_D : LSX2R_VV<0x729e3400>;
+def VFTINTRZ_WU_S : LSX2R_VV<0x729e7000>;
+def VFTINTRZ_LU_D : LSX2R_VV<0x729e7400>;
+def VFTINT_WU_S : LSX2R_VV<0x729e5800>;
+def VFTINT_LU_D : LSX2R_VV<0x729e5c00>;
+
+def VFTINTRNE_W_D : LSX3R_VVV<0x714b8000>;
+def VFTINTRZ_W_D : LSX3R_VVV<0x714b0000>;
+def VFTINTRP_W_D : LSX3R_VVV<0x714a8000>;
+def VFTINTRM_W_D : LSX3R_VVV<0x714a0000>;
+def VFTINT_W_D : LSX3R_VVV<0x71498000>;
+
+def VFTINTRNEL_L_S : LSX2R_VV<0x729ea000>;
+def VFTINTRNEH_L_S : LSX2R_VV<0x729ea400>;
+def VFTINTRZL_L_S : LSX2R_VV<0x729e9800>;
+def VFTINTRZH_L_S : LSX2R_VV<0x729e9c00>;
+def VFTINTRPL_L_S : LSX2R_VV<0x729e9000>;
+def VFTINTRPH_L_S : LSX2R_VV<0x729e9400>;
+def VFTINTRML_L_S : LSX2R_VV<0x729e8800>;
+def VFTINTRMH_L_S : LSX2R_VV<0x729e8c00>;
+def VFTINTL_L_S : LSX2R_VV<0x729e8000>;
+def VFTINTH_L_S : LSX2R_VV<0x729e8400>;
+
+def VFFINT_S_W : LSX2R_VV<0x729e0000>;
+def VFFINT_D_L : LSX2R_VV<0x729e0800>;
+def VFFINT_S_WU : LSX2R_VV<0x729e0400>;
+def VFFINT_D_LU : LSX2R_VV<0x729e0c00>;
+def VFFINTL_D_W : LSX2R_VV<0x729e1000>;
+def VFFINTH_D_W : LSX2R_VV<0x729e1400>;
+def VFFINT_S_L : LSX3R_VVV<0x71480000>;
+
+def VSEQ_B : LSX3R_VVV<0x70000000>;
+def VSEQ_H : LSX3R_VVV<0x70008000>;
+def VSEQ_W : LSX3R_VVV<0x70010000>;
+def VSEQ_D : LSX3R_VVV<0x70018000>;
+def VSEQI_B : LSX2RI5_VVI<0x72800000, simm5>;
+def VSEQI_H : LSX2RI5_VVI<0x72808000, simm5>;
+def VSEQI_W : LSX2RI5_VVI<0x72810000, simm5>;
+def VSEQI_D : LSX2RI5_VVI<0x72818000, simm5>;
+
+def VSLE_B : LSX3R_VVV<0x70020000>;
+def VSLE_H : LSX3R_VVV<0x70028000>;
+def VSLE_W : LSX3R_VVV<0x70030000>;
+def VSLE_D : LSX3R_VVV<0x70038000>;
+def VSLEI_B : LSX2RI5_VVI<0x72820000, simm5>;
+def VSLEI_H : LSX2RI5_VVI<0x72828000, simm5>;
+def VSLEI_W : LSX2RI5_VVI<0x72830000, simm5>;
+def VSLEI_D : LSX2RI5_VVI<0x72838000, simm5>;
+
+def VSLE_BU : LSX3R_VVV<0x70040000>;
+def VSLE_HU : LSX3R_VVV<0x70048000>;
+def VSLE_WU : LSX3R_VVV<0x70050000>;
+def VSLE_DU : LSX3R_VVV<0x70058000>;
+def VSLEI_BU : LSX2RI5_VVI<0x72840000>;
+def VSLEI_HU : LSX2RI5_VVI<0x72848000>;
+def VSLEI_WU : LSX2RI5_VVI<0x72850000>;
+def VSLEI_DU : LSX2RI5_VVI<0x72858000>;
+
+def VSLT_B : LSX3R_VVV<0x70060000>;
+def VSLT_H : LSX3R_VVV<0x70068000>;
+def VSLT_W : LSX3R_VVV<0x70070000>;
+def VSLT_D : LSX3R_VVV<0x70078000>;
+def VSLTI_B : LSX2RI5_VVI<0x72860000, simm5>;
+def VSLTI_H : LSX2RI5_VVI<0x72868000, simm5>;
+def VSLTI_W : LSX2RI5_VVI<0x72870000, simm5>;
+def VSLTI_D : LSX2RI5_VVI<0x72878000, simm5>;
+
+def VSLT_BU : LSX3R_VVV<0x70080000>;
+def VSLT_HU : LSX3R_VVV<0x70088000>;
+def VSLT_WU : LSX3R_VVV<0x70090000>;
+def VSLT_DU : LSX3R_VVV<0x70098000>;
+def VSLTI_BU : LSX2RI5_VVI<0x72880000>;
+def VSLTI_HU : LSX2RI5_VVI<0x72888000>;
+def VSLTI_WU : LSX2RI5_VVI<0x72890000>;
+def VSLTI_DU : LSX2RI5_VVI<0x72898000>;
+
+def VFCMP_CAF_S : LSX3R_VVV<0x0c500000>;
+def VFCMP_SAF_S : LSX3R_VVV<0x0c508000>;
+def VFCMP_CLT_S : LSX3R_VVV<0x0c510000>;
+def VFCMP_SLT_S : LSX3R_VVV<0x0c518000>;
+def VFCMP_CEQ_S : LSX3R_VVV<0x0c520000>;
+def VFCMP_SEQ_S : LSX3R_VVV<0x0c528000>;
+def VFCMP_CLE_S : LSX3R_VVV<0x0c530000>;
+def VFCMP_SLE_S : LSX3R_VVV<0x0c538000>;
+def VFCMP_CUN_S : LSX3R_VVV<0x0c540000>;
+def VFCMP_SUN_S : LSX3R_VVV<0x0c548000>;
+def VFCMP_CULT_S : LSX3R_VVV<0x0c550000>;
+def VFCMP_SULT_S : LSX3R_VVV<0x0c558000>;
+def VFCMP_CUEQ_S : LSX3R_VVV<0x0c560000>;
+def VFCMP_SUEQ_S : LSX3R_VVV<0x0c568000>;
+def VFCMP_CULE_S : LSX3R_VVV<0x0c570000>;
+def VFCMP_SULE_S : LSX3R_VVV<0x0c578000>;
+def VFCMP_CNE_S : LSX3R_VVV<0x0c580000>;
+def VFCMP_SNE_S : LSX3R_VVV<0x0c588000>;
+def VFCMP_COR_S : LSX3R_VVV<0x0c5a0000>;
+def VFCMP_SOR_S : LSX3R_VVV<0x0c5a8000>;
+def VFCMP_CUNE_S : LSX3R_VVV<0x0c5c0000>;
+def VFCMP_SUNE_S : LSX3R_VVV<0x0c5c8000>;
+
+def VFCMP_CAF_D : LSX3R_VVV<0x0c600000>;
+def VFCMP_SAF_D : LSX3R_VVV<0x0c608000>;
+def VFCMP_CLT_D : LSX3R_VVV<0x0c610000>;
+def VFCMP_SLT_D : LSX3R_VVV<0x0c618000>;
+def VFCMP_CEQ_D : LSX3R_VVV<0x0c620000>;
+def VFCMP_SEQ_D : LSX3R_VVV<0x0c628000>;
+def VFCMP_CLE_D : LSX3R_VVV<0x0c630000>;
+def VFCMP_SLE_D : LSX3R_VVV<0x0c638000>;
+def VFCMP_CUN_D : LSX3R_VVV<0x0c640000>;
+def VFCMP_SUN_D : LSX3R_VVV<0x0c648000>;
+def VFCMP_CULT_D : LSX3R_VVV<0x0c650000>;
+def VFCMP_SULT_D : LSX3R_VVV<0x0c658000>;
+def VFCMP_CUEQ_D : LSX3R_VVV<0x0c660000>;
+def VFCMP_SUEQ_D : LSX3R_VVV<0x0c668000>;
+def VFCMP_CULE_D : LSX3R_VVV<0x0c670000>;
+def VFCMP_SULE_D : LSX3R_VVV<0x0c678000>;
+def VFCMP_CNE_D : LSX3R_VVV<0x0c680000>;
+def VFCMP_SNE_D : LSX3R_VVV<0x0c688000>;
+def VFCMP_COR_D : LSX3R_VVV<0x0c6a0000>;
+def VFCMP_SOR_D : LSX3R_VVV<0x0c6a8000>;
+def VFCMP_CUNE_D : LSX3R_VVV<0x0c6c0000>;
+def VFCMP_SUNE_D : LSX3R_VVV<0x0c6c8000>;
+
+def VBITSEL_V : LSX4R_VVVV<0x0d100000>;
+
+def VBITSELI_B : LSX2RI8_VVVI<0x73c40000>;
+
+def VSETEQZ_V : LSX2R_CV<0x729c9800>;
+def VSETNEZ_V : LSX2R_CV<0x729c9c00>;
+def VSETANYEQZ_B : LSX2R_CV<0x729ca000>;
+def VSETANYEQZ_H : LSX2R_CV<0x729ca400>;
+def VSETANYEQZ_W : LSX2R_CV<0x729ca800>;
+def VSETANYEQZ_D : LSX2R_CV<0x729cac00>;
+def VSETALLNEZ_B : LSX2R_CV<0x729cb000>;
+def VSETALLNEZ_H : LSX2R_CV<0x729cb400>;
+def VSETALLNEZ_W : LSX2R_CV<0x729cb800>;
+def VSETALLNEZ_D : LSX2R_CV<0x729cbc00>;
+
+def VINSGR2VR_B : LSX2RI4_VVRI<0x72eb8000>;
+def VINSGR2VR_H : LSX2RI3_VVRI<0x72ebc000>;
+def VINSGR2VR_W : LSX2RI2_VVRI<0x72ebe000>;
+def VINSGR2VR_D : LSX2RI1_VVRI<0x72ebf000>;
+def VPICKVE2GR_B : LSX2RI4_RVI<0x72ef8000>;
+def VPICKVE2GR_H : LSX2RI3_RVI<0x72efc000>;
+def VPICKVE2GR_W : LSX2RI2_RVI<0x72efe000>;
+def VPICKVE2GR_D : LSX2RI1_RVI<0x72eff000>;
+def VPICKVE2GR_BU : LSX2RI4_RVI<0x72f38000>;
+def VPICKVE2GR_HU : LSX2RI3_RVI<0x72f3c000>;
+def VPICKVE2GR_WU : LSX2RI2_RVI<0x72f3e000>;
+def VPICKVE2GR_DU : LSX2RI1_RVI<0x72f3f000>;
+
+def VREPLGR2VR_B : LSX2R_VR<0x729f0000>;
+def VREPLGR2VR_H : LSX2R_VR<0x729f0400>;
+def VREPLGR2VR_W : LSX2R_VR<0x729f0800>;
+def VREPLGR2VR_D : LSX2R_VR<0x729f0c00>;
+
+def VREPLVE_B : LSX3R_VVR<0x71220000>;
+def VREPLVE_H : LSX3R_VVR<0x71228000>;
+def VREPLVE_W : LSX3R_VVR<0x71230000>;
+def VREPLVE_D : LSX3R_VVR<0x71238000>;
+def VREPLVEI_B : LSX2RI4_VVI<0x72f78000>;
+def VREPLVEI_H : LSX2RI3_VVI<0x72f7c000>;
+def VREPLVEI_W : LSX2RI2_VVI<0x72f7e000>;
+def VREPLVEI_D : LSX2RI1_VVI<0x72f7f000>;
+
+def VBSLL_V : LSX2RI5_VVI<0x728e0000>;
+def VBSRL_V : LSX2RI5_VVI<0x728e8000>;
+
+def VPACKEV_B : LSX3R_VVV<0x71160000>;
+def VPACKEV_H : LSX3R_VVV<0x71168000>;
+def VPACKEV_W : LSX3R_VVV<0x71170000>;
+def VPACKEV_D : LSX3R_VVV<0x71178000>;
+def VPACKOD_B : LSX3R_VVV<0x71180000>;
+def VPACKOD_H : LSX3R_VVV<0x71188000>;
+def VPACKOD_W : LSX3R_VVV<0x71190000>;
+def VPACKOD_D : LSX3R_VVV<0x71198000>;
+
+def VPICKEV_B : LSX3R_VVV<0x711e0000>;
+def VPICKEV_H : LSX3R_VVV<0x711e8000>;
+def VPICKEV_W : LSX3R_VVV<0x711f0000>;
+def VPICKEV_D : LSX3R_VVV<0x711f8000>;
+def VPICKOD_B : LSX3R_VVV<0x71200000>;
+def VPICKOD_H : LSX3R_VVV<0x71208000>;
+def VPICKOD_W : LSX3R_VVV<0x71210000>;
+def VPICKOD_D : LSX3R_VVV<0x71218000>;
+
+def VILVL_B : LSX3R_VVV<0x711a0000>;
+def VILVL_H : LSX3R_VVV<0x711a8000>;
+def VILVL_W : LSX3R_VVV<0x711b0000>;
+def VILVL_D : LSX3R_VVV<0x711b8000>;
+def VILVH_B : LSX3R_VVV<0x711c0000>;
+def VILVH_H : LSX3R_VVV<0x711c8000>;
+def VILVH_W : LSX3R_VVV<0x711d0000>;
+def VILVH_D : LSX3R_VVV<0x711d8000>;
+
+def VSHUF_B : LSX4R_VVVV<0x0d500000>;
+
+def VSHUF_H : LSX3R_VVVV<0x717a8000>;
+def VSHUF_W : LSX3R_VVVV<0x717b0000>;
+def VSHUF_D : LSX3R_VVVV<0x717b8000>;
+
+def VSHUF4I_B : LSX2RI8_VVVI<0x73900000>;
+def VSHUF4I_H : LSX2RI8_VVVI<0x73940000>;
+def VSHUF4I_W : LSX2RI8_VVVI<0x73980000>;
+def VSHUF4I_D : LSX2RI8_VVVI<0x739c0000>;
+
+def VPERMI_W : LSX2RI8_VVVI<0x73e40000>;
+
+def VEXTRINS_D : LSX2RI8_VVVI<0x73800000>;
+def VEXTRINS_W : LSX2RI8_VVVI<0x73840000>;
+def VEXTRINS_H : LSX2RI8_VVVI<0x73880000>;
+def VEXTRINS_B : LSX2RI8_VVVI<0x738c0000>;
+} // mayLoad = 0, mayStore = 0
+
+let mayLoad = 1, mayStore = 0 in {
+def VLD : LSX2RI12_VRI<0x2c000000>;
+def VLDX : LSX3R_VRR<0x38400000>;
+
+def VLDREPL_B : LSX2RI12_VRI<0x30800000>;
+def VLDREPL_H : LSX2RI11_VRI<0x30400000>;
+def VLDREPL_W : LSX2RI10_VRI<0x30200000>;
+def VLDREPL_D : LSX2RI9_VRI<0x30100000>;
+} // mayLoad = 1, mayStore = 0
+
+let mayLoad = 0, mayStore = 1 in {
+def VST : LSX2RI12_VRI<0x2c400000>;
+def VSTX : LSX3R_VRR<0x38440000>;
+
+def VSTELM_B : LSX2RI8I4_VRII<0x31800000>;
+def VSTELM_H : LSX2RI8I3_VRII<0x31400000, simm8_lsl1>;
+def VSTELM_W : LSX2RI8I2_VRII<0x31200000, simm8_lsl2>;
+def VSTELM_D : LSX2RI8I1_VRII<0x31100000, simm8_lsl3>;
+} // mayLoad = 0, mayStore = 1
+
+} // hasSideEffects = 0, Predicates = [HasExtLSX]
+
+/// Pseudo-instructions
+
+let Predicates = [HasExtLSX] in {
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
+    isAsmParserOnly = 1 in {
+def PseudoVREPLI_B : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [],
+                            "vrepli.b", "$vd, $imm">;
+def PseudoVREPLI_H : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [],
+                            "vrepli.h", "$vd, $imm">;
+def PseudoVREPLI_W : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [],
+                            "vrepli.w", "$vd, $imm">;
+def PseudoVREPLI_D : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [],
+                            "vrepli.d", "$vd, $imm">;
+}
+
+} // Predicates = [HasExtLSX]

diff  --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td
index b34e03367cba8e..47cf6c1948dade 100644
--- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td
@@ -37,6 +37,12 @@ class LoongArchReg64<LoongArchReg32 subreg>
   let SubRegIndices = [sub_32];
 }
 
+def sub_64 : SubRegIndex<64>;
+class LoongArchReg128<LoongArchReg64 subreg, string n>
+    : LoongArchRegWithSubRegs<subreg.HWEncoding, n, [subreg]> {
+  let SubRegIndices = [sub_64];
+}
+
 let FallbackRegAltNameIndex = NoRegAltName in
 def RegAliasName : RegAltNameIndex;
 } // Namespace = "LoongArch"
@@ -174,3 +180,13 @@ def FCSR#I : LoongArchReg<I, "fcsr"#I>;
 
 let isAllocatable = false in
 def FCSR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCSR%u", 0, 3)>;
+
+// LSX registers
+
+foreach I = 0-31 in
+def VR#I : LoongArchReg128<!cast<LoongArchReg64>("F"#I#"_64"), "vr"#I>,
+           DwarfRegAlias<!cast<LoongArchReg64>("F"#I#"_64")>;
+
+def LSX128 : RegisterClass<"LoongArch",
+                           [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64],
+                           128, (sequence "VR%u", 0, 31)>;

diff  --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index 174261906c31b2..95429ce84d401d 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -43,6 +43,11 @@ class LoongArchMCCodeEmitter : public MCCodeEmitter {
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const override;
 
+  template <unsigned Opc>
+  void expandToVectorLDI(const MCInst &MI, SmallVectorImpl<char> &CB,
+                         SmallVectorImpl<MCFixup> &Fixups,
+                         const MCSubtargetInfo &STI) const;
+
   /// TableGen'erated function for getting the binary encoding for an
   /// instruction.
   uint64_t getBinaryCodeForInstr(const MCInst &MI,
@@ -65,12 +70,21 @@ class LoongArchMCCodeEmitter : public MCCodeEmitter {
 
   /// Return binary encoding of an immediate operand specified by OpNo.
   /// The value returned is the value of the immediate shifted right
-  //  arithmetically by 2.
+  //  arithmetically by N.
   /// Note that this function is dedicated to specific immediate types,
   /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2.
-  unsigned getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
-                             SmallVectorImpl<MCFixup> &Fixups,
-                             const MCSubtargetInfo &STI) const;
+  template <unsigned N>
+  unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo,
+                            SmallVectorImpl<MCFixup> &Fixups,
+                            const MCSubtargetInfo &STI) const {
+    const MCOperand &MO = MI.getOperand(OpNo);
+    if (MO.isImm()) {
+      unsigned Res = MI.getOperand(OpNo).getImm();
+      assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero");
+      return Res >> N;
+    }
+    return getExprOpValue(MI, MO, Fixups, STI);
+  }
 
   unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO,
                           SmallVectorImpl<MCFixup> &Fixups,
@@ -101,21 +115,6 @@ LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
   return MI.getOperand(OpNo).getImm() - 1;
 }
 
-unsigned
-LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
-                                          SmallVectorImpl<MCFixup> &Fixups,
-                                          const MCSubtargetInfo &STI) const {
-  const MCOperand &MO = MI.getOperand(OpNo);
-
-  if (MO.isImm()) {
-    unsigned Res = MI.getOperand(OpNo).getImm();
-    assert((Res & 3) == 0 && "lowest 2 bits are non-zero");
-    return Res >> 2;
-  }
-
-  return getExprOpValue(MI, MO, Fixups, STI);
-}
-
 unsigned
 LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
@@ -273,6 +272,29 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
   return 0;
 }
 
+template <unsigned Opc>
+void LoongArchMCCodeEmitter::expandToVectorLDI(
+    const MCInst &MI, SmallVectorImpl<char> &CB,
+    SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
+  int64_t Imm = MI.getOperand(1).getImm() & 0x3FF;
+  switch (MI.getOpcode()) {
+  case LoongArch::PseudoVREPLI_B:
+    break;
+  case LoongArch::PseudoVREPLI_H:
+    Imm |= 0x400;
+    break;
+  case LoongArch::PseudoVREPLI_W:
+    Imm |= 0x800;
+    break;
+  case LoongArch::PseudoVREPLI_D:
+    Imm |= 0xC00;
+    break;
+  }
+  MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm);
+  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
+  support::endian::write(CB, Binary, support::little);
+}
+
 void LoongArchMCCodeEmitter::encodeInstruction(
     const MCInst &MI, SmallVectorImpl<char> &CB,
     SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
@@ -280,6 +302,16 @@ void LoongArchMCCodeEmitter::encodeInstruction(
   // Get byte count of instruction.
   unsigned Size = Desc.getSize();
 
+  switch (MI.getOpcode()) {
+  default:
+    break;
+  case LoongArch::PseudoVREPLI_B:
+  case LoongArch::PseudoVREPLI_H:
+  case LoongArch::PseudoVREPLI_W:
+  case LoongArch::PseudoVREPLI_D:
+    return expandToVectorLDI<LoongArch::VLDI>(MI, CB, Fixups, STI);
+  }
+
   switch (Size) {
   default:
     llvm_unreachable("Unhandled encodeInstruction length!");


        


More information about the llvm-commits mailing list