-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension #118113
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 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support.
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-backend-risc-v Author: Sudharsan Veeravalli (svs-quic) ChangesThis extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: This patch adds assembler only support. Patch is 20.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118113.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 70b7a96daf1daf..9df903115b57c1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -188,6 +188,7 @@
// CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level)
// CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level)
// CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
+// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 230bf66fcf461b..3978332b1149a9 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -426,6 +426,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-Xqcia``
+ LLVM implements `version 0.2 of the Qualcomm uC Arithmetic 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-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.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 6d50839d68953e..dc3f3aeb735f87 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -215,6 +215,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
+ extension.
Changes to the WebAssembly Backend
----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b843bb5ae43100..7c91dc07bbd3e5 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
bool isUImm32() const { return IsUImm<32>(); }
@@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm11:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 95658f24f79e1c..4d563046923a58 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC CSR custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
"Qualcomm uC Scaled Load Store custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
+ "Qualcomm uC Arithmetic custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ca2f868cd4e764..9e36d62352ae51 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -312,6 +312,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10_LSB00_NONZERO,
+ OPERAND_UIMM11,
OPERAND_UIMM12,
OPERAND_UIMM16,
OPERAND_UIMM32,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 95a37a76836729..52268c3fa62ccb 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1359,6 +1359,14 @@ def HasVendorXqcisls
AssemblerPredicate<(all_of FeatureVendorXqcisls),
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
+def FeatureVendorXqcia
+ : RISCVExperimentalExtension<"xqcia", 0, 2,
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+def HasVendorXqcia
+ : Predicate<"Subtarget->hasVendorXqcia()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcia),
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3f53165d5235e6..29758014f73edf 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,8 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def uimm11 : RISCVUImmLeafOp<11>;
+
//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
@@ -45,6 +47,16 @@ class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
}
}
+class QCIRVInstR<bits<4> func4, string opcodestr>
+ : RVInstR<{0b000, func4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
+ let rs2 = 0;
+}
+
+class QCIRVInstRR<bits<5> func5, DAGOperand InTyRs1, string opcodestr>
+ : RVInstR<{0b00, func5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -72,3 +84,27 @@ let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"
+
+let Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ def QC_SLASAT : QCIRVInstRR<0b01010, GPRNoX0, "qc.slasat">;
+ def QC_SLLSAT : QCIRVInstRR<0b01100, GPRNoX0, "qc.sllsat">;
+ def QC_ADDSAT : QCIRVInstRR<0b01110, GPRNoX0, "qc.addsat">;
+ def QC_ADDUSAT : QCIRVInstRR<0b01111, GPRNoX0, "qc.addusat">;
+ def QC_SUBSAT : QCIRVInstRR<0b10000, GPRNoX0, "qc.subsat">;
+ def QC_SUBUSAT : QCIRVInstRR<0b10001, GPRNoX0, "qc.subusat">;
+
+ def QC_WRAP : QCIRVInstRR<0b10010, GPR, "qc.wrap">;
+ def QC_WRAPI : RVInstI<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1, uimm11:$imm11), "qc.wrapi",
+ "$rd, $rs1, $imm11"> {
+ bits<11> imm11;
+
+ let imm12 = {0b0, imm11};
+ }
+
+ def QC_NORM : QCIRVInstR<0b0111, "qc.norm">;
+ def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">;
+ def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 5673866f9d9d9d..d54b81e0d39810 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -741,7 +741,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasVector = Exts.count("zve32x") != 0;
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
- static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};
+ static constexpr StringLiteral XqciExts[] = {
+ {"xqcia"}, {"xqcicsr"}, {"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 8a3d5e5cfe6216..356dce29795658 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -81,6 +81,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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %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
@@ -387,6 +388,7 @@
; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
+; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcia-invalid.s b/llvm/test/MC/RISCV/xqcia-invalid.s
new file mode 100644
index 00000000000000..a410fb63fad9c9
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-invalid.s
@@ -0,0 +1,201 @@
+# Xqcia - Qualcomm uC Arithmetic Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.slasat x10, x3
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.slasat x0, x3, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.slasat x10, x0, x17
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.slasat x10, x3, x17
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, 27
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.sllsat x23, x25
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.sllsat x0, x25, x27
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.sllsat x23, x0, x27
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.sllsat x23, x25, x27
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addsat x17, x14
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.addsat x0, x14, x7
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addsat x17, x0, x7
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addsat x17, x14, x7
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, 28
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addusat x8, x18
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.addusat x0, x18, x28
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addusat x8, x0, x28
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addusat x8, x18, x28
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subsat x22, x2
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.subsat x0, x2, x12
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subsat x22, x0, x12
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subsat x22, x2, x12
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subusat x9, x14
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.subusat x0, x14, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subusat x9, x0, x17
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subusat x9, x14, x17
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, 23
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrap x3, x30
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.wrap x0, x30, x23
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrap x3, x30, x23
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, 12, 2047
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, x12, 2047
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.wrapi x6, x0, 2047
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrapi x6, x12
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [0, 2047]
+qc.wrapi x6, x12, 2048
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrapi x6, x12, 2047
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.norm x3
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.norm x0, x7
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.norm x3, x7
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normu x11
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.normu x0, x17
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normu x11, x17
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, 31
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normeu x26
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.normeu x0, x31
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normeu x26, x31
diff --git a/llvm/test/MC/RISCV/xqcia-valid.s b/llvm/test/MC/RISCV/xqcia-valid.s
new file mode 100644
index 00000000000000..6bd10492d4d6ab
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-valid.s
@@ -0,0 +1,55 @@
+# Xqcia - Qualcomm uC Arithmetic Extesnsion
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.slasat a0, gp, a7
+# CHECK-ENC: encoding: [0x0b,0xb5,0x11,0x15]
+qc.slasat x10, x3, x17
+
+# CHECK-INST: qc.sllsat s7, s9, s11
+# CHECK-ENC: encoding: [0x8b,0xbb,0xbc,0x19]
+qc.sllsat x23, x25, x27
+
+# CHECK-INST: qc.addsat a7, a4, t2
+# CHECK-ENC: encoding: [0x8b,0x38,0x77,0x1c]
+qc.addsat x17, x14, x7
+
+# CHECK-INST: qc.addusat s0, s2, t3
+# CHECK-ENC: encoding: [0x0b,0x34,0xc9,0x1f]
+qc.addusat x8, x18, x28
+
+# CHECK-INST: qc.subsat s6, sp, a2
+# CHECK-ENC: encoding: [0x0b,0x3b,0xc1,0x20]
+qc.subsat x22, x2, x12
+
+# CHECK-INST: qc.subusat s1, a4, a7
+# CHECK-ENC: encoding: [0x8b,0x34,0x17,0x23]
+qc.subusat x9, x14, x17
+
+# CHECK-INST: qc.wrap gp, t5, s7
+# CHECK-ENC: encoding: [0x8b,0x31,0x7f,0x25]
+qc.wrap x3, x30, x23
+
+# CHECK-INST: qc.wrapi t1, a2, 2047
+# CHECK-ENC: encoding: [0x0b,0x03,0xf6,0x7f]
+qc.wrapi x6, x12, 2047
+
+# CHECK-INST: qc.norm gp, t2
+# CHECK-ENC: encoding: [0x8b,0xb1,0x03,0x0e]
+qc.norm x3, x7
+
+# CHECK-INST: qc.normu a1, a7
+# CHECK-ENC: encoding: [0x8b,0xb5,0x08,0x10]
+qc.normu x11, x17
+
+# CHECK-INST: qc.normeu s10, t6
+# CHECK-ENC: encoding: [0x0b,0xbd,0x0f,0x12]
+qc.normeu x26, x31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 23f1d832773ccf..f9ff45f1166039 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,6 +657,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"'xqcisls' is only supported for 'rv32'");
}
+
+ for (StringRef Input : {"rv64i_xqcia0p2"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "'xqcia' is only supported for 'rv32'");
+ }
}
TEST(ParseArchString, MissingDepency) {
@@ -1109,6 +1114,7 @@ Experimental extensions
smctr 1.0
ssctr 1.0
svukte 0.3
+ xqcia 0.2
xqcicsr ...
[truncated]
|
@llvm/pr-subscribers-mc Author: Sudharsan Veeravalli (svs-quic) ChangesThis extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: This patch adds assembler only support. Patch is 20.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118113.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 70b7a96daf1daf..9df903115b57c1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -188,6 +188,7 @@
// CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level)
// CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level)
// CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
+// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 230bf66fcf461b..3978332b1149a9 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -426,6 +426,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-Xqcia``
+ LLVM implements `version 0.2 of the Qualcomm uC Arithmetic 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-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.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 6d50839d68953e..dc3f3aeb735f87 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -215,6 +215,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
+ extension.
Changes to the WebAssembly Backend
----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b843bb5ae43100..7c91dc07bbd3e5 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
bool isUImm32() const { return IsUImm<32>(); }
@@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm11:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 95658f24f79e1c..4d563046923a58 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC CSR custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
"Qualcomm uC Scaled Load Store custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
+ "Qualcomm uC Arithmetic custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ca2f868cd4e764..9e36d62352ae51 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -312,6 +312,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10_LSB00_NONZERO,
+ OPERAND_UIMM11,
OPERAND_UIMM12,
OPERAND_UIMM16,
OPERAND_UIMM32,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 95a37a76836729..52268c3fa62ccb 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1359,6 +1359,14 @@ def HasVendorXqcisls
AssemblerPredicate<(all_of FeatureVendorXqcisls),
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
+def FeatureVendorXqcia
+ : RISCVExperimentalExtension<"xqcia", 0, 2,
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+def HasVendorXqcia
+ : Predicate<"Subtarget->hasVendorXqcia()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcia),
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3f53165d5235e6..29758014f73edf 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,8 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def uimm11 : RISCVUImmLeafOp<11>;
+
//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
@@ -45,6 +47,16 @@ class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
}
}
+class QCIRVInstR<bits<4> func4, string opcodestr>
+ : RVInstR<{0b000, func4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
+ let rs2 = 0;
+}
+
+class QCIRVInstRR<bits<5> func5, DAGOperand InTyRs1, string opcodestr>
+ : RVInstR<{0b00, func5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -72,3 +84,27 @@ let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"
+
+let Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ def QC_SLASAT : QCIRVInstRR<0b01010, GPRNoX0, "qc.slasat">;
+ def QC_SLLSAT : QCIRVInstRR<0b01100, GPRNoX0, "qc.sllsat">;
+ def QC_ADDSAT : QCIRVInstRR<0b01110, GPRNoX0, "qc.addsat">;
+ def QC_ADDUSAT : QCIRVInstRR<0b01111, GPRNoX0, "qc.addusat">;
+ def QC_SUBSAT : QCIRVInstRR<0b10000, GPRNoX0, "qc.subsat">;
+ def QC_SUBUSAT : QCIRVInstRR<0b10001, GPRNoX0, "qc.subusat">;
+
+ def QC_WRAP : QCIRVInstRR<0b10010, GPR, "qc.wrap">;
+ def QC_WRAPI : RVInstI<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1, uimm11:$imm11), "qc.wrapi",
+ "$rd, $rs1, $imm11"> {
+ bits<11> imm11;
+
+ let imm12 = {0b0, imm11};
+ }
+
+ def QC_NORM : QCIRVInstR<0b0111, "qc.norm">;
+ def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">;
+ def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 5673866f9d9d9d..d54b81e0d39810 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -741,7 +741,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasVector = Exts.count("zve32x") != 0;
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
- static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};
+ static constexpr StringLiteral XqciExts[] = {
+ {"xqcia"}, {"xqcicsr"}, {"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 8a3d5e5cfe6216..356dce29795658 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -81,6 +81,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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %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
@@ -387,6 +388,7 @@
; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
+; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcia-invalid.s b/llvm/test/MC/RISCV/xqcia-invalid.s
new file mode 100644
index 00000000000000..a410fb63fad9c9
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-invalid.s
@@ -0,0 +1,201 @@
+# Xqcia - Qualcomm uC Arithmetic Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.slasat x10, x3
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.slasat x0, x3, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.slasat x10, x0, x17
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.slasat x10, x3, x17
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, 27
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.sllsat x23, x25
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.sllsat x0, x25, x27
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.sllsat x23, x0, x27
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.sllsat x23, x25, x27
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addsat x17, x14
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.addsat x0, x14, x7
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addsat x17, x0, x7
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addsat x17, x14, x7
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, 28
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addusat x8, x18
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.addusat x0, x18, x28
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addusat x8, x0, x28
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addusat x8, x18, x28
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subsat x22, x2
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.subsat x0, x2, x12
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subsat x22, x0, x12
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subsat x22, x2, x12
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subusat x9, x14
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.subusat x0, x14, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subusat x9, x0, x17
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subusat x9, x14, x17
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, 23
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrap x3, x30
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.wrap x0, x30, x23
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrap x3, x30, x23
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, 12, 2047
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, x12, 2047
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.wrapi x6, x0, 2047
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrapi x6, x12
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [0, 2047]
+qc.wrapi x6, x12, 2048
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrapi x6, x12, 2047
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.norm x3
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.norm x0, x7
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.norm x3, x7
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normu x11
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.normu x0, x17
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normu x11, x17
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, 31
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normeu x26
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.normeu x0, x31
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normeu x26, x31
diff --git a/llvm/test/MC/RISCV/xqcia-valid.s b/llvm/test/MC/RISCV/xqcia-valid.s
new file mode 100644
index 00000000000000..6bd10492d4d6ab
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-valid.s
@@ -0,0 +1,55 @@
+# Xqcia - Qualcomm uC Arithmetic Extesnsion
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.slasat a0, gp, a7
+# CHECK-ENC: encoding: [0x0b,0xb5,0x11,0x15]
+qc.slasat x10, x3, x17
+
+# CHECK-INST: qc.sllsat s7, s9, s11
+# CHECK-ENC: encoding: [0x8b,0xbb,0xbc,0x19]
+qc.sllsat x23, x25, x27
+
+# CHECK-INST: qc.addsat a7, a4, t2
+# CHECK-ENC: encoding: [0x8b,0x38,0x77,0x1c]
+qc.addsat x17, x14, x7
+
+# CHECK-INST: qc.addusat s0, s2, t3
+# CHECK-ENC: encoding: [0x0b,0x34,0xc9,0x1f]
+qc.addusat x8, x18, x28
+
+# CHECK-INST: qc.subsat s6, sp, a2
+# CHECK-ENC: encoding: [0x0b,0x3b,0xc1,0x20]
+qc.subsat x22, x2, x12
+
+# CHECK-INST: qc.subusat s1, a4, a7
+# CHECK-ENC: encoding: [0x8b,0x34,0x17,0x23]
+qc.subusat x9, x14, x17
+
+# CHECK-INST: qc.wrap gp, t5, s7
+# CHECK-ENC: encoding: [0x8b,0x31,0x7f,0x25]
+qc.wrap x3, x30, x23
+
+# CHECK-INST: qc.wrapi t1, a2, 2047
+# CHECK-ENC: encoding: [0x0b,0x03,0xf6,0x7f]
+qc.wrapi x6, x12, 2047
+
+# CHECK-INST: qc.norm gp, t2
+# CHECK-ENC: encoding: [0x8b,0xb1,0x03,0x0e]
+qc.norm x3, x7
+
+# CHECK-INST: qc.normu a1, a7
+# CHECK-ENC: encoding: [0x8b,0xb5,0x08,0x10]
+qc.normu x11, x17
+
+# CHECK-INST: qc.normeu s10, t6
+# CHECK-ENC: encoding: [0x0b,0xbd,0x0f,0x12]
+qc.normeu x26, x31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 23f1d832773ccf..f9ff45f1166039 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,6 +657,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"'xqcisls' is only supported for 'rv32'");
}
+
+ for (StringRef Input : {"rv64i_xqcia0p2"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "'xqcia' is only supported for 'rv32'");
+ }
}
TEST(ParseArchString, MissingDepency) {
@@ -1109,6 +1114,7 @@ Experimental extensions
smctr 1.0
ssctr 1.0
svukte 0.3
+ xqcia 0.2
xqcicsr ...
[truncated]
|
@llvm/pr-subscribers-clang Author: Sudharsan Veeravalli (svs-quic) ChangesThis extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: This patch adds assembler only support. Patch is 20.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118113.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 70b7a96daf1daf..9df903115b57c1 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -188,6 +188,7 @@
// CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level)
// CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level)
// CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
+// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 230bf66fcf461b..3978332b1149a9 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -426,6 +426,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-Xqcia``
+ LLVM implements `version 0.2 of the Qualcomm uC Arithmetic 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-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.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 6d50839d68953e..dc3f3aeb735f87 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -215,6 +215,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
+ extension.
Changes to the WebAssembly Backend
----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b843bb5ae43100..7c91dc07bbd3e5 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
bool isUImm32() const { return IsUImm<32>(); }
@@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm11:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 95658f24f79e1c..4d563046923a58 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC CSR custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
"Qualcomm uC Scaled Load Store custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
+ "Qualcomm uC Arithmetic custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ca2f868cd4e764..9e36d62352ae51 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -312,6 +312,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10_LSB00_NONZERO,
+ OPERAND_UIMM11,
OPERAND_UIMM12,
OPERAND_UIMM16,
OPERAND_UIMM32,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 95a37a76836729..52268c3fa62ccb 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1359,6 +1359,14 @@ def HasVendorXqcisls
AssemblerPredicate<(all_of FeatureVendorXqcisls),
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
+def FeatureVendorXqcia
+ : RISCVExperimentalExtension<"xqcia", 0, 2,
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+def HasVendorXqcia
+ : Predicate<"Subtarget->hasVendorXqcia()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcia),
+ "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3f53165d5235e6..29758014f73edf 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,8 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def uimm11 : RISCVUImmLeafOp<11>;
+
//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
@@ -45,6 +47,16 @@ class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
}
}
+class QCIRVInstR<bits<4> func4, string opcodestr>
+ : RVInstR<{0b000, func4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
+ let rs2 = 0;
+}
+
+class QCIRVInstRR<bits<5> func5, DAGOperand InTyRs1, string opcodestr>
+ : RVInstR<{0b00, func5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -72,3 +84,27 @@ let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"
+
+let Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ def QC_SLASAT : QCIRVInstRR<0b01010, GPRNoX0, "qc.slasat">;
+ def QC_SLLSAT : QCIRVInstRR<0b01100, GPRNoX0, "qc.sllsat">;
+ def QC_ADDSAT : QCIRVInstRR<0b01110, GPRNoX0, "qc.addsat">;
+ def QC_ADDUSAT : QCIRVInstRR<0b01111, GPRNoX0, "qc.addusat">;
+ def QC_SUBSAT : QCIRVInstRR<0b10000, GPRNoX0, "qc.subsat">;
+ def QC_SUBUSAT : QCIRVInstRR<0b10001, GPRNoX0, "qc.subusat">;
+
+ def QC_WRAP : QCIRVInstRR<0b10010, GPR, "qc.wrap">;
+ def QC_WRAPI : RVInstI<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1, uimm11:$imm11), "qc.wrapi",
+ "$rd, $rs1, $imm11"> {
+ bits<11> imm11;
+
+ let imm12 = {0b0, imm11};
+ }
+
+ def QC_NORM : QCIRVInstR<0b0111, "qc.norm">;
+ def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">;
+ def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 5673866f9d9d9d..d54b81e0d39810 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -741,7 +741,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasVector = Exts.count("zve32x") != 0;
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
- static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};
+ static constexpr StringLiteral XqciExts[] = {
+ {"xqcia"}, {"xqcicsr"}, {"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 8a3d5e5cfe6216..356dce29795658 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -81,6 +81,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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %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
@@ -387,6 +388,7 @@
; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
+; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcia-invalid.s b/llvm/test/MC/RISCV/xqcia-invalid.s
new file mode 100644
index 00000000000000..a410fb63fad9c9
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-invalid.s
@@ -0,0 +1,201 @@
+# Xqcia - Qualcomm uC Arithmetic Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcia < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.slasat x10, x3
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.slasat x0, x3, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.slasat x10, x0, x17
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.slasat x10, x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.slasat x10, x3, x17
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, 27
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.sllsat x23, x25
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.sllsat x0, x25, x27
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.sllsat x23, x0, x27
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.sllsat x23, x25, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.sllsat x23, x25, x27
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addsat x17, x14
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.addsat x0, x14, x7
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addsat x17, x0, x7
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addsat x17, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addsat x17, x14, x7
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, 28
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.addusat x8, x18
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.addusat x0, x18, x28
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.addusat x8, x0, x28
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.addusat x8, x18, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.addusat x8, x18, x28
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subsat x22, x2
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.subsat x0, x2, x12
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subsat x22, x0, x12
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.subsat x22, x2, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subsat x22, x2, x12
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.subusat x9, x14
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.subusat x0, x14, x17
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.subusat x9, x0, x17
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.subusat x9, x14, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.subusat x9, x14, x17
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, 23
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrap x3, x30
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.wrap x0, x30, x23
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.wrap x3, x30, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrap x3, x30, x23
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, 12, 2047
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.wrapi x0, x12, 2047
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.wrapi x6, x0, 2047
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.wrapi x6, x12
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [0, 2047]
+qc.wrapi x6, x12, 2048
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.wrapi x6, x12, 2047
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.norm x3
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.norm x0, x7
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.norm x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.norm x3, x7
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, 17
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normu x11
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.normu x0, x17
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.normu x11, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normu x11, x17
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, 31
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.normeu x26
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.normeu x0, x31
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.normeu x26, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
+qc.normeu x26, x31
diff --git a/llvm/test/MC/RISCV/xqcia-valid.s b/llvm/test/MC/RISCV/xqcia-valid.s
new file mode 100644
index 00000000000000..6bd10492d4d6ab
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcia-valid.s
@@ -0,0 +1,55 @@
+# Xqcia - Qualcomm uC Arithmetic Extesnsion
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcia -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcia < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcia --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.slasat a0, gp, a7
+# CHECK-ENC: encoding: [0x0b,0xb5,0x11,0x15]
+qc.slasat x10, x3, x17
+
+# CHECK-INST: qc.sllsat s7, s9, s11
+# CHECK-ENC: encoding: [0x8b,0xbb,0xbc,0x19]
+qc.sllsat x23, x25, x27
+
+# CHECK-INST: qc.addsat a7, a4, t2
+# CHECK-ENC: encoding: [0x8b,0x38,0x77,0x1c]
+qc.addsat x17, x14, x7
+
+# CHECK-INST: qc.addusat s0, s2, t3
+# CHECK-ENC: encoding: [0x0b,0x34,0xc9,0x1f]
+qc.addusat x8, x18, x28
+
+# CHECK-INST: qc.subsat s6, sp, a2
+# CHECK-ENC: encoding: [0x0b,0x3b,0xc1,0x20]
+qc.subsat x22, x2, x12
+
+# CHECK-INST: qc.subusat s1, a4, a7
+# CHECK-ENC: encoding: [0x8b,0x34,0x17,0x23]
+qc.subusat x9, x14, x17
+
+# CHECK-INST: qc.wrap gp, t5, s7
+# CHECK-ENC: encoding: [0x8b,0x31,0x7f,0x25]
+qc.wrap x3, x30, x23
+
+# CHECK-INST: qc.wrapi t1, a2, 2047
+# CHECK-ENC: encoding: [0x0b,0x03,0xf6,0x7f]
+qc.wrapi x6, x12, 2047
+
+# CHECK-INST: qc.norm gp, t2
+# CHECK-ENC: encoding: [0x8b,0xb1,0x03,0x0e]
+qc.norm x3, x7
+
+# CHECK-INST: qc.normu a1, a7
+# CHECK-ENC: encoding: [0x8b,0xb5,0x08,0x10]
+qc.normu x11, x17
+
+# CHECK-INST: qc.normeu s10, t6
+# CHECK-ENC: encoding: [0x0b,0xbd,0x0f,0x12]
+qc.normeu x26, x31
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 23f1d832773ccf..f9ff45f1166039 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,6 +657,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"'xqcisls' is only supported for 'rv32'");
}
+
+ for (StringRef Input : {"rv64i_xqcia0p2"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "'xqcia' is only supported for 'rv32'");
+ }
}
TEST(ParseArchString, MissingDepency) {
@@ -1109,6 +1114,7 @@ Experimental extensions
smctr 1.0
ssctr 1.0
svukte 0.3
+ xqcia 0.2
xqcicsr ...
[truncated]
|
} | ||
|
||
def QC_NORM : QCIRVInstR<0b0111, "qc.norm">; | ||
def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">; |
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.
I have a question about the semantics of qc.normu in the spec
XReg clz = (xlen() - 1) - $signed(highest_set_bit(X[rs1]));
XReg exp = (X[rs1] << clz);
XReg mnt = (-clz);
X[rd] = {mnt[23:0], exp[7:0]};
Are the assignments of mnt
and exp
swapped? Unless I'm misunderstanding, I would expect exp
to be based only on clz
and mnt
to be baed on (X[rs1] << clz)
.
Also the assignment of X[rd] = {mnt[23:0], exp[7:0]};
seems like it should be taking the upper 24 bits of mnt
not the lower 24 bits? But maybe I've misunderstood?
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.
LGTM.
I note Craig has questions about the spec, we will ensure those are relayed to the spec authors, but they don't relate to encoding/assembling problems, so I'm not sure if they should block landing this.
I don't consider my questions blocking. I just didn't know where else to ask. |
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.
LGTM
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/146/builds/1731 Here is the relevant piece of the build log for the reference
|
This extension adds 11 instructions that perform integer arithmetic.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest
This patch adds assembler only support.