[clang] [llvm] [RISCV] Add Andes XAndesperf (Andes Performance) extension. (PR #135110)

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 9 18:05:34 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Jim Lin (tclin914)

<details>
<summary>Changes</summary>

The spec can be found at:
https://github.com/andestech/andes-v5-isa/releases/tag/ast-v5_4_0-release.

This patch only supports assembler.

Relocation and fixup for the branch and gp-implied instructions will be added in a later patch.

---

Patch is 39.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135110.diff


16 Files Affected:

- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) 
- (modified) llvm/docs/RISCVUsage.rst (+3) 
- (modified) llvm/docs/ReleaseNotes.md (+1) 
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+45-11) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+16-6) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+18-5) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+9) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1) 
- (added) llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td (+358) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+4) 
- (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1) 
- (added) llvm/test/MC/RISCV/xandesperf-invalid.s (+56) 
- (added) llvm/test/MC/RISCV/xandesperf-rv64-invalid.s (+20) 
- (added) llvm/test/MC/RISCV/xandesperf-rv64-valid.s (+34) 
- (added) llvm/test/MC/RISCV/xandesperf-valid.s (+105) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1) 


``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index d06cedac5b1eb..f65bfcc2e44d6 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -154,6 +154,7 @@
 // CHECK-NEXT:     svnapot              1.0       'Svnapot' (NAPOT Translation Contiguity)
 // CHECK-NEXT:     svpbmt               1.0       'Svpbmt' (Page-Based Memory Types)
 // CHECK-NEXT:     svvptc               1.0       'Svvptc' (Obviating Memory-Management Instructions after Marking PTEs Valid)
+// CHECK-NEXT:     xandesperf           5.0       'XAndesPerf' (Andes Performance Extension)
 // CHECK-NEXT:     xcvalu               1.0       'XCValu' (CORE-V ALU Operations)
 // CHECK-NEXT:     xcvbi                1.0       'XCVbi' (CORE-V Immediate Branching)
 // CHECK-NEXT:     xcvbitmanip          1.0       'XCVbitmanip' (CORE-V Bit Manipulation)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index cda7e5fec8488..118f45abc1c31 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -503,6 +503,9 @@ The current vendor extensions supported are:
 ``experimental-XRivosVizip``
   LLVM implements `version 0.1 of the Rivos Vector Register Zips extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
 
+``XAndesPerf``
+  LLVM implements `version 5.0.0 of the Andes Performance Extension specification <https://github.com/andestech/andes-v5-isa/releases/download/ast-v5_4_0-release/AndeStar_V5_ISA_Spec_UM165-v1.5.08-20250317.pdf>` by Andes Technology. All instructions are prefixed with `nds.` as described in the specification.
+
 Experimental C Intrinsics
 =========================
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 526d6b4002bba..6c219a5af8398 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -159,6 +159,7 @@ Changes to the RISC-V Backend
 * Adds assembler support for ``.option exact``, which disables automatic compression,
   and branch and linker relaxation. This can be disabled with ``.option noexact``,
   which is also the default.
+* Adds assembler support for the Andes `XAndesperf` (Andes Performance extension).
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index c57c123ab01dc..3dafc21b84c21 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -536,19 +536,24 @@ struct RISCVOperand final : public MCParsedAsmOperand {
   }
 
   // True if operand is a symbol with no modifiers, or a constant with no
-  // modifiers and isShiftedInt<N-1, 1>(Op).
-  template <int N> bool isBareSimmNLsb0() const {
-    int64_t Imm;
-    RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+  // modifiers and isShiftedInt<N-K, K>(Op).
+  template <unsigned N, unsigned K> bool isBareSimmNLsbK() const {
     if (!isImm())
       return false;
-    bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
-    bool IsValid;
-    if (!IsConstantImm)
-      IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
-    else
-      IsValid = isShiftedInt<N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
-    return IsValid && VK == RISCVMCExpr::VK_None;
+
+    int64_t Imm;
+    if (evaluateConstantImm(getImm(), Imm))
+      return isShiftedInt<N - K, K>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+    RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+    return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+           VK == RISCVMCExpr::VK_None;
+  }
+
+  // True if operand is a symbol with no modifiers, or a constant with no
+  // modifiers and isShiftedInt<N-1, 1>(Op).
+  template <int N> bool isBareSimmNLsb0() const {
+    return isBareSimmNLsbK<N, 1>();
   }
 
   // True if operand is a symbol with no modifiers, or a constant with no
@@ -856,6 +861,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return SignExtend64<32>(Imm);
   }
 
+  bool isSImm11Lsb0() const { return isBareSimmNLsb0<11>(); }
+
   bool isSImm12() const {
     if (!isImm())
       return false;
@@ -940,6 +947,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
         [](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); });
   }
 
+  bool isSImm18() const { return isBareSimmNLsbK<18, 0>(); }
+
+  bool isSImm18Lsb0() const { return isBareSimmNLsb0<18>(); }
+
+  bool isSImm19Lsb00() const { return isBareSimmNLsbK<19, 2>(); }
+
+  bool isSImm20Lsb000() const { return isBareSimmNLsbK<20, 3>(); }
+
   bool isSImm32Lsb0() const {
     return isSImmPred([](int64_t Imm) { return isShiftedInt<31, 1>(Imm); });
   }
@@ -1511,6 +1526,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidSImm11:
     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
                                       (1 << 10) - 1);
+  case Match_InvalidSImm11Lsb0:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
+        "immediate must be a multiple of 2 bytes in the range");
   case Match_InvalidUImm10:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
   case Match_InvalidUImm11:
@@ -1583,6 +1602,21 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                       (1 << 4),
                                       "immediate must be in the range");
   }
+  case Match_InvalidSImm18:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
+                                      (1 << 17) - 1);
+  case Match_InvalidSImm18Lsb0:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
+        "immediate must be a multiple of 2 bytes in the range");
+  case Match_InvalidSImm19Lsb00:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
+        "immediate must be a multiple of 4 bytes in the range");
+  case Match_InvalidSImm20Lsb000:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
+        "immediate must be a multiple of 8 bytes in the range");
   case Match_InvalidSImm26:
     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
                                       (1 << 25) - 1);
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 366291b53bebb..c793bf2fa75f2 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -447,18 +447,25 @@ static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
 }
 
-template <unsigned N>
-static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
+template <unsigned T, unsigned N>
+static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint64_t Imm,
                                              int64_t Address,
                                              const MCDisassembler *Decoder) {
-  assert(isUInt<N>(Imm) && "Invalid immediate");
-  // Sign-extend the number in the bottom N bits of Imm after accounting for
-  // the fact that the N bit immediate is stored in N-1 bits (the LSB is
+  assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");
+  // Sign-extend the number in the bottom T bits of Imm after accounting for
+  // the fact that the T bit immediate is stored in T-N bits (the LSB is
   // always zero)
-  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
+  Inst.addOperand(MCOperand::createImm(SignExtend64<T>(Imm << N)));
   return MCDisassembler::Success;
 }
 
+template <unsigned T>
+static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
+                                             int64_t Address,
+                                             const MCDisassembler *Decoder) {
+  return decodeSImmOperandAndLslN<T, 1>(Inst, Imm, Address, Decoder);
+}
+
 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
@@ -727,6 +734,8 @@ static constexpr FeatureBitset XTHeadGroup = {
     RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,
     RISCV::FeatureVendorXTHeadVdot};
 
+static constexpr FeatureBitset XAndesGroup = {RISCV::FeatureVendorXAndesPerf};
+
 static constexpr DecoderListEntry DecoderList32[]{
     // Vendor Extensions
     {DecoderTableXVentana32,
@@ -740,6 +749,7 @@ static constexpr DecoderListEntry DecoderList32[]{
     {DecoderTableXmipscmove32,
      {RISCV::FeatureVendorXMIPSCMove},
      "MIPS mips.ccmov"},
+    {DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
     // Standard Extensions
     {DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},
     {DecoderTableXqci32, XqciFeatureGroup, "Qualcomm uC Extensions"},
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 95858da45f202..ed56a92d08af8 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -96,6 +96,11 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  template <unsigned N>
+  unsigned getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
   uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo,
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const;
@@ -535,21 +540,29 @@ RISCVMCCodeEmitter::getImmOpValueSlist(const MCInst &MI, unsigned OpNo,
   }
 }
 
-uint64_t
-RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
+template <unsigned N>
+unsigned
+RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const {
   const MCOperand &MO = MI.getOperand(OpNo);
 
   if (MO.isImm()) {
-    uint64_t Res = MO.getImm();
-    assert((Res & 1) == 0 && "LSB is non-zero");
-    return Res >> 1;
+    unsigned Res = MO.getImm();
+    assert((Res & ((1 << N) - 1)) == 0 && "LSB is non-zero");
+    return Res >> N;
   }
 
   return getImmOpValue(MI, OpNo, Fixups, STI);
 }
 
+uint64_t
+RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
+                                      SmallVectorImpl<MCFixup> &Fixups,
+                                      const MCSubtargetInfo &STI) const {
+  return getImmOpValueAsrN<1>(MI, OpNo, Fixups, STI);
+}
+
 uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 60d3c0f397371..19bf35359e49e 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1479,6 +1479,15 @@ def HasVendorXRivosVizip
       AssemblerPredicate<(all_of FeatureVendorXRivosVizip),
                          "'XRivosVizip' (Rivos Vector Register Zips)">;
 
+// Andes Extension(s)
+
+def FeatureVendorXAndesPerf
+    : RISCVExtension<5, 0, "Andes Performance Extension">;
+def HasVendorXAndesPerf
+    : Predicate<"Subtarget->hasVendorXAndesPerf()">,
+      AssemblerPredicate<(all_of FeatureVendorXAndesPerf),
+                         "'XAndesPerf' (Andes Performance Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index c87452171f090..f1d455987c713 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2182,6 +2182,7 @@ include "RISCVInstrInfoXqci.td"
 include "RISCVInstrInfoXqccmp.td"
 include "RISCVInstrInfoXMips.td"
 include "RISCVInstrInfoXRivos.td"
+include "RISCVInstrInfoXAndes.td"
 
 //===----------------------------------------------------------------------===//
 // Global ISel
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
new file mode 100644
index 0000000000000..afe6e784dbfb0
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -0,0 +1,358 @@
+//===-- RISCVInstrInfoXAndes.td ----------------------------*- 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 vendor extensions defined by Andes Technology.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+// A 11-bit signed immediate where the least significant bit is zero.
+def simm11_lsb0 : Operand<OtherVT> {
+  let ParserMatchClass = SImmAsmOperand<11, "Lsb0">;
+  let PrintMethod = "printBranchOperand";
+  let EncoderMethod = "getImmOpValueAsr1";
+  let DecoderMethod = "decodeSImmOperandAndLsl1<11>";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (MCOp.evaluateAsConstantImm(Imm))
+      return isShiftedInt<10, 1>(Imm);
+    return MCOp.isBareSymbolRef();
+  }];
+  let OperandType = "OPERAND_PCREL";
+}
+
+def simm18 : Operand<XLenVT> {
+  let ParserMatchClass = SImmAsmOperand<18>;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeSImmOperand<18>";
+}
+
+def simm18_lsb0 : Operand<XLenVT> {
+  let ParserMatchClass = SImmAsmOperand<18, "Lsb0">;
+  let EncoderMethod = "getImmOpValueAsr1";
+  let DecoderMethod = "decodeSImmOperandAndLsl1<18>";
+}
+
+def simm19_lsb00 : Operand<XLenVT> {
+  let ParserMatchClass = SImmAsmOperand<19, "Lsb00">;
+  let EncoderMethod = "getImmOpValueAsrN<2>";
+  let DecoderMethod = "decodeSImmOperandAndLslN<19, 2>";
+}
+
+def simm20_lsb000 : Operand<XLenVT> {
+  let ParserMatchClass = SImmAsmOperand<20, "Lsb000">;
+  let EncoderMethod = "getImmOpValueAsrN<3>";
+  let DecoderMethod = "decodeSImmOperandAndLslN<20, 3>";
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+class NDSRVInstBB<bit cs, string opcodestr>
+    : RVInst<(outs), (ins GPR:$rs1, uimmlog2xlen:$cimm, simm11_lsb0:$imm10),
+             opcodestr, "$rs1, $cimm, $imm10", [], InstFormatOther>,
+      Sched<[WriteJmp, ReadIALU]> {
+  bits<10> imm10;
+  bits<5> rs1;
+  bits<6> cimm;
+
+  let Inst{31} = imm10{9};
+  let Inst{30} = cs;
+  let Inst{29-25} = imm10{8-4};
+  let Inst{24-20} = cimm{4-0};
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = 0b111;
+  let Inst{11-8} = imm10{3-0};
+  let Inst{7} = cimm{5};
+  let Inst{6-0} = OPC_CUSTOM_2.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let isBranch = 1;
+  let isTerminator = 1;
+}
+
+class NDSRVInstBC<bits<3> funct3, string opcodestr>
+    : RVInst<(outs), (ins GPR:$rs1, uimm7:$cimm, simm11_lsb0:$imm10),
+             opcodestr, "$rs1, $cimm, $imm10", [], InstFormatOther>,
+      Sched<[WriteJmp, ReadIALU]> {
+  bits<10> imm10;
+  bits<5> rs1;
+  bits<7> cimm;
+
+  let Inst{31} = imm10{9};
+  let Inst{30} = cimm{6};
+  let Inst{29-25} = imm10{8-4};
+  let Inst{24-20} = cimm{4-0};
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-8} = imm10{3-0};
+  let Inst{7} = cimm{5};
+  let Inst{6-0} = OPC_CUSTOM_2.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+  let isBranch = 1;
+  let isTerminator = 1;
+}
+
+class NDSRVInstBFO<bits<3> funct3, string opcodestr>
+    : RVInst<(outs GPR:$rd), (ins GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb),
+             opcodestr, "$rd, $rs1, $msb, $lsb", [], InstFormatOther>,
+      Sched<[WriteIALU, ReadIALU]> {
+  bits<5> rd;
+  bits<5> rs1;
+  bits<6> msb;
+  bits<6> lsb;
+
+  let Inst{31-26} = msb;
+  let Inst{25-20} = lsb;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_CUSTOM_2.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class NDSRVInstRR<bits<7> funct7, string opcodestr>
+    : RVInstR<funct7, 0b000, OPC_CUSTOM_2,
+              (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
+              opcodestr, "$rd, $rs1, $rs2">,
+      Sched<[WriteIALU, ReadIALU, ReadIALU]> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+}
+
+// GP: ADDI, LB, LBU
+class NDSRVInstLBGP<bits<2> funct2, string opcodestr>
+    : RVInst<(outs GPR:$rd), (ins simm18:$imm18),
+             opcodestr, "$rd, ${imm18}", [], InstFormatOther> {
+  bits<18> imm18;
+  bits<5> rd;
+
+  let Inst{31} = imm18{17};
+  let Inst{30-21} = imm18{10-1};
+  let Inst{20} = imm18{11};
+  let Inst{19-17} = imm18{14-12};
+  let Inst{16-15} = imm18{16-15};
+  let Inst{14} = imm18{0};
+  let Inst{13-12} = funct2;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_CUSTOM_0.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+}
+
+// GP: LH, LHU
+class NDSRVInstLHGP<bits<3> funct3, string opcodestr>
+    : RVInst<(outs GPR:$rd), (ins simm18_lsb0:$imm17),
+             opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
+  bits<17> imm17;
+  bits<5> rd;
+
+  let Inst{31} = imm17{16};
+  let Inst{30-21} = imm17{9-0};
+  let Inst{20} = imm17{10};
+  let Inst{19-17} = imm17{13-11};
+  let Inst{16-15} = imm17{15-14};
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_CUSTOM_1.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+}
+
+class NDSRVInstLWGP<bits<3> funct3, string opcodestr>
+    : RVInst<(outs GPR:$rd), (ins simm19_lsb00:$imm17),
+             opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
+  bits<17> imm17;
+  bits<5> rd;
+
+  let Inst{31} = imm17{16};
+  let Inst{30-22} = imm17{8-0};
+  let Inst{21} = imm17{15};
+  let Inst{20} = imm17{9};
+  let Inst{19-17} = imm17{12-10};
+  let Inst{16-15} = imm17{14-13};
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_CUSTOM_1.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+}
+
+// GP: LD
+class NDSRVInstLDGP<bits<3> funct3, string opcodestr>
+    : RVInst<(outs GPR:$rd), (ins simm20_lsb000:$imm17),
+             opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
+  bits<17> imm17;
+  bits<5> rd;
+
+  let Inst{31} = imm17{16};
+  let Inst{30-23} = imm17{7-0};
+  let Inst{22-21} = imm17{15-14};
+  let Inst{20} = imm17{8};
+  let Inst{19-17} = imm17{11-9};
+  let Inst{16-15} = imm17{13-12};
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_CUSTOM_1.Value;
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+}
+
+// GP: SB
+class NDSRVInstSBGP<bits<2> funct2, string opcodestr>
+    : RVInst<(outs), (ins GPR:$rs2, simm18:$imm18),
+             opcodestr, "$rs2, ${imm18}", [], InstFormatOther> {
+  bits<18> imm18;
+  bits<5> rs2;
+
+  let Inst{31} = imm18{17};
+  let Inst{30-25} = imm18{10-5};
+  let Inst{24-20} = rs2;
+  let Inst{19-17} = imm18{14-12};
+  let Inst{16-15} = imm18{16-15};
+  let Inst{14} = imm18{0};
+  let Inst{13-12} = funct2;
+  let Inst{11-8} = imm18{4-1};
+  let Inst{7} = imm18{11};
+  let Inst{...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/135110


More information about the cfe-commits mailing list