[clang] [llvm] [RISCV] Add Qualcomm uC Xqcisim (Simulation Hint) extension (PR #128833)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 25 22:49:18 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-driver

Author: Sudharsan Veeravalli (svs-quic)

<details>
<summary>Changes</summary>

This extension adds 10 instructions that provide hints to the interface simulation environment.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/

This patch adds assembler only support.

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


11 Files Affected:

- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) 
- (modified) llvm/docs/RISCVUsage.rst (+3) 
- (modified) llvm/docs/ReleaseNotes.md (+2) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+1-1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+50) 
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) 
- (added) llvm/test/MC/RISCV/xqcisim-invalid.s (+125) 
- (added) llvm/test/MC/RISCV/xqcisim-valid.s (+52) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+2-1) 


``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..5a5d2db7df072 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -203,6 +203,7 @@
 // CHECK-NEXT:     xqcilia              0.2       'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
 // 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:     xqcisim              0.2       'Xqcisim' (Qualcomm uC Simulation Hint Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
 // CHECK-NEXT:     xrivosvizip          0.1       'XRivosVizip' (Rivos Vector Register Zips)
 // CHECK-EMPTY:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..bbb98cd209b98 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -459,6 +459,9 @@ The current vendor extensions supported are:
 ``experimental-Xqcilsm``
   LLVM implements `version 0.2 of the Qualcomm uC Load Store Multiple extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
+``experimental-Xqcisim``
+  LLVM implements `version 0.2 of the Qualcomm uC Simulation Hint extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
+
 ``experimental-Xqcisls``
   LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 2a617901a1146..2dc49bbd945a5 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -109,6 +109,8 @@ Changes to the RISC-V Backend
 
 * Adds experimental assembler support for the Qualcomm uC 'Xqcilia` (Large Immediate Arithmetic)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcisim` (Simulation Hint)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 1025b57369f4a..81ace9138fded 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -628,7 +628,7 @@ static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcics,  RISCV::FeatureVendorXqcicsr,
     RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilia,
     RISCV::FeatureVendorXqcilo,  RISCV::FeatureVendorXqcilsm,
-    RISCV::FeatureVendorXqcisls,
+    RISCV::FeatureVendorXqcisim, RISCV::FeatureVendorXqcisls,
 };
 
 DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..e60c0e611179c 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1374,6 +1374,14 @@ def HasVendorXqcilo
       AssemblerPredicate<(all_of FeatureVendorXqcilo),
                          "'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)">;
 
+def FeatureVendorXqcisim
+    : RISCVExperimentalExtension<0, 2, "Qualcomm uC Simulation Hint Extension",
+                                 [FeatureStdExtZca]>;
+def HasVendorXqcisim
+    : Predicate<"Subtarget->hasVendorXqcisim()">,
+                AssemblerPredicate<(all_of FeatureVendorXqcisim),
+                "'Xqcisim' (Qualcomm uC Simulation Hint Extension)">;
+
 // Rivos Extension(s)
 
 def FeatureVendorXRivosVizip
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index b1283d0e3ae18..16fca9b2de978 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -215,6 +215,19 @@ class QCIInt_IMM<bits<1> funct1, string opcodestr>
   let Inst{24-20} = imm10{9-5};
 }
 
+class QCISim_NONE<bits<4> imm11_8, string opcodestr>
+    : RVInstI<0b010, OPC_OP_IMM, (outs), (ins), opcodestr, ""> {
+  let rs1 = 0;
+  let rd = 0;
+  let imm12 = {imm11_8, 0b00000000};
+}
+
+class QCISim_RS1<bits<4> imm11_8, string opcodestr>
+    : RVInstI<0b010, OPC_OP_IMM, (outs), (ins GPR:$rs1), opcodestr, "$rs1"> {
+  let rd = 0;
+  let imm12 = {imm11_8, 0b00000000};
+}
+
 class QCIRVInstEIBase<bits<3> funct3, bits<2> funct2, dag outs,
                       dag ins, string opcodestr, string argstr>
     : RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {
@@ -485,6 +498,43 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcilia, IsRV32]
 
+let Predicates = [HasVendorXqcisim, IsRV32] in {
+let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
+  def QC_PSYSCALLI : RVInstI<0b010, OPC_OP_IMM, (outs),
+                                  (ins uimm10:$imm10), "qc.psyscalli",
+                                  "$imm10"> {
+    bits<10> imm10;
+
+    let rs1 = 0;
+    let rd = 0;
+    let imm12 = {0b00, imm10};
+  }
+
+  def QC_PPUTCI : RVInstI<0b010, OPC_OP_IMM, (outs), (ins uimm8:$imm8),
+                               "qc.pputci", "$imm8"> {
+    bits<8> imm8;
+
+    let rs1 = 0;
+    let rd = 0;
+    let imm12 = {0b0100, imm8};
+  }
+
+  def QC_PCOREDUMP : QCISim_NONE<0b0110, "qc.pcoredump">;
+  def QC_PPREGS : QCISim_NONE<0b0111, "qc.ppregs">;
+  def QC_PPREG : QCISim_RS1<0b1000, "qc.ppreg">;
+  def QC_PPUTC : QCISim_RS1<0b1001, "qc.pputc">;
+  def QC_PPUTS : QCISim_RS1<0b1010, "qc.pputs">;
+  def QC_PEXIT : QCISim_RS1<0b1011, "qc.pexit">;
+  def QC_PSYSCALL : QCISim_RS1<0b1100, "qc.psyscall">;
+
+  def QC_C_PTRACE : RVInst16CI<0b000, 0b10, (outs), (ins), "qc.c.ptrace", ""> {
+    let rd = 0;
+    let imm = 0;
+    let Inst{6-2} = 0;
+  }
+} // mayLoad = 0, mayStore = 0, hasSideEffects = 1
+} // Predicates = [HasVendorXqcisim, IsRV32]
+
 } // DecoderNamespace = "Xqci"
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 132c47ca631b6..3e34695a1a6db 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -744,7 +744,7 @@ Error RISCVISAInfo::checkDependency() {
   static constexpr StringLiteral XqciExts[] = {
       {"xqcia"},  {"xqciac"},  {"xqcicli"}, {"xqcicm"},
       {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcilia"},
-      {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
+      {"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}};
 
   if (HasI && HasE)
     return getIncompatibleError("i", "e");
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index daab7b236879f..e638c5fc4fcc9 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -91,6 +91,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisim %s -o - | FileCheck --check-prefix=RV32XQCISIM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
@@ -408,6 +409,7 @@
 ; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
 ; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"
 ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
+; RV32XQCISIM: attribute 5, "rv32i2p1_zca1p0_xqcisim0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
diff --git a/llvm/test/MC/RISCV/xqcisim-invalid.s b/llvm/test/MC/RISCV/xqcisim-invalid.s
new file mode 100644
index 0000000000000..c8fe925b623f6
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcisim-invalid.s
@@ -0,0 +1,125 @@
+# Xqcisim - Simulaton Hint Instructions
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisim < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisim < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [0, 1023]
+qc.psyscalli 1024
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.psyscalli
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.psyscalli 23, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.psyscalli       1023
+
+
+# CHECK-PLUS: :[[@LINE+1]]:11: error: immediate must be an integer in the range [0, 255]
+qc.pputci 256
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.pputci
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.pputci 200, x8
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.pputci  255
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.ptrace x0
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.ptrace 1
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.c.ptrace
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.pcoredump 12
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.pcoredump x4
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.pcoredump
+
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.ppregs x1
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.ppregs 23
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.ppregs
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.ppreg x10, x2
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.ppreg
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.ppreg 23
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.ppreg   a0
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.pputc x7, x3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.pputc
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.pputc 34
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.pputc   t2
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.pputs x15, x18
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.pputs
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.pputs 45
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.pputs   a5
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.pexit x26, x23
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.pexit
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.pexit 78
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.pexit   s10
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.psyscall x11, x5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.psyscall
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.psyscall 98
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
+qc.psyscall        a1
diff --git a/llvm/test/MC/RISCV/xqcisim-valid.s b/llvm/test/MC/RISCV/xqcisim-valid.s
new file mode 100644
index 0000000000000..668f279643c74
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcisim-valid.s
@@ -0,0 +1,52 @@
+# Xqcisim - Simulation Hint Instructions
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisim -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisim < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcisim -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisim -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisim < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcisim --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+
+# CHECK-INST: qc.psyscalli 1023
+# CHECK-ENC: encoding: [0x13,0x20,0xf0,0x3f]
+qc.psyscalli 1023
+
+# CHECK-INST: qc.pputci    255
+# CHECK-ENC: encoding: [0x13,0x20,0xf0,0x4f]
+qc.pputci 255
+
+# CHECK-INST: qc.c.ptrace
+# CHECK-ENC: encoding: [0x02,0x00]
+qc.c.ptrace
+
+# CHECK-INST: qc.pcoredump
+# CHECK-ENC: encoding: [0x13,0x20,0x00,0x60]
+qc.pcoredump
+
+# CHECK-INST: qc.ppregs
+# CHECK-ENC: encoding: [0x13,0x20,0x00,0x70]
+qc.ppregs
+
+# CHECK-INST: qc.ppreg     a0
+# CHECK-ENC: encoding: [0x13,0x20,0x05,0x80]
+qc.ppreg x10
+
+# CHECK-INST: qc.pputc     t2
+# CHECK-ENC: encoding: [0x13,0xa0,0x03,0x90]
+qc.pputc x7
+
+# CHECK-INST: qc.pputs     a5
+# CHECK-ENC: encoding: [0x13,0xa0,0x07,0xa0]
+qc.pputs x15
+
+# CHECK-INST: qc.pexit      s10
+# CHECK-ENC: encoding: [0x13,0x20,0x0d,0xb0]
+qc.pexit x26
+
+# CHECK-INST: qc.psyscall  a1
+# CHECK-ENC: encoding: [0x13,0xa0,0x05,0xc0]
+qc.psyscall x11
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..2d9d6f4482a1b 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,7 +657,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
        {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p3",
         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
         "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2",
-        "rv64i_xqcilo0p2", "rv64i_xqcilia0p2"}) {
+        "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcisim0p2"}) {
     EXPECT_THAT(
         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
         ::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1129,6 +1129,7 @@ Experimental extensions
     xqcilia              0.2
     xqcilo               0.2
     xqcilsm              0.2
+    xqcisim              0.2
     xqcisls              0.2
     xrivosvizip          0.1
 

``````````

</details>


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


More information about the llvm-commits mailing list