[clang] [llvm] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (PR #118113)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 29 08:49:55 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Sudharsan Veeravalli (svs-quic)

<details>
<summary>Changes</summary>

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.

---

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:

- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) 
- (modified) llvm/docs/RISCVUsage.rst (+3) 
- (modified) llvm/docs/ReleaseNotes.md (+2) 
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+3) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+36) 
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+2-1) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) 
- (added) llvm/test/MC/RISCV/xqcia-invalid.s (+201) 
- (added) llvm/test/MC/RISCV/xqcia-valid.s (+55) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+6) 


``````````diff
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]

``````````

</details>


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


More information about the cfe-commits mailing list