-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add Qualcomm uC Xqciio (External Input Output) extension #132721
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
Conversation
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/latest This patch adds assembler only support. Change-Id: Icef5879bce785c17039dc3958f7b52483ad9c65a
Change-Id: I7780eb744f8e7fc4a4c91032b5c01403f1576558
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-clang-driver Author: quic_hchandel (hchandel) ChangesThis extension adds two external input output instructions for a The current spec can be found at: This patch adds assembler only support. Co-authored-by: Sudharsan Veeravalli <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/132721.diff 13 Files Affected:
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
|
@llvm/pr-subscribers-clang Author: quic_hchandel (hchandel) ChangesThis extension adds two external input output instructions for a The current spec can be found at: This patch adds assembler only support. Co-authored-by: Sudharsan Veeravalli <[email protected]> Full diff: https://github.com/llvm/llvm-project/pull/132721.diff 13 Files Affected:
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
|
|
||
def QC_INW : RVInstI<0b101, OPC_CUSTOM_0, (outs GPRNoX0:$rd), | ||
(ins GPR:$rs1, uimm14lsb00:$imm14), | ||
"qc.inw", "$rd, ${imm14}(${rs1})"> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both this and qc.outw
need aliases where $imm14
is omitted from the assembly - in which case the immediate value should be 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I'm looking at using MIOperandInfo to create sub-operands and change how we do parsing so we can get rid of these kinds of InstAliases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be good. I did wonder if there was a nice way with optional operands, but I think that gets messy as the optionality is on the immediate and not on the combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lenary I added aliases for both of them.
Change-Id: I9d9e9aa1c18b995c10b835accb49ef6466fc72eb
✅ With the latest revision this PR passed the C/C++ code formatter. |
This extension adds two external input output instructions for 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 [email protected]