Skip to content

[RISCV] Add Qualcomm uC Xqcics(Conditional Select) extension #119504

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

Merged
merged 2 commits into from
Dec 12, 2024

Conversation

hchandel
Copy link
Contributor

The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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

This patch adds assembler only support.

The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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

This patch adds assembler only support.

Change-Id: I0b893841e6e62e2cb3996ef87b456ccf49c44128
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' mc Machine (object) code labels Dec 11, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 11, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: quic_hchandel (hchandel)

Changes

The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119504.diff

11 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/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+91)
  • (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2)
  • (added) llvm/test/MC/RISCV/xqcics-invalid.s (+121)
  • (added) llvm/test/MC/RISCV/xqcics-valid.s (+147)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 9df903115b57c1..c268f75a0fd8df 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -189,6 +189,7 @@
 // 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:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select 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 3978332b1149a9..2867dcceb84fd7 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -429,6 +429,9 @@ The current vendor extensions supported are:
 ``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-Xqcics``
+  LLVM implements `version 0.2 of the Qualcomm uC Conditional Select 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 a5805e050bfdbe..ddee4ab8ce1b37 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -221,6 +221,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 4d563046923a58..b8ca32434aa43e 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -688,6 +688,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "Qualcomm uC Scaled Load Store custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
                         "Qualcomm uC Arithmetic custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
+                        "Qualcomm uC Conditional Select custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 52268c3fa62ccb..d1922eb0262792 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1367,6 +1367,14 @@ def HasVendorXqcia
       AssemblerPredicate<(all_of FeatureVendorXqcia),
                          "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
 
+def FeatureVendorXqcics
+    : RISCVExperimentalExtension<"xqcics", 0, 2,
+                                 "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+def HasVendorXqcics
+    : Predicate<"Subtarget->hasVendorXqcics()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcics),
+                         "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 29758014f73edf..eaeac1642d70e2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -57,6 +57,86 @@ 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">;
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTIICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                            simm5:$simm5, simm5:$simm), opcodestr,
+                            "$rd, $rs1, $simm5, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs1;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b00;
+  let Inst{24-20} = simm5;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                           GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                           "$rd, $rs1, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> rs1;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b01;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTCCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                           GPRNoX0:$rs2, GPRNoX0:$rs3), opcodestr,
+                           "$rd, $simm5, $rs2, $rs3", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> rs3;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = rs3;
+  let Inst{26-25} = 0b10;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                            GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                            "$rd, $simm5, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b11;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -108,3 +188,14 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
   def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
+
+let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
+  def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">;
+  def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">;
+  def QC_SELECTIEQ  : QCISELECTICC  <0b010, "qc.selectieq">;
+  def QC_SELECTINE  : QCISELECTICC  <0b011, "qc.selectine">;
+  def QC_SELECTEQI  : QCISELECTCCI  <0b010, "qc.selecteqi">;
+  def QC_SELECTNEI  : QCISELECTCCI  <0b011, "qc.selectnei">;
+  def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
+  def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
+} // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d54b81e0d39810..de3d5564210ff4 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"}, {"xqcicsr"}, {"xqcisls"}};
+      {"xqcia"}, {"xqcics"}, {"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 356dce29795658..cdccc712a46981 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -82,6 +82,7 @@
 ; 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-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-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
@@ -389,6 +390,7 @@
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
+; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcics-invalid.s b/llvm/test/MC/RISCV/xqcics-invalid.s
new file mode 100644
index 00000000000000..e7effdfd263b64
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-invalid.s
@@ -0,0 +1,121 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selecteqi 9, 15, x4, x3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selecteqi x9, 15, x4
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selecteqi x9, 16, x4, x3
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectieq 8, x4, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieq x8, x4, x3
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectieq x8, x4, x3, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieq x8, x4, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectieqi 9, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieqi x9, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieqi x9, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiieq 9, x3, 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiieq x9, x3, 11
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 16, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 11, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiieq x9, x3, 11, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiine 8, x3, 10, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiine x8, x3, 10
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 16, 11
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 12, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiine x8, x3, 10, 11
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectine 8, x3, x4, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectine x8, x3, x4
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectine x8, x3, x4, 16
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectine x8, x3, x4, 11
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectinei 8, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectinei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectinei x8, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectnei 8, 11, x3, x5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectnei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selectnei x8, 16, x3, x5
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectnei x8, 11, x3, x5
+
diff --git a/llvm/test/MC/RISCV/xqcics-valid.s b/llvm/test/MC/RISCV/xqcics-valid.s
new file mode 100644
index 00000000000000..eb888a62226931
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-valid.s
@@ -0,0 +1,147 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.selecteqi    s1, 5, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x42,0x1c]
+qc.selecteqi x9, 5, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, -16, tp, gp
+# CHECK-ENC: encoding: [0xdb,0x24,0x48,0x1c]
+qc.selecteqi x9, -16, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, 15, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x47,0x1c]
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x62]
+qc.selectieq x8, x4, x3, 12
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, -16
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x82]
+qc.selectieq x8, x4, x3, -16
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 15
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x7a]
+qc.selectieq x8, x4, x3, 15
+
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x66]
+qc.selectieqi x9, 11, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, -16, gp, 12
+# CHECK-ENC: encoding: [0xdb,0x24,0x38,0x66]
+qc.selectieqi x9, -16, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 15, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x37,0x66]
+qc.selectieqi x9, 15, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x86]
+qc.selectieqi x9, 11, x3, -16
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x7e]
+qc.selectieqi x9, 11, x3, 15
+
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x60]
+qc.selectiieq x9, x3, 11, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, -16, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x01,0x61]
+qc.selectiieq x9, x3, -16, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 15, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xf1,0x60]
+qc.selectiieq x9, x3, 15, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x80]
+qc.selectiieq x9, x3, 11, -16
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x78]
+qc.selectiieq x9, x3, 11, 15
+
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x58]
+qc.selectiine x8, x3, 10, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, -16, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x01,0x59]
+qc.selectiine x8, x3, -16, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 15, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xf1,0x58]
+qc.selectiine x8, x3, 15, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x80]
+qc.selectiine x8, x3, 10, -16
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x78]
+qc.selectiine x8, x3, 10, 15
+
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x5a]
+qc.selectine x8, x3, x4, 11
+
+# CHECK-INST: qc.selectine    s0, gp, tp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x82]
+qc.selectine x8, x3, x4, -16
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x7a]
+qc.selectine x8, x3, x4, 15
+
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x66]
+qc.selectinei x8, 11, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, -16, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x66]
+qc.selectinei x8, -16, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 15, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x66]
+qc.selectinei x8, 15, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x86]
+qc.selectinei x8, 11, x3, -16
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x7e]
+qc.selectinei x8, 11, x3, 15
+
+
+# CHECK-INST: qc.selectnei    s0, 11, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x2c]
+qc.selectnei x8, 11, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, -16, gp, t0
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x2c]
+qc.selectnei x8, -16, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, 15, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x2c]
+qc.selectnei x8, 15, x3, x5
+
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f9ff45f1166039..cf06ec5670346e 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Targ...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 11, 2024

@llvm/pr-subscribers-backend-risc-v

Author: quic_hchandel (hchandel)

Changes

The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119504.diff

11 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/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+91)
  • (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2)
  • (added) llvm/test/MC/RISCV/xqcics-invalid.s (+121)
  • (added) llvm/test/MC/RISCV/xqcics-valid.s (+147)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 9df903115b57c1..c268f75a0fd8df 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -189,6 +189,7 @@
 // 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:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select 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 3978332b1149a9..2867dcceb84fd7 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -429,6 +429,9 @@ The current vendor extensions supported are:
 ``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-Xqcics``
+  LLVM implements `version 0.2 of the Qualcomm uC Conditional Select 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 a5805e050bfdbe..ddee4ab8ce1b37 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -221,6 +221,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 4d563046923a58..b8ca32434aa43e 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -688,6 +688,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "Qualcomm uC Scaled Load Store custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
                         "Qualcomm uC Arithmetic custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
