[clang] [llvm] [RISCV] Add Qualcomm uC Xqcicsr (CSR) extension (PR #117169)

Sudharsan Veeravalli via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 27 21:42:25 PST 2024


https://github.com/svs-quic updated https://github.com/llvm/llvm-project/pull/117169

>From 92a3e2e9c44c03093e6050b92b938fd2a0d6886c Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Wed, 20 Nov 2024 13:24:07 +0530
Subject: [PATCH 1/2] [RISCV] Add Qualcomm uC Xqcicsr (CSR) extension

The Qualcomm uC Xqcicsr extension adds 2 instructions that can read
and write CSRs.

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

This patch adds assembler only support.
---
 .../Driver/print-supported-extensions-riscv.c |  1 +
 llvm/docs/RISCVUsage.rst                      |  3 ++
 llvm/docs/ReleaseNotes.md                     |  3 +-
 .../RISCV/Disassembler/RISCVDisassembler.cpp  |  2 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        | 10 +++++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |  1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   | 44 +++++++++++++++++++
 llvm/lib/TargetParser/RISCVISAInfo.cpp        |  4 ++
 llvm/test/CodeGen/RISCV/attributes.ll         |  2 +
 llvm/test/MC/RISCV/xqcicsr-invalid.s          | 27 ++++++++++++
 llvm/test/MC/RISCV/xqcicsr-valid.s            | 19 ++++++++
 .../TargetParser/RISCVISAInfoTest.cpp         |  1 +
 12 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
 create mode 100644 llvm/test/MC/RISCV/xqcicsr-invalid.s
 create mode 100644 llvm/test/MC/RISCV/xqcicsr-valid.s

diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 774dc3a4e1e756..a0b93621d2fcdc 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -187,6 +187,7 @@
 // CHECK-NEXT:     zvkgs                0.7       'Zvkgs' (Vector-Scalar GCM instructions for Cryptography)
 // CHECK-NEXT:     smctr                1.0       'Smctr' (Control Transfer Records Machine Level)
 // CHECK-NEXT:     ssctr                1.0       'Ssctr' (Control Transfer Records Supervisor Level)
+// CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR Extension)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
 // CHECK-NEXT:     rva20s64
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 1317221448ea5b..a656ccd00ed482 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -329,6 +329,9 @@ The primary goal of experimental support is to assist in the process of ratifica
 ``experimental-smctr``, ``experimental-ssctr``
   LLVM implements the `1.0-rc3 specification <https://github.com/riscv/riscv-control-transfer-records/releases/tag/v1.0_rc3>`__.
 
+``experimental-xqcicsr``
+  LLVM implements the `0.2 extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__.
+
 To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using.  To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`.  Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
 
 Vendor Extensions
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 1ba3672baeed88..89e7c048592f34 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -211,7 +211,8 @@ Changes to the RISC-V Backend
 * `f` and `cf` inline assembly constraints, when using F-/D-/H-in-X extensions,
   will use the relevant GPR rather than FPR. This makes inline assembly portable
   between e.g. F and Zfinx code.
-
+* Adds experimental assembler support for the Qualcomm uC 'Xqcicsr` (CSR)
+  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 cf8e337810d83b..e4f7ee323cf20b 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -682,6 +682,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "CORE-V SIMD extensions custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
                         "CORE-V Immediate Branching custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicsr, DecoderTableXqcicsr32,
+                        "Qualcomm uC CSR custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 3977816ebdd49c..ed87c9604f38b1 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1338,6 +1338,16 @@ def HasVendorXwchc
       AssemblerPredicate<(all_of FeatureVendorXwchc),
                          "'Xwchc' (WCH/QingKe additional compressed opcodes)">;
 
+// Qualcomm Extension(s)
+
+def FeatureVendorXqcicsr
+    : RISCVExperimentalExtension<"xqcicsr", 0, 2,
+                                 "'Xqcicsr' (Qualcomm uC CSR Extension)">;
+def HasVendorXqcicsr
+    : Predicate<"Subtarget->hasVendorXqcicsr()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcicsr),
+                         "'Xqcicsr' (Qualcomm uC CSR Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 5747f05ffafd47..cad9f5e3790be1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2064,6 +2064,7 @@ include "RISCVInstrInfoXSf.td"
 include "RISCVInstrInfoSFB.td"
 include "RISCVInstrInfoXCV.td"
 include "RISCVInstrInfoXwch.td"
+include "RISCVInstrInfoXqci.td"
 
 //===----------------------------------------------------------------------===//
 // Global ISel
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
new file mode 100644
index 00000000000000..562cd3182c0b42
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -0,0 +1,44 @@
+//===---------------- RISCVInstrInfoXQci.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 QUALCOMM.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Formats
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr" in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+  def QC_CSRRWR : RVInstR<0b1000110, 0b000, OPC_SYSTEM, (outs GPR:$rd),
+                          (ins GPR:$rs1, GPRNoX0:$rs2), "qc.csrrwr",
+                          "$rd, $rs1, $rs2">;
+
+  def QC_CSRRWRI : RVInstRBase<0b000, OPC_SYSTEM, (outs GPR:$rd),
+                               (ins uimm5:$imm5, GPRNoX0:$rs2),
+                               "qc.csrrwri", "$rd, $imm5, $rs2"> {
+    bits<5> imm5;
+
+    let Inst{31-25} = {0b1000111};
+    let Inst{19-15} = imm5;
+  }
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index c1bc441fc3f63d..63f75cc605f67d 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -771,6 +771,10 @@ Error RISCVISAInfo::checkDependency() {
       return getIncompatibleError("xwchc", "zcb");
   }
 
+  if (Exts.count("xqcicsr") != 0 && (XLen != 32)) {
+    return getError("'xqcicsr' is only supported in 'rv32'");
+  }
+
   return Error::success();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 1c8c459d1b316e..e4c3a6051f3884 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -80,6 +80,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV32XTHEADMEMPAIR %s
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck --check-prefix=RV32XWCHC %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %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
 ; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s
@@ -382,6 +383,7 @@
 ; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
+; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
 ; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0"
diff --git a/llvm/test/MC/RISCV/xqcicsr-invalid.s b/llvm/test/MC/RISCV/xqcicsr-invalid.s
new file mode 100644
index 00000000000000..26fa26f7ff95f1
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcicsr-invalid.s
@@ -0,0 +1,27 @@
+# Xqcicsr - Qualcomm uC CSR Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcicsr < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcicsr < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.csrrwr x10, x5, x0
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.csrrwr x10, x5
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicsr' (Qualcomm uC CSR Extension)
+qc.csrrwr x10, x5, x20
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.csrrwri x20, 31, x0
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [0, 31]
+qc.csrrwri x20, 45, x12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.csrrwri x20, 23
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicsr' (Qualcomm uC CSR Extension)
+qc.csrrwri x30, 31, x12
diff --git a/llvm/test/MC/RISCV/xqcicsr-valid.s b/llvm/test/MC/RISCV/xqcicsr-valid.s
new file mode 100644
index 00000000000000..f5cbf46e8bbded
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcicsr-valid.s
@@ -0,0 +1,19 @@
+# Xqcicsr - Qualcomm uC CSR Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcicsr -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcicsr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcicsr -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcicsr -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcicsr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcicsr --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.csrrwr  a0, t0, s4
+# CHECK-ENC: encoding: [0x73,0x85,0x42,0x8d]
+qc.csrrwr  x10, x5, x20
+
+# CHECK-INST: qc.csrrwri s4, 31, a2
+# CHECK-ENC: encoding: [0x73,0x8a,0xcf,0x8e]
+qc.csrrwri x20, 31, x12
\ No newline at end of file
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 08944659d78f46..a59976d2b303d7 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1084,6 +1084,7 @@ Experimental extensions
     zvkgs                0.7
     smctr                1.0
     ssctr                1.0
+    xqcicsr              0.2
 
 Supported Profiles
     rva20s64

>From 4e6ee07bce4cfc8463ac97ac6f28ba8145e30e02 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 21 Nov 2024 21:53:29 +0530
Subject: [PATCH 2/2] RISCVUsage change

---
 llvm/docs/RISCVUsage.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a656ccd00ed482..c7c211a8f347c4 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -329,9 +329,6 @@ The primary goal of experimental support is to assist in the process of ratifica
 ``experimental-smctr``, ``experimental-ssctr``
   LLVM implements the `1.0-rc3 specification <https://github.com/riscv/riscv-control-transfer-records/releases/tag/v1.0_rc3>`__.
 
-``experimental-xqcicsr``
-  LLVM implements the `0.2 extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__.
-
 To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using.  To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`.  Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
 
 Vendor Extensions
@@ -426,6 +423,9 @@ The current vendor extensions supported are:
 ``Xwchc``
   LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".
 
+``experimental-Xqcicsr``
+  LLVM implements `version 0.2 of the Qualcomm uC CSR 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 C Intrinsics
 =========================
 



More information about the cfe-commits mailing list