[clang] [llvm] [RISCV] Add Qualcomm uC Xqciio (External Input Output) extension (PR #132721)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 24 05:14:01 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
@llvm/pr-subscribers-clang-driver
Author: quic_hchandel (hchandel)
<details>
<summary>Changes</summary>
This extension adds two external input output instructions for a
non-memory-mapped device.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7.0
This patch adds assembler only support.
Co-authored-by: Sudharsan Veeravalli <quic_svs@<!-- -->quicinc.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/132721.diff
13 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/AsmParser/RISCVAsmParser.cpp (+14)
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+9-9)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1)
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+31)
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+3-3)
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2)
- (added) llvm/test/MC/RISCV/xqciio-invalid.s (+40)
- (added) llvm/test/MC/RISCV/xqciio-valid.s (+20)
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+4-3)
``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index b5533b54347b9..a4176e7a33ac9 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -206,6 +206,7 @@
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqciint 0.4 'Xqciint' (Qualcomm uC Interrupts Extension)
+// CHECK-NEXT: xqciio 0.1 'Xqciio' (Qualcomm uC External Input Output Extension)
// CHECK-NEXT: xqcilb 0.2 'Xqcilb' (Qualcomm uC Long Branch Extension)
// CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
// CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 8735b274a805f..cda7e5fec8488 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -461,6 +461,9 @@ The current vendor extensions supported are:
``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-Xqciio``
+ LLVM implements `version 0.1 of the Qualcomm uC External Input Output 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-Xqciint``
LLVM implements `version 0.4 of the Qualcomm uC Interrupts 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 1e39f761ecdad..a388a728a13a7 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -142,6 +142,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisync` (Sync Delay)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqciio` (External Input Output)
+ extension.
* Adds assembler support for the 'Zilsd` (Load/Store Pair Instructions)
extension.
* Adds assembler support for the 'Zclsd` (Compressed Load/Store Pair Instructions)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 05997cf78c6b1..07ed538fd01c1 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -987,6 +987,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return SignExtend64<32>(Imm);
}
+ bool isUImm14Lsb00() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isShiftedUInt<12, 2>(Imm) &&
+ VK == RISCVMCExpr::VK_None;
+ }
+
bool isSImm11() const {
if (!isImm())
return false;
@@ -1741,6 +1751,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
+ case Match_InvalidUImm14Lsb00:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, 0, (1 << 14) - 4,
+ "immediate must be a multiple of 4 bytes in the range");
case Match_InvalidUImm16NonZero:
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
case Match_InvalidSImm12:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 93cbf662bfa32..49dc46d0b0918 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -672,15 +672,15 @@ static constexpr FeatureBitset XRivosFeatureGroup = {
};
static constexpr FeatureBitset XqciFeatureGroup = {
- RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
- RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
- RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
- RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
- RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilb,
- RISCV::FeatureVendorXqcili, RISCV::FeatureVendorXqcilia,
- RISCV::FeatureVendorXqcilo, RISCV::FeatureVendorXqcilsm,
- RISCV::FeatureVendorXqcisim, RISCV::FeatureVendorXqcisls,
- RISCV::FeatureVendorXqcisync,
+ RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
+ RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
+ RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
+ RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
+ RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
+ RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
+ RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
+ RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
+ RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
};
static constexpr FeatureBitset XSfVectorGroup = {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index db305b0083415..b4c61779e8f50 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
+ OPERAND_UIMM14_LSB00,
OPERAND_UIMM16,
OPERAND_UIMM16_NONZERO,
OPERAND_UIMM20,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 85e3675beb80e..385d490b1fc14 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcicm
AssemblerPredicate<(all_of FeatureVendorXqcicm),
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
+def FeatureVendorXqciio
+ : RISCVExperimentalExtension<0, 1, "Qualcomm uC External Input Output Extension">;
+def HasVendorXqciio
+ : Predicate<"Subtarget->hasVendorXqciio()">,
+ AssemblerPredicate<(all_of FeatureVendorXqciio),
+ "'Xqciio' (Qualcomm uC External Input Output Extension)">;
+
def FeatureVendorXqciint
: RISCVExperimentalExtension<0, 4, "Qualcomm uC Interrupts Extension",
[FeatureStdExtZca]>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 69290c0da1824..22cfbd95f72ef 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -69,6 +69,15 @@ def uimm10 : RISCVUImmLeafOp<10>;
def uimm11 : RISCVUImmLeafOp<11>;
+// A 14-bit unsigned immediate where the least significant two bits are zero.
+def uimm14lsb00 : RISCVOp,
+ ImmLeaf<XLenVT, [{return isShiftedUInt<12, 2>(Imm);}]> {
+ let ParserMatchClass = UImmAsmOperand<14, "Lsb00">;
+ let EncoderMethod = "getImmOpValue";
+ let DecoderMethod = "decodeUImmOperand<14>";
+ let OperandType = "OPERAND_UIMM14_LSB00";
+}
+
def uimm16nonzero : RISCVOp<XLenVT>,
ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<16>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<16, "NonZero">;
@@ -741,6 +750,28 @@ def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
} // Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 1
+let Predicates = [HasVendorXqciio, IsRV32] in {
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
+ def QC_OUTW : RVInstI<0b100, OPC_CUSTOM_0, (outs),
+ (ins GPR:$rs3, GPR:$rs1, uimm14lsb00:$imm14),
+ "qc.outw", "$rs3, ${imm14}(${rs1})"> {
+ bits<5> rs3;
+ bits<14> imm14;
+
+ let rd = rs3;
+ let imm12 = imm14{13-2};
+ }
+
+ def QC_INW : RVInstI<0b101, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPR:$rs1, uimm14lsb00:$imm14),
+ "qc.inw", "$rd, ${imm14}(${rs1})"> {
+ bits<14> imm14;
+
+ let imm12 = imm14{13-2};
+ }
+} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqciio, IsRV32]
+
let Predicates = [HasVendorXqcilo, IsRV32] in {
def QC_E_LB : QCIRVInstEILoad<0b101, 0b00, "qc.e.lb">;
def QC_E_LBU : QCIRVInstEILoad<0b101, 0b01, "qc.e.lbu">;
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 0f7673c624c92..713da131e52dc 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -745,9 +745,9 @@ Error RISCVISAInfo::checkDependency() {
static constexpr StringLiteral XqciExts[] = {
{"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"},
- {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcilb"},
- {"xqcili"}, {"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisim"},
- {"xqcisls"}, {"xqcisync"}};
+ {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqciio"},
+ {"xqcilb"}, {"xqcili"}, {"xqcilia"}, {"xqcilo"}, {"xqcilsm"},
+ {"xqcisim"}, {"xqcisls"}, {"xqcisync"}};
static constexpr StringLiteral ZcdOverlaps[] = {
{"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index b1793233339de..bff3bbf53b01e 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -93,6 +93,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciio %s -o - | FileCheck --check-prefix=RV32XQCIIO %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilb %s -o - | FileCheck --check-prefix=RV32XQCILB %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck --check-prefix=RV32XQCILI %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
@@ -428,6 +429,7 @@
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
+; RV32XQCIIO: .attribute 5, "rv32i2p1_xqciio0p1"
; RV32XQCILB: .attribute 5, "rv32i2p1_zca1p0_xqcilb0p2"
; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2"
; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
diff --git a/llvm/test/MC/RISCV/xqciio-invalid.s b/llvm/test/MC/RISCV/xqciio-invalid.s
new file mode 100644
index 0000000000000..f37e58023c7e1
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciio-invalid.s
@@ -0,0 +1,40 @@
+# Xqciio - Qualcomm uC External Input Output Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciio < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciio < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:18: error: expected register
+qc.outw x5, 2048(10)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
+qc.outw x5, x10
+
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.outw x5, x10
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
+qc.outw x5, 4099(x10)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciio' (Qualcomm uC External Input Output Extension)
+qc.outw x5, 2048(x10)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.inw x23, 16380(17)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
+qc.inw x23, x17
+
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.inw x23, x17
+
+# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.inw x0, 16380(x17)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
+qc.inw x23, 16384(x17)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciio' (Qualcomm uC External Input Output Extension)
+qc.inw x23, 16380(x17)
diff --git a/llvm/test/MC/RISCV/xqciio-valid.s b/llvm/test/MC/RISCV/xqciio-valid.s
new file mode 100644
index 0000000000000..912db65966de9
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciio-valid.s
@@ -0,0 +1,20 @@
+# Xqciio - Qualcomm uC External Input Output Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciio -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciio --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+
+# CHECK-INST: qc.outw t0, 2048(a0)
+# CHECK-ENC: encoding: [0x8b,0x42,0x05,0x20]
+qc.outw x5, 2048(x10)
+
+# CHECK-INST: qc.inw s7, 16380(a7)
+# CHECK-ENC: encoding: [0x8b,0xdb,0xf8,0xff]
+qc.inw x23, 16380(x17)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cf510995afa07..c03e786af51c1 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -667,9 +667,9 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
{"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
"rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
- "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
- "rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2",
- "rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
+ "rv64i_xqciio0p1", "rv64i_xqcilo0p2", "rv64i_xqcilia0p2",
+ "rv64i_xqcibm0p4", "rv64i_xqcibi0p2", "rv64i_xqcili0p2",
+ "rv64i_xqcisim0p2", "rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1159,6 +1159,7 @@ Experimental extensions
xqcics 0.2
xqcicsr 0.2
xqciint 0.4
+ xqciio 0.1
xqcilb 0.2
xqcili 0.2
xqcilia 0.2
``````````
</details>
https://github.com/llvm/llvm-project/pull/132721
More information about the llvm-commits
mailing list