+                        "Qualcomm uC Conditional Select custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 52268c3fa62ccb..d1922eb0262792 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1367,6 +1367,14 @@ def HasVendorXqcia
       AssemblerPredicate<(all_of FeatureVendorXqcia),
                          "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
 
+def FeatureVendorXqcics
+    : RISCVExperimentalExtension<"xqcics", 0, 2,
+                                 "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+def HasVendorXqcics
+    : Predicate<"Subtarget->hasVendorXqcics()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcics),
+                         "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 29758014f73edf..eaeac1642d70e2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -57,6 +57,86 @@ 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">;
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTIICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                            simm5:$simm5, simm5:$simm), opcodestr,
+                            "$rd, $rs1, $simm5, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs1;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b00;
+  let Inst{24-20} = simm5;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                           GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                           "$rd, $rs1, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> rs1;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b01;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTCCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                           GPRNoX0:$rs2, GPRNoX0:$rs3), opcodestr,
+                           "$rd, $simm5, $rs2, $rs3", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> rs3;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = rs3;
+  let Inst{26-25} = 0b10;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                            GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                            "$rd, $simm5, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b11;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -108,3 +188,14 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
   def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
+
+let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
+  def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">;
+  def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">;
+  def QC_SELECTIEQ  : QCISELECTICC  <0b010, "qc.selectieq">;
+  def QC_SELECTINE  : QCISELECTICC  <0b011, "qc.selectine">;
+  def QC_SELECTEQI  : QCISELECTCCI  <0b010, "qc.selecteqi">;
+  def QC_SELECTNEI  : QCISELECTCCI  <0b011, "qc.selectnei">;
+  def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
+  def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
+} // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d54b81e0d39810..de3d5564210ff4 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"}, {"xqcicsr"}, {"xqcisls"}};
+      {"xqcia"}, {"xqcics"}, {"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 356dce29795658..cdccc712a46981 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -82,6 +82,7 @@
 ; 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-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-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
@@ -389,6 +390,7 @@
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
+; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcics-invalid.s b/llvm/test/MC/RISCV/xqcics-invalid.s
new file mode 100644
index 00000000000000..e7effdfd263b64
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-invalid.s
@@ -0,0 +1,121 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selecteqi 9, 15, x4, x3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selecteqi x9, 15, x4
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selecteqi x9, 16, x4, x3
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectieq 8, x4, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieq x8, x4, x3
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectieq x8, x4, x3, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieq x8, x4, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectieqi 9, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieqi x9, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieqi x9, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiieq 9, x3, 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiieq x9, x3, 11
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 16, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 11, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiieq x9, x3, 11, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiine 8, x3, 10, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiine x8, x3, 10
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 16, 11
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 12, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiine x8, x3, 10, 11
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectine 8, x3, x4, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectine x8, x3, x4
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectine x8, x3, x4, 16
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectine x8, x3, x4, 11
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectinei 8, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectinei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectinei x8, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectnei 8, 11, x3, x5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectnei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selectnei x8, 16, x3, x5
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectnei x8, 11, x3, x5
+
diff --git a/llvm/test/MC/RISCV/xqcics-valid.s b/llvm/test/MC/RISCV/xqcics-valid.s
new file mode 100644
index 00000000000000..eb888a62226931
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-valid.s
@@ -0,0 +1,147 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.selecteqi    s1, 5, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x42,0x1c]
+qc.selecteqi x9, 5, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, -16, tp, gp
+# CHECK-ENC: encoding: [0xdb,0x24,0x48,0x1c]
+qc.selecteqi x9, -16, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, 15, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x47,0x1c]
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x62]
+qc.selectieq x8, x4, x3, 12
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, -16
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x82]
+qc.selectieq x8, x4, x3, -16
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 15
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x7a]
+qc.selectieq x8, x4, x3, 15
+
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x66]
+qc.selectieqi x9, 11, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, -16, gp, 12
+# CHECK-ENC: encoding: [0xdb,0x24,0x38,0x66]
+qc.selectieqi x9, -16, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 15, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x37,0x66]
+qc.selectieqi x9, 15, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x86]
+qc.selectieqi x9, 11, x3, -16
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x7e]
+qc.selectieqi x9, 11, x3, 15
+
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x60]
+qc.selectiieq x9, x3, 11, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, -16, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x01,0x61]
+qc.selectiieq x9, x3, -16, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 15, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xf1,0x60]
+qc.selectiieq x9, x3, 15, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x80]
+qc.selectiieq x9, x3, 11, -16
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x78]
+qc.selectiieq x9, x3, 11, 15
+
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x58]
+qc.selectiine x8, x3, 10, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, -16, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x01,0x59]
+qc.selectiine x8, x3, -16, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 15, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xf1,0x58]
+qc.selectiine x8, x3, 15, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x80]
+qc.selectiine x8, x3, 10, -16
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x78]
+qc.selectiine x8, x3, 10, 15
+
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x5a]
+qc.selectine x8, x3, x4, 11
+
+# CHECK-INST: qc.selectine    s0, gp, tp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x82]
+qc.selectine x8, x3, x4, -16
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x7a]
+qc.selectine x8, x3, x4, 15
+
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x66]
+qc.selectinei x8, 11, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, -16, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x66]
+qc.selectinei x8, -16, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 15, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x66]
+qc.selectinei x8, 15, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x86]
+qc.selectinei x8, 11, x3, -16
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x7e]
+qc.selectinei x8, 11, x3, 15
+
+
+# CHECK-INST: qc.selectnei    s0, 11, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x2c]
+qc.selectnei x8, 11, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, -16, gp, t0
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x2c]
+qc.selectnei x8, -16, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, 15, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x2c]
+qc.selectnei x8, 15, x3, x5
+
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f9ff45f1166039..cf06ec5670346e 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Targ...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 11, 2024

@llvm/pr-subscribers-mc

Author: quic_hchandel (hchandel)

Changes

The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119504.diff

11 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/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+91)
  • (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2)
  • (added) llvm/test/MC/RISCV/xqcics-invalid.s (+121)
  • (added) llvm/test/MC/RISCV/xqcics-valid.s (+147)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 9df903115b57c1..c268f75a0fd8df 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -189,6 +189,7 @@
 // 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:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select 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 3978332b1149a9..2867dcceb84fd7 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -429,6 +429,9 @@ The current vendor extensions supported are:
 ``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-Xqcics``
+  LLVM implements `version 0.2 of the Qualcomm uC Conditional Select 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 a5805e050bfdbe..ddee4ab8ce1b37 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -221,6 +221,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 4d563046923a58..b8ca32434aa43e 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -688,6 +688,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "Qualcomm uC Scaled Load Store custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
                         "Qualcomm uC Arithmetic custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
+                        "Qualcomm uC Conditional Select custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 52268c3fa62ccb..d1922eb0262792 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1367,6 +1367,14 @@ def HasVendorXqcia
       AssemblerPredicate<(all_of FeatureVendorXqcia),
                          "'Xqcia' (Qualcomm uC Arithmetic Extension)">;
 
+def FeatureVendorXqcics
+    : RISCVExperimentalExtension<"xqcics", 0, 2,
+                                 "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+def HasVendorXqcics
+    : Predicate<"Subtarget->hasVendorXqcics()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcics),
+                         "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 29758014f73edf..eaeac1642d70e2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -57,6 +57,86 @@ 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">;
 
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTIICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                            simm5:$simm5, simm5:$simm), opcodestr,
+                            "$rd, $rs1, $simm5, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs1;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b00;
+  let Inst{24-20} = simm5;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICC<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, GPRNoX0:$rs1,
+                           GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                           "$rd, $rs1, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> rs1;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b01;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTCCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                           GPRNoX0:$rs2, GPRNoX0:$rs3), opcodestr,
+                           "$rd, $simm5, $rs2, $rs3", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> rs3;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = rs3;
+  let Inst{26-25} = 0b10;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class QCISELECTICCI<bits<3> func3, string opcodestr>
+    : RVInst<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm5:$simm5,
+                            GPRNoX0:$rs2, simm5:$simm), opcodestr,
+                            "$rd, $simm5, $rs2, $simm", [], InstFormatR4> {
+  let Constraints = "$rd = $rd_wb";
+  bits<5> simm;
+  bits<5> simm5;
+  bits<5> rs2;
+  bits<5> rd;
+
+  let Inst{31-27} = simm;
+  let Inst{26-25} = 0b11;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = simm5;
+  let Inst{14-12} = func3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b1011011;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -108,3 +188,14 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
   def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
+
+let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
+  def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">;
+  def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">;
+  def QC_SELECTIEQ  : QCISELECTICC  <0b010, "qc.selectieq">;
+  def QC_SELECTINE  : QCISELECTICC  <0b011, "qc.selectine">;
+  def QC_SELECTEQI  : QCISELECTCCI  <0b010, "qc.selecteqi">;
+  def QC_SELECTNEI  : QCISELECTCCI  <0b011, "qc.selectnei">;
+  def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
+  def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
+} // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d54b81e0d39810..de3d5564210ff4 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"}, {"xqcicsr"}, {"xqcisls"}};
+      {"xqcia"}, {"xqcics"}, {"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 356dce29795658..cdccc712a46981 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -82,6 +82,7 @@
 ; 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-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-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
@@ -389,6 +390,7 @@
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
+; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqcics-invalid.s b/llvm/test/MC/RISCV/xqcics-invalid.s
new file mode 100644
index 00000000000000..e7effdfd263b64
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-invalid.s
@@ -0,0 +1,121 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcics < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selecteqi 9, 15, x4, x3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selecteqi x9, 15, x4
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selecteqi x9, 16, x4, x3
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectieq 8, x4, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieq x8, x4, x3
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectieq x8, x4, x3, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieq x8, x4, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectieqi 9, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectieqi x9, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectieqi x9, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectieqi x9, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiieq 9, x3, 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiieq x9, x3, 11
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 16, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiieq x9, x3, 11, 17
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiieq x9, x3, 11, 12
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectiine 8, x3, 10, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectiine x8, x3, 10
+
+# CHECK-IMM: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 16, 11
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectiine x8, x3, 12, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectiine x8, x3, 10, 11
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectine 8, x3, x4, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectine x8, x3, x4
+
+# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [-16, 15]
+qc.selectine x8, x3, x4, 16
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectine x8, x3, x4, 11
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.selectinei 8, 11, x3, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectinei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 16, x3, 12
+
+# CHECK-IMM: :[[@LINE+1]]:27: error: immediate must be an integer in the range [-16, 15]
+qc.selectinei x8, 11, x3, 18
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectinei x8, 11, x3, 12
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.selectnei 8, 11, x3, x5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.selectnei x8, 11, x3
+
+# CHECK-IMM: :[[@LINE+1]]:18: error: immediate must be an integer in the range [-16, 15]
+qc.selectnei x8, 16, x3, x5
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcics' (Qualcomm uC Conditional Select Extension)
+qc.selectnei x8, 11, x3, x5
+
diff --git a/llvm/test/MC/RISCV/xqcics-valid.s b/llvm/test/MC/RISCV/xqcics-valid.s
new file mode 100644
index 00000000000000..eb888a62226931
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcics-valid.s
@@ -0,0 +1,147 @@
+# Xqcics - Qualcomm uC Conditional Select Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcics -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcics < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcics --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.selecteqi    s1, 5, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x42,0x1c]
+qc.selecteqi x9, 5, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, -16, tp, gp
+# CHECK-ENC: encoding: [0xdb,0x24,0x48,0x1c]
+qc.selecteqi x9, -16, x4, x3
+
+# CHECK-INST: qc.selecteqi    s1, 15, tp, gp
+# CHECK-ENC: encoding: [0xdb,0xa4,0x47,0x1c]
+qc.selecteqi x9, 15, x4, x3
+
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x62]
+qc.selectieq x8, x4, x3, 12
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, -16
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x82]
+qc.selectieq x8, x4, x3, -16
+
+# CHECK-INST: qc.selectieq    s0, tp, gp, 15
+# CHECK-ENC: encoding: [0x5b,0x24,0x32,0x7a]
+qc.selectieq x8, x4, x3, 15
+
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x66]
+qc.selectieqi x9, 11, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, -16, gp, 12
+# CHECK-ENC: encoding: [0xdb,0x24,0x38,0x66]
+qc.selectieqi x9, -16, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 15, gp, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x37,0x66]
+qc.selectieqi x9, 15, x3, 12
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x86]
+qc.selectieqi x9, 11, x3, -16
+
+# CHECK-INST: qc.selectieqi   s1, 11, gp, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0x35,0x7e]
+qc.selectieqi x9, 11, x3, 15
+
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x60]
+qc.selectiieq x9, x3, 11, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, -16, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0x01,0x61]
+qc.selectiieq x9, x3, -16, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 15, 12
+# CHECK-ENC: encoding: [0xdb,0xa4,0xf1,0x60]
+qc.selectiieq x9, x3, 15, 12
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, -16
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x80]
+qc.selectiieq x9, x3, 11, -16
+
+# CHECK-INST: qc.selectiieq   s1, gp, 11, 15
+# CHECK-ENC: encoding: [0xdb,0xa4,0xb1,0x78]
+qc.selectiieq x9, x3, 11, 15
+
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x58]
+qc.selectiine x8, x3, 10, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, -16, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x01,0x59]
+qc.selectiine x8, x3, -16, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 15, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0xf1,0x58]
+qc.selectiine x8, x3, 15, 11
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x80]
+qc.selectiine x8, x3, 10, -16
+
+# CHECK-INST: qc.selectiine   s0, gp, 10, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0xa1,0x78]
+qc.selectiine x8, x3, 10, 15
+
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 11
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x5a]
+qc.selectine x8, x3, x4, 11
+
+# CHECK-INST: qc.selectine    s0, gp, tp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x82]
+qc.selectine x8, x3, x4, -16
+
+# CHECK-INST: qc.selectine    s0, gp, tp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x41,0x7a]
+qc.selectine x8, x3, x4, 15
+
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x66]
+qc.selectinei x8, 11, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, -16, gp, 12
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x66]
+qc.selectinei x8, -16, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 15, gp, 12
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x66]
+qc.selectinei x8, 15, x3, 12
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, -16
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x86]
+qc.selectinei x8, 11, x3, -16
+
+# CHECK-INST: qc.selectinei   s0, 11, gp, 15
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x7e]
+qc.selectinei x8, 11, x3, 15
+
+
+# CHECK-INST: qc.selectnei    s0, 11, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x35,0x2c]
+qc.selectnei x8, 11, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, -16, gp, t0
+# CHECK-ENC: encoding: [0x5b,0x34,0x38,0x2c]
+qc.selectnei x8, -16, x3, x5
+
+# CHECK-INST: qc.selectnei    s0, 15, gp, t0
+# CHECK-ENC: encoding: [0x5b,0xb4,0x37,0x2c]
+qc.selectnei x8, 15, x3, x5
+
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f9ff45f1166039..cf06ec5670346e 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Targ...
[truncated]

@@ -57,6 +57,86 @@ 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">;

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class QCISELECTIICC<bits<3> func3, string opcodestr>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func3 -> funct3 to be consistent with the base ISA naming

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@svs-quic svs-quic requested review from lenary, apazos and pgodeq December 11, 2024 08:05
Change-Id: Id04daeaad4b131740651099f5f1e80b712dd5a7e
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@svs-quic svs-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@svs-quic svs-quic merged commit 0614c60 into llvm:main Dec 12, 2024
6 of 9 checks passed
@hchandel hchandel deleted the working branch December 12, 2024 05:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants