Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISCV][MC] Add assembler support for XRivosVisni #128773

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

preames
Copy link
Collaborator

@preames preames commented Feb 25, 2025

This implements assembler support for the XRivosVisni custom/vendor extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See src/xrivosvisni.adoc)

Codegen support will follow in separate changes.

This implements assembler support for the XRivosVisni custom/vendor
extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See
src/xrivosvisni.adoc)

Codegen support will follow in a separate change.
@preames preames requested review from lenary and topperc February 25, 2025 21:01
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' mc Machine (object) code labels Feb 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

@llvm/pr-subscribers-mc

Author: Philip Reames (preames)

Changes

This implements assembler support for the XRivosVisni custom/vendor extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See src/xrivosvisni.adoc)

Codegen support will follow in separate changes.


Full diff: https://github.com/llvm/llvm-project/pull/128773.diff

7 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+6-3)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td (+64)
  • (added) llvm/test/MC/RISCV/xrivosvisni-valid.s (+40)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..fbb86d39f4df1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -204,6 +204,7 @@
 // CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
 // CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+// CHECK-NEXT:     xrivosvisni          0.1       'XRivosVisni' (Rivos Vector Small Integer New)
 // CHECK-NEXT:     xrivosvizip          0.1       'XRivosVizip' (Rivos Vector Register Zips)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..d368ec4809838 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -468,6 +468,9 @@ The current vendor extensions supported are:
 ``Xmipslsp``
   LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
 
+``experimental-XRivosVisni``
+  LLVM implements `version 0.1 of the Rivos Vector Integer Small New Instructions extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
+
 ``experimental-XRivosVizip``
   LLVM implements `version 0.1 of the Rivos Vector Register Zips extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
 
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1025b57369f4a..bd26254d89af0 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -622,6 +622,10 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
 #define TRY_TO_DECODE_FEATURE_ANY(FEATURES, DECODER_TABLE, DESC)               \
   TRY_TO_DECODE((STI.getFeatureBits() & (FEATURES)).any(), DECODER_TABLE, DESC)
 
+static constexpr FeatureBitset XRivosFeatureGroup = {
+    RISCV::FeatureVendorXRivosVisni, RISCV::FeatureVendorXRivosVizip,
+};
+
 static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
     RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
@@ -717,12 +721,11 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "CORE-V SIMD extensions");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
                         "CORE-V Immediate Branching");
-
   TRY_TO_DECODE_FEATURE_ANY(XqciFeatureGroup, DecoderTableXqci32,
                             "Qualcomm uC Extensions");
 
-  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXRivosVizip, DecoderTableXRivos32,
-                        "Rivos");
+  TRY_TO_DECODE_FEATURE_ANY(XRivosFeatureGroup, DecoderTableXRivos32,
+                            "Rivos");
 
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32");
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..1a11da9f97261 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcilo
 
 // Rivos Extension(s)
 
+def FeatureVendorXRivosVisni
+    :  RISCVExperimentalExtension<0, 1, "Rivos Vector Small Integer New">;
+def HasVendorXRivosVisni
+    : Predicate<"Subtarget->hasVendorXRivosVisni()">,
+      AssemblerPredicate<(all_of FeatureVendorXRivosVisni),
+                         "'XRivosVizisni' (Rivos Vector Small Integer New)">;
+
 def FeatureVendorXRivosVizip
     :  RISCVExperimentalExtension<0, 1, "Rivos Vector Register Zips">;
 def HasVendorXRivosVizip
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
index 4890c3b1b9505..e8ef9a08127e6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
@@ -10,6 +10,46 @@
 //
 //===----------------------------------------------------------------------===//
 
+class RVInstVXI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> rs1;
+  bits<5> vd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = imm;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
+class RVInstXVI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> vs2;
+  bits<5> rd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = imm;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
 //===----------------------------------------------------------------------===//
 // XRivosVizip
 //===----------------------------------------------------------------------===//
@@ -25,3 +65,27 @@ defm RI_VZIP2B_V : VALU_IV_V<"ri.vzip2b", 0b010100>;
 defm RI_VUNZIP2A_V : VALU_IV_V<"ri.vunzip2a", 0b001000>;
 defm RI_VUNZIP2B_V : VALU_IV_V<"ri.vunzip2b", 0b011000>;
 }
+
+//===----------------------------------------------------------------------===//
+// XRivosVisni
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXRivosVisni], DecoderNamespace = "XRivos",
+  Inst<6-0> = OPC_CUSTOM_2.Value, mayLoad = false, mayStore = false,
+  hasSideEffects = false in {
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1, vm = 0, vs2=0 in
+def RI_VZERO : RVInstV<0b000000, 0b00000, OPCFG, (outs VR:$vd),
+                     (ins), "ri.vzero", "$vd">;
+
+let vm = 0, Constraints = "$vd = $vd_wb", RVVConstraint = NoConstraint in
+def RI_VINSERT : RVInstVXI<0b010000, OPMVX, (outs VR:$vd_wb),
+                           (ins VR:$vd, GPR:$rs1, uimm5:$imm),
+                           "ri.vinsert.v.x", "$vd, $rs1, $imm">;
+
+let vm = 1, RVVConstraint = NoConstraint in
+def RI_VEXTRACT : RVInstXVI<0b010111, OPMVV, (outs GPR:$rd),
+                            (ins VR:$vs2, uimm5:$imm),
+                            "ri.vextract.x.v", "$rd, $vs2, $imm">;
+
+}
diff --git a/llvm/test/MC/RISCV/xrivosvisni-valid.s b/llvm/test/MC/RISCV/xrivosvisni-valid.s
new file mode 100644
index 0000000000000..17cb1305642ac
--- /dev/null
+++ b/llvm/test/MC/RISCV/xrivosvisni-valid.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ri.vzero v1
+# CHECK-ASM: encoding: [0xdb,0x70,0x00,0x00]
+ri.vzero v1
+# CHECK-ASM-AND-OBJ: vzero v2
+# CHECK-ASM: encoding: [0x5b,0x71,0x00,0x00]
+ri.vzero v2
+# CHECK-ASM-AND-OBJ: vzero v3
+# CHECK-ASM: encoding: [0xdb,0x71,0x00,0x00]
+ri.vzero v3
+
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x v0, zero, 0
+# CHECK-ASM: encoding: [0x5b,0x60,0x00,0x40]
+ri.vinsert.v.x v0, x0, 0
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, s4, 13
+# CHECK-ASM: encoding: [0xdb,0x60,0xda,0x40]
+ri.vinsert.v.x v1, x20, 13
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, zero, 1
+# CHECK-ASM: encoding: [0xdb,0x60,0x10,0x40]
+ri.vinsert.v.x v1, x0, 1
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v23, ra, 1
+# CHECK-ASM: encoding: [0xdb,0xeb,0x10,0x40]
+ri.vinsert.v.x v23, x1, 1
+
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s4, v1, 13
+# CHECK-ASM: encoding: [0x5b,0xaa,0x16,0x5e]
+ri.vextract.x.v x20, v1, 13
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s5, v2, 31
+# CHECK-ASM: encoding: [0xdb,0xaa,0x2f,0x5e]
+ri.vextract.x.v x21, v2, 31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..8adf95e82e652 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1130,6 +1130,7 @@ Experimental extensions
     xqcilo               0.2
     xqcilsm              0.2
     xqcisls              0.2
+    xrivosvisni          0.1
     xrivosvizip          0.1
 
 Supported Profiles

@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

@llvm/pr-subscribers-clang

Author: Philip Reames (preames)

Changes

This implements assembler support for the XRivosVisni custom/vendor extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See src/xrivosvisni.adoc)

Codegen support will follow in separate changes.


Full diff: https://github.com/llvm/llvm-project/pull/128773.diff

7 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+6-3)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td (+64)
  • (added) llvm/test/MC/RISCV/xrivosvisni-valid.s (+40)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..fbb86d39f4df1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -204,6 +204,7 @@
 // CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
 // CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+// CHECK-NEXT:     xrivosvisni          0.1       'XRivosVisni' (Rivos Vector Small Integer New)
 // CHECK-NEXT:     xrivosvizip          0.1       'XRivosVizip' (Rivos Vector Register Zips)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..d368ec4809838 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -468,6 +468,9 @@ The current vendor extensions supported are:
 ``Xmipslsp``
   LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
 
+``experimental-XRivosVisni``
+  LLVM implements `version 0.1 of the Rivos Vector Integer Small New Instructions extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
+
 ``experimental-XRivosVizip``
   LLVM implements `version 0.1 of the Rivos Vector Register Zips extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
 
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1025b57369f4a..bd26254d89af0 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -622,6 +622,10 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
 #define TRY_TO_DECODE_FEATURE_ANY(FEATURES, DECODER_TABLE, DESC)               \
   TRY_TO_DECODE((STI.getFeatureBits() & (FEATURES)).any(), DECODER_TABLE, DESC)
 
+static constexpr FeatureBitset XRivosFeatureGroup = {
+    RISCV::FeatureVendorXRivosVisni, RISCV::FeatureVendorXRivosVizip,
+};
+
 static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
     RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
@@ -717,12 +721,11 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "CORE-V SIMD extensions");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
                         "CORE-V Immediate Branching");
-
   TRY_TO_DECODE_FEATURE_ANY(XqciFeatureGroup, DecoderTableXqci32,
                             "Qualcomm uC Extensions");
 
-  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXRivosVizip, DecoderTableXRivos32,
-                        "Rivos");
+  TRY_TO_DECODE_FEATURE_ANY(XRivosFeatureGroup, DecoderTableXRivos32,
+                            "Rivos");
 
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32");
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..1a11da9f97261 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcilo
 
 // Rivos Extension(s)
 
+def FeatureVendorXRivosVisni
+    :  RISCVExperimentalExtension<0, 1, "Rivos Vector Small Integer New">;
+def HasVendorXRivosVisni
+    : Predicate<"Subtarget->hasVendorXRivosVisni()">,
+      AssemblerPredicate<(all_of FeatureVendorXRivosVisni),
+                         "'XRivosVizisni' (Rivos Vector Small Integer New)">;
+
 def FeatureVendorXRivosVizip
     :  RISCVExperimentalExtension<0, 1, "Rivos Vector Register Zips">;
 def HasVendorXRivosVizip
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
index 4890c3b1b9505..e8ef9a08127e6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
@@ -10,6 +10,46 @@
 //
 //===----------------------------------------------------------------------===//
 
+class RVInstVXI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> rs1;
+  bits<5> vd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = imm;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
+class RVInstXVI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> vs2;
+  bits<5> rd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = imm;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
 //===----------------------------------------------------------------------===//
 // XRivosVizip
 //===----------------------------------------------------------------------===//
@@ -25,3 +65,27 @@ defm RI_VZIP2B_V : VALU_IV_V<"ri.vzip2b", 0b010100>;
 defm RI_VUNZIP2A_V : VALU_IV_V<"ri.vunzip2a", 0b001000>;
 defm RI_VUNZIP2B_V : VALU_IV_V<"ri.vunzip2b", 0b011000>;
 }
+
+//===----------------------------------------------------------------------===//
+// XRivosVisni
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXRivosVisni], DecoderNamespace = "XRivos",
+  Inst<6-0> = OPC_CUSTOM_2.Value, mayLoad = false, mayStore = false,
+  hasSideEffects = false in {
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1, vm = 0, vs2=0 in
+def RI_VZERO : RVInstV<0b000000, 0b00000, OPCFG, (outs VR:$vd),
+                     (ins), "ri.vzero", "$vd">;
+
+let vm = 0, Constraints = "$vd = $vd_wb", RVVConstraint = NoConstraint in
+def RI_VINSERT : RVInstVXI<0b010000, OPMVX, (outs VR:$vd_wb),
+                           (ins VR:$vd, GPR:$rs1, uimm5:$imm),
+                           "ri.vinsert.v.x", "$vd, $rs1, $imm">;
+
+let vm = 1, RVVConstraint = NoConstraint in
+def RI_VEXTRACT : RVInstXVI<0b010111, OPMVV, (outs GPR:$rd),
+                            (ins VR:$vs2, uimm5:$imm),
+                            "ri.vextract.x.v", "$rd, $vs2, $imm">;
+
+}
diff --git a/llvm/test/MC/RISCV/xrivosvisni-valid.s b/llvm/test/MC/RISCV/xrivosvisni-valid.s
new file mode 100644
index 0000000000000..17cb1305642ac
--- /dev/null
+++ b/llvm/test/MC/RISCV/xrivosvisni-valid.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ri.vzero v1
+# CHECK-ASM: encoding: [0xdb,0x70,0x00,0x00]
+ri.vzero v1
+# CHECK-ASM-AND-OBJ: vzero v2
+# CHECK-ASM: encoding: [0x5b,0x71,0x00,0x00]
+ri.vzero v2
+# CHECK-ASM-AND-OBJ: vzero v3
+# CHECK-ASM: encoding: [0xdb,0x71,0x00,0x00]
+ri.vzero v3
+
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x v0, zero, 0
+# CHECK-ASM: encoding: [0x5b,0x60,0x00,0x40]
+ri.vinsert.v.x v0, x0, 0
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, s4, 13
+# CHECK-ASM: encoding: [0xdb,0x60,0xda,0x40]
+ri.vinsert.v.x v1, x20, 13
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, zero, 1
+# CHECK-ASM: encoding: [0xdb,0x60,0x10,0x40]
+ri.vinsert.v.x v1, x0, 1
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v23, ra, 1
+# CHECK-ASM: encoding: [0xdb,0xeb,0x10,0x40]
+ri.vinsert.v.x v23, x1, 1
+
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s4, v1, 13
+# CHECK-ASM: encoding: [0x5b,0xaa,0x16,0x5e]
+ri.vextract.x.v x20, v1, 13
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s5, v2, 31
+# CHECK-ASM: encoding: [0xdb,0xaa,0x2f,0x5e]
+ri.vextract.x.v x21, v2, 31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..8adf95e82e652 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1130,6 +1130,7 @@ Experimental extensions
     xqcilo               0.2
     xqcilsm              0.2
     xqcisls              0.2
+    xrivosvisni          0.1
     xrivosvizip          0.1
 
 Supported Profiles

@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

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

Author: Philip Reames (preames)

Changes

This implements assembler support for the XRivosVisni custom/vendor extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See src/xrivosvisni.adoc)

Codegen support will follow in separate changes.


Full diff: https://github.com/llvm/llvm-project/pull/128773.diff

7 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+6-3)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td (+64)
  • (added) llvm/test/MC/RISCV/xrivosvisni-valid.s (+40)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..fbb86d39f4df1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -204,6 +204,7 @@
 // CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
 // CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+// CHECK-NEXT:     xrivosvisni          0.1       'XRivosVisni' (Rivos Vector Small Integer New)
 // CHECK-NEXT:     xrivosvizip          0.1       'XRivosVizip' (Rivos Vector Register Zips)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..d368ec4809838 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -468,6 +468,9 @@ The current vendor extensions supported are:
 ``Xmipslsp``
   LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
 
+``experimental-XRivosVisni``
+  LLVM implements `version 0.1 of the Rivos Vector Integer Small New Instructions extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
+
 ``experimental-XRivosVizip``
   LLVM implements `version 0.1 of the Rivos Vector Register Zips extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
 
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1025b57369f4a..bd26254d89af0 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -622,6 +622,10 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
 #define TRY_TO_DECODE_FEATURE_ANY(FEATURES, DECODER_TABLE, DESC)               \
   TRY_TO_DECODE((STI.getFeatureBits() & (FEATURES)).any(), DECODER_TABLE, DESC)
 
+static constexpr FeatureBitset XRivosFeatureGroup = {
+    RISCV::FeatureVendorXRivosVisni, RISCV::FeatureVendorXRivosVizip,
+};
+
 static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
     RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
@@ -717,12 +721,11 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "CORE-V SIMD extensions");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
                         "CORE-V Immediate Branching");
-
   TRY_TO_DECODE_FEATURE_ANY(XqciFeatureGroup, DecoderTableXqci32,
                             "Qualcomm uC Extensions");
 
-  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXRivosVizip, DecoderTableXRivos32,
-                        "Rivos");
+  TRY_TO_DECODE_FEATURE_ANY(XRivosFeatureGroup, DecoderTableXRivos32,
+                            "Rivos");
 
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32");
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..1a11da9f97261 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcilo
 
 // Rivos Extension(s)
 
+def FeatureVendorXRivosVisni
+    :  RISCVExperimentalExtension<0, 1, "Rivos Vector Small Integer New">;
+def HasVendorXRivosVisni
+    : Predicate<"Subtarget->hasVendorXRivosVisni()">,
+      AssemblerPredicate<(all_of FeatureVendorXRivosVisni),
+                         "'XRivosVizisni' (Rivos Vector Small Integer New)">;
+
 def FeatureVendorXRivosVizip
     :  RISCVExperimentalExtension<0, 1, "Rivos Vector Register Zips">;
 def HasVendorXRivosVizip
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
index 4890c3b1b9505..e8ef9a08127e6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
@@ -10,6 +10,46 @@
 //
 //===----------------------------------------------------------------------===//
 
+class RVInstVXI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> rs1;
+  bits<5> vd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = imm;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
+class RVInstXVI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> vs2;
+  bits<5> rd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = imm;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
 //===----------------------------------------------------------------------===//
 // XRivosVizip
 //===----------------------------------------------------------------------===//
@@ -25,3 +65,27 @@ defm RI_VZIP2B_V : VALU_IV_V<"ri.vzip2b", 0b010100>;
 defm RI_VUNZIP2A_V : VALU_IV_V<"ri.vunzip2a", 0b001000>;
 defm RI_VUNZIP2B_V : VALU_IV_V<"ri.vunzip2b", 0b011000>;
 }
+
+//===----------------------------------------------------------------------===//
+// XRivosVisni
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXRivosVisni], DecoderNamespace = "XRivos",
+  Inst<6-0> = OPC_CUSTOM_2.Value, mayLoad = false, mayStore = false,
+  hasSideEffects = false in {
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1, vm = 0, vs2=0 in
+def RI_VZERO : RVInstV<0b000000, 0b00000, OPCFG, (outs VR:$vd),
+                     (ins), "ri.vzero", "$vd">;
+
+let vm = 0, Constraints = "$vd = $vd_wb", RVVConstraint = NoConstraint in
+def RI_VINSERT : RVInstVXI<0b010000, OPMVX, (outs VR:$vd_wb),
+                           (ins VR:$vd, GPR:$rs1, uimm5:$imm),
+                           "ri.vinsert.v.x", "$vd, $rs1, $imm">;
+
+let vm = 1, RVVConstraint = NoConstraint in
+def RI_VEXTRACT : RVInstXVI<0b010111, OPMVV, (outs GPR:$rd),
+                            (ins VR:$vs2, uimm5:$imm),
+                            "ri.vextract.x.v", "$rd, $vs2, $imm">;
+
+}
diff --git a/llvm/test/MC/RISCV/xrivosvisni-valid.s b/llvm/test/MC/RISCV/xrivosvisni-valid.s
new file mode 100644
index 0000000000000..17cb1305642ac
--- /dev/null
+++ b/llvm/test/MC/RISCV/xrivosvisni-valid.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ri.vzero v1
+# CHECK-ASM: encoding: [0xdb,0x70,0x00,0x00]
+ri.vzero v1
+# CHECK-ASM-AND-OBJ: vzero v2
+# CHECK-ASM: encoding: [0x5b,0x71,0x00,0x00]
+ri.vzero v2
+# CHECK-ASM-AND-OBJ: vzero v3
+# CHECK-ASM: encoding: [0xdb,0x71,0x00,0x00]
+ri.vzero v3
+
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x v0, zero, 0
+# CHECK-ASM: encoding: [0x5b,0x60,0x00,0x40]
+ri.vinsert.v.x v0, x0, 0
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, s4, 13
+# CHECK-ASM: encoding: [0xdb,0x60,0xda,0x40]
+ri.vinsert.v.x v1, x20, 13
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, zero, 1
+# CHECK-ASM: encoding: [0xdb,0x60,0x10,0x40]
+ri.vinsert.v.x v1, x0, 1
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v23, ra, 1
+# CHECK-ASM: encoding: [0xdb,0xeb,0x10,0x40]
+ri.vinsert.v.x v23, x1, 1
+
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s4, v1, 13
+# CHECK-ASM: encoding: [0x5b,0xaa,0x16,0x5e]
+ri.vextract.x.v x20, v1, 13
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s5, v2, 31
+# CHECK-ASM: encoding: [0xdb,0xaa,0x2f,0x5e]
+ri.vextract.x.v x21, v2, 31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..8adf95e82e652 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1130,6 +1130,7 @@ Experimental extensions
     xqcilo               0.2
     xqcilsm              0.2
     xqcisls              0.2
+    xrivosvisni          0.1
     xrivosvizip          0.1
 
 Supported Profiles

@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

@llvm/pr-subscribers-clang-driver

Author: Philip Reames (preames)

Changes

This implements assembler support for the XRivosVisni custom/vendor extension from Rivos Inc. which is defined in:
https://github.com/rivosinc/rivos-custom-extensions (See src/xrivosvisni.adoc)

Codegen support will follow in separate changes.


Full diff: https://github.com/llvm/llvm-project/pull/128773.diff

7 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+6-3)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td (+64)
  • (added) llvm/test/MC/RISCV/xrivosvisni-valid.s (+40)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..fbb86d39f4df1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -204,6 +204,7 @@
 // CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
 // CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+// CHECK-NEXT:     xrivosvisni          0.1       'XRivosVisni' (Rivos Vector Small Integer New)
 // CHECK-NEXT:     xrivosvizip          0.1       'XRivosVizip' (Rivos Vector Register Zips)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..d368ec4809838 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -468,6 +468,9 @@ The current vendor extensions supported are:
 ``Xmipslsp``
   LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
 
+``experimental-XRivosVisni``
+  LLVM implements `version 0.1 of the Rivos Vector Integer Small New Instructions extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
+
 ``experimental-XRivosVizip``
   LLVM implements `version 0.1 of the Rivos Vector Register Zips extension specification <https://github.com/rivosinc/rivos-custom-extensions>`__.
 
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1025b57369f4a..bd26254d89af0 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -622,6 +622,10 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
 #define TRY_TO_DECODE_FEATURE_ANY(FEATURES, DECODER_TABLE, DESC)               \
   TRY_TO_DECODE((STI.getFeatureBits() & (FEATURES)).any(), DECODER_TABLE, DESC)
 
+static constexpr FeatureBitset XRivosFeatureGroup = {
+    RISCV::FeatureVendorXRivosVisni, RISCV::FeatureVendorXRivosVizip,
+};
+
 static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
     RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
@@ -717,12 +721,11 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "CORE-V SIMD extensions");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
                         "CORE-V Immediate Branching");
-
   TRY_TO_DECODE_FEATURE_ANY(XqciFeatureGroup, DecoderTableXqci32,
                             "Qualcomm uC Extensions");
 
-  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXRivosVizip, DecoderTableXRivos32,
-                        "Rivos");
+  TRY_TO_DECODE_FEATURE_ANY(XRivosFeatureGroup, DecoderTableXRivos32,
+                            "Rivos");
 
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32");
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..1a11da9f97261 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcilo
 
 // Rivos Extension(s)
 
+def FeatureVendorXRivosVisni
+    :  RISCVExperimentalExtension<0, 1, "Rivos Vector Small Integer New">;
+def HasVendorXRivosVisni
+    : Predicate<"Subtarget->hasVendorXRivosVisni()">,
+      AssemblerPredicate<(all_of FeatureVendorXRivosVisni),
+                         "'XRivosVizisni' (Rivos Vector Small Integer New)">;
+
 def FeatureVendorXRivosVizip
     :  RISCVExperimentalExtension<0, 1, "Rivos Vector Register Zips">;
 def HasVendorXRivosVizip
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
index 4890c3b1b9505..e8ef9a08127e6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXRivos.td
@@ -10,6 +10,46 @@
 //
 //===----------------------------------------------------------------------===//
 
+class RVInstVXI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> rs1;
+  bits<5> vd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = imm;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
+class RVInstXVI<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
+                string opcodestr, string argstr>
+    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> imm;
+  bits<5> vs2;
+  bits<5> rd;
+  bit vm;
+
+  let Inst{31-26} = funct6;
+  let Inst{25} = vm;
+  let Inst{24-20} = vs2;
+  let Inst{19-15} = imm;
+  let Inst{14-12} = opv.Value;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = OPC_OP_V.Value;
+
+  let Uses = [VTYPE, VL];
+  let RVVConstraint = VMConstraint;
+}
+
 //===----------------------------------------------------------------------===//
 // XRivosVizip
 //===----------------------------------------------------------------------===//
@@ -25,3 +65,27 @@ defm RI_VZIP2B_V : VALU_IV_V<"ri.vzip2b", 0b010100>;
 defm RI_VUNZIP2A_V : VALU_IV_V<"ri.vunzip2a", 0b001000>;
 defm RI_VUNZIP2B_V : VALU_IV_V<"ri.vunzip2b", 0b011000>;
 }
+
+//===----------------------------------------------------------------------===//
+// XRivosVisni
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXRivosVisni], DecoderNamespace = "XRivos",
+  Inst<6-0> = OPC_CUSTOM_2.Value, mayLoad = false, mayStore = false,
+  hasSideEffects = false in {
+
+let isReMaterializable = 1, isAsCheapAsAMove = 1, vm = 0, vs2=0 in
+def RI_VZERO : RVInstV<0b000000, 0b00000, OPCFG, (outs VR:$vd),
+                     (ins), "ri.vzero", "$vd">;
+
+let vm = 0, Constraints = "$vd = $vd_wb", RVVConstraint = NoConstraint in
+def RI_VINSERT : RVInstVXI<0b010000, OPMVX, (outs VR:$vd_wb),
+                           (ins VR:$vd, GPR:$rs1, uimm5:$imm),
+                           "ri.vinsert.v.x", "$vd, $rs1, $imm">;
+
+let vm = 1, RVVConstraint = NoConstraint in
+def RI_VEXTRACT : RVInstXVI<0b010111, OPMVV, (outs GPR:$rd),
+                            (ins VR:$vs2, uimm5:$imm),
+                            "ri.vextract.x.v", "$rd, $vs2, $imm">;
+
+}
diff --git a/llvm/test/MC/RISCV/xrivosvisni-valid.s b/llvm/test/MC/RISCV/xrivosvisni-valid.s
new file mode 100644
index 0000000000000..17cb1305642ac
--- /dev/null
+++ b/llvm/test/MC/RISCV/xrivosvisni-valid.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-xrivosvisni -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-xrivosvisni < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xrivosvisni -M no-aliases --no-print-imm-hex -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ri.vzero v1
+# CHECK-ASM: encoding: [0xdb,0x70,0x00,0x00]
+ri.vzero v1
+# CHECK-ASM-AND-OBJ: vzero v2
+# CHECK-ASM: encoding: [0x5b,0x71,0x00,0x00]
+ri.vzero v2
+# CHECK-ASM-AND-OBJ: vzero v3
+# CHECK-ASM: encoding: [0xdb,0x71,0x00,0x00]
+ri.vzero v3
+
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x v0, zero, 0
+# CHECK-ASM: encoding: [0x5b,0x60,0x00,0x40]
+ri.vinsert.v.x v0, x0, 0
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, s4, 13
+# CHECK-ASM: encoding: [0xdb,0x60,0xda,0x40]
+ri.vinsert.v.x v1, x20, 13
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v1, zero, 1
+# CHECK-ASM: encoding: [0xdb,0x60,0x10,0x40]
+ri.vinsert.v.x v1, x0, 1
+# CHECK-ASM-AND-OBJ: ri.vinsert.v.x	v23, ra, 1
+# CHECK-ASM: encoding: [0xdb,0xeb,0x10,0x40]
+ri.vinsert.v.x v23, x1, 1
+
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s4, v1, 13
+# CHECK-ASM: encoding: [0x5b,0xaa,0x16,0x5e]
+ri.vextract.x.v x20, v1, 13
+# CHECK-ASM-AND-OBJ: ri.vextract.x.v	s5, v2, 31
+# CHECK-ASM: encoding: [0xdb,0xaa,0x2f,0x5e]
+ri.vextract.x.v x21, v2, 31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..8adf95e82e652 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1130,6 +1130,7 @@ Experimental extensions
     xqcilo               0.2
     xqcilsm              0.2
     xqcisls              0.2
+    xrivosvisni          0.1
     xrivosvizip          0.1
 
 Supported Profiles

Copy link

github-actions bot commented Feb 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one nit, otherwise looks good I think. I didn't closely inspect the encodings.


let isReMaterializable = 1, isAsCheapAsAMove = 1, vm = 0, vs2=0 in
def RI_VZERO : RVInstV<0b000000, 0b00000, OPCFG, (outs VR:$vd),
(ins), "ri.vzero", "$vd">;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(ins), "ri.vzero", "$vd">;
(ins), "ri.vzero.v", "$vd">;

The document uses this mnemonic - should we use it here? I'm not entirely up to date on the V-extensions, and how mnemonics are generally handled there though, and what the conventions are.

def HasVendorXRivosVisni
: Predicate<"Subtarget->hasVendorXRivosVisni()">,
AssemblerPredicate<(all_of FeatureVendorXRivosVisni),
"'XRivosVizisni' (Rivos Vector Small Integer New)">;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the spec uses "Vector Integer Small New", should it be consistent here as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think it might be 'XRivosVisni' rather than 'XRivosVizisni'?

let Inst{19-15} = rs1;
let Inst{14-12} = opv.Value;
let Inst{11-7} = vd;
let Inst{6-0} = OPC_OP_V.Value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec uses CUSTOM_2 not OP_V

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants