[clang] [llvm] [RISCV] Add Qualcomm uC Xqcibm (Bit Manipulation) extension (PR #129504)

via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 5 22:11:41 PST 2025


https://github.com/hchandel updated https://github.com/llvm/llvm-project/pull/129504

>From c93d0db7c67ca5bac425b2ecc1579afff93e747a Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Wed, 26 Feb 2025 16:52:54 +0530
Subject: [PATCH 1/8] [RISCV] Add Qualcomm uC Xqcibm (Bit Manipulation)
 extension This extension adds thirty eight  bit manipulation 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: Ie4cbec5d86ca015088cf8fecd634c0ce43903885
---
 .../Driver/print-supported-extensions-riscv.c |   1 +
 llvm/docs/RISCVUsage.rst                      |   3 +
 llvm/docs/ReleaseNotes.md                     |   2 +
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  24 +
 .../RISCV/Disassembler/RISCVDisassembler.cpp  |  10 +-
 .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |   1 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        |   8 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   | 116 ++++-
 llvm/lib/TargetParser/RISCVISAInfo.cpp        |   6 +-
 llvm/test/CodeGen/RISCV/attributes.ll         |   2 +
 llvm/test/MC/RISCV/xqcibm-invalid.s           | 474 ++++++++++++++++++
 llvm/test/MC/RISCV/xqcibm-valid.s             | 123 +++++
 .../TargetParser/RISCVISAInfoTest.cpp         |   2 +-
 13 files changed, 760 insertions(+), 12 deletions(-)
 create mode 100644 llvm/test/MC/RISCV/xqcibm-invalid.s
 create mode 100644 llvm/test/MC/RISCV/xqcibm-valid.s

diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index fcd820464e2d1..740e4a437524c 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -195,6 +195,7 @@
 // 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:     xqciac               0.3       'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
+// CHECK-NEXT:     xqcibm               0.4       'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 // CHECK-NEXT:     xqcicli              0.2       'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension)
 // CHECK-NEXT:     xqcicm               0.2       'Xqcicm' (Qualcomm uC Conditional Move Extension)
 // CHECK-NEXT:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select Extension)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 051eaf6999edb..20a1f0dafccc0 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -435,6 +435,9 @@ The current vendor extensions supported are:
 ``experimental-Xqciac``
   LLVM implements `version 0.3 of the Qualcomm uC Load-Store Address Calculation 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-Xqcibm``
+  LLVM implements `version 0.4 of the Qualcomm uC Bit Manipulation 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-Xqcicli``
   LLVM implements `version 0.2 of the Qualcomm uC Conditional Load Immediate 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 2a617901a1146..f8eafea7ab120 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -109,6 +109,8 @@ Changes to the RISC-V Backend
 
 * Adds experimental assembler support for the Qualcomm uC 'Xqcilia` (Large Immediate Arithmetic)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcibm` (Bit Manipulation)
+  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 650ad48e50de0..ac24db30be325 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -745,6 +745,26 @@ struct RISCVOperand final : public MCParsedAsmOperand {
            VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isUImm5Plus1() const {
+    if (!isImm())
+      return false;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    int64_t Imm;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && ((isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32)) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
+  bool isUImm5GE6Plus1() const {
+    if (!isImm())
+      return false;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    int64_t Imm;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && ((isUInt<5>(Imm) && (Imm >= 6)) || (Imm == 32)) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm8GE32() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1562,6 +1582,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
   case Match_InvalidUImm5GT3:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
+  case Match_InvalidUImm5Plus1:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
+  case Match_InvalidUImm5GE6Plus1:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
   case Match_InvalidUImm6:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
   case Match_InvalidUImm7:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 9b3104e86a8da..e827b8d47e80f 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -624,11 +624,11 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
 
 static constexpr FeatureBitset XqciFeatureGroup = {
     RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
-    RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
-    RISCV::FeatureVendorXqcics,  RISCV::FeatureVendorXqcicsr,
-    RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilia,
-    RISCV::FeatureVendorXqcilo,  RISCV::FeatureVendorXqcilsm,
-    RISCV::FeatureVendorXqcisls,
+    RISCV::FeatureVendorXqcibm,  RISCV::FeatureVendorXqcicli,
+    RISCV::FeatureVendorXqcicm,  RISCV::FeatureVendorXqcics,
+    RISCV::FeatureVendorXqcicsr, RISCV::FeatureVendorXqciint,
+    RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
+    RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisls,
 };
 
 static constexpr FeatureBitset XSfVectorGroup = {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 80ff18d914dca..3bf7a64404e27 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -296,6 +296,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM5,
   OPERAND_UIMM5_NONZERO,
   OPERAND_UIMM5_GT3,
+  OPERAND_UIMM5_GE6_PLUS1,
   OPERAND_UIMM5_LSB0,
   OPERAND_UIMM6,
   OPERAND_UIMM6_LSB0,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 1a93371a4d92f..a8ce955b60427 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1366,6 +1366,14 @@ def HasVendorXqcilia
       AssemblerPredicate<(all_of FeatureVendorXqcilia),
                          "'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)">;
 
+def FeatureVendorXqcibm
+    : RISCVExperimentalExtension<0, 4, "Qualcomm uC Bit Manipulation Extension",
+                                 [FeatureStdExtZca]>;
+def HasVendorXqcibm
+    : Predicate<"Subtarget->hasVendorXqcibm()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcibm),
+                         "'Xqcibm' (Qualcomm uC Bit Manipulation Extension)">;
+
 def FeatureVendorXqcilo
     : RISCVExperimentalExtension<0, 2, "Qualcomm uC Large Offset Load Store Extension",
                                  [FeatureStdExtZca]>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index b1283d0e3ae18..12e1f0ccfbeb6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -28,6 +28,28 @@ def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
   let OperandType = "OPERAND_UIMM5_GT3";
 }
 
+def UImm5Plus1AsmOperand : AsmOperandClass {
+  let Name = "UImm5Plus1";
+  let RenderMethod = "addImmOperands";
+  let DiagnosticType = "InvalidUImm5Plus1";
+}
+
+def uimm5_plus1 : RISCVOp, ImmLeaf<XLenVT,
+  [{return (isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32);}]> {
+  let ParserMatchClass = UImm5Plus1AsmOperand;
+  let EncoderMethod = "getImmOpValueMinus1";
+  let DecoderMethod = "decodeUImmPlus1Operand<5>";
+  let OperandType = "OPERAND_UIMM5_PLUS1";
+}
+
+def uimm5ge6_plus1 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
+  [{return (Imm >= 6) && (isUInt<5>(Imm) || (Imm == 32));}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "GE6Plus1">;
+  let EncoderMethod = "getImmOpValueMinus1";
+  let DecoderMethod = "decodeUImmPlus1Operand<5>";
+  let OperandType = "OPERAND_UIMM5_GE6_PLUS1";
+}
+
 def uimm10 : RISCVUImmLeafOp<10>;
 
 def uimm11 : RISCVUImmLeafOp<11>;
@@ -80,16 +102,40 @@ class QCIStore_ScaleIdx<bits<4> funct4, string opcodestr>
 }
 }
 
-class QCIRVInstR<bits<4> funct4, string opcodestr>
-    : RVInstR<{0b000, funct4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+class QCIRVInstI<bits<4> funct4, string opcodestr>
+    : RVInstI<0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
               (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
-  let rs2 = 0;
+  let imm12 = {0b000, funct4, 0b00000};
 }
 
 class QCIRVInstRR<bits<5> funct5, DAGOperand InTyRs1, string opcodestr>
     : RVInstR<{0b00, funct5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
               (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;
 
+class QCIBitManipRII<bits<3> funct3, bits<2> funct2,
+                     DAGOperand InTyRs1, string opcodestr>
+    : RVInstIBase<funct3, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                  (ins InTyRs1:$rs1, uimm5:$shamt, uimm5_plus1:$width),
+                  opcodestr, "$rd, $rs1, $width, $shamt"> {
+  bits<5> shamt;
+  bits<6> width;
+
+  let Inst{31-30} = funct2;
+  let Inst{29-25} = width{4-0};
+  let Inst{24-20} = shamt;
+}
+
+class QCIRVInstRI<bits<1> funct1, DAGOperand InTyImm11,
+                             string opcodestr>
+    : RVInstIBase<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                  (ins GPRNoX0:$rs1, InTyImm11:$imm11), opcodestr,
+                  "$rd, $rs1, $imm11"> {
+  bits<11> imm11;
+
+  let Inst{31-31} = funct1;
+  let Inst{30-20} = imm11;
+}
+
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
 class QCISELECTIICC<bits<3> funct3, string opcodestr>
     : RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd_wb),
@@ -185,6 +231,17 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
   let rs2 = imm;
 }
 
+class QCI_RVInst16CB_BM<bits<2> funct2, string opcodestr>
+    : RVInst16CB<0b100, 0b01, (outs GPRC:$rd),
+                 (ins GPRC:$rs1, uimmlog2xlennonzero:$shamt),
+                 opcodestr, "$rs1, $shamt"> {
+  bits<5> shamt;
+  let Constraints = "$rs1 = $rd";
+  let Inst{12} = 0b1;
+  let Inst{11-10} = funct2;
+  let Inst{6-2} = shamt{4-0};
+}
+
 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
 class QCIRVInst16CI_RS1<bits<5> funct5, string OpcodeStr>
     : RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {
@@ -333,6 +390,59 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcia, IsRV32]
 
+let Predicates = [HasVendorXqcibm, IsRV32] in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+  def QC_INSBRI : QCIRVInstRI<0b1, simm11, "qc.insbri">;
+  def QC_INSBI : RVInstIBase<0b001, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                             (ins simm5:$imm5, uimm5:$shamt,
+                             uimm5_plus1:$width), "qc.insbi",
+                             "$rd, $imm5, $width, $shamt"> {
+    bits<5> imm5;
+    bits<5> shamt;
+    bits<6> width;
+    let rs1 = imm5;
+    let Inst{31-30} = 0b00;
+    let Inst{29-25} = width{4-0};
+    let Inst{24-20} = shamt;
+  }
+  def QC_INSB : QCIBitManipRII<0b001, 0b01, GPR, "qc.insb">;
+  def QC_INSBH : QCIBitManipRII<0b001, 0b10, GPR, "qc.insbh">;
+  def QC_INSBR : QCIRVInstRR<0b00000, GPR, "qc.insbr">;
+  def QC_INSBHR : QCIRVInstRR<0b00001, GPR, "qc.insbhr">;
+  def QC_INSBPR : QCIRVInstRR<0b00010, GPR, "qc.insbpr">;
+  def QC_INSBPRH : QCIRVInstRR<0b00011, GPR, "qc.insbprh">;
+  def QC_EXTU : QCIBitManipRII<0b010, 0b00, GPRNoX0, "qc.extu">;
+  def QC_EXTDU : QCIBitManipRII<0b010, 0b10, GPR, "qc.extdu">;
+  def QC_EXTDUR : QCIRVInstRR<0b00100, GPR, "qc.extdur">;
+  def QC_EXTDUPR : QCIRVInstRR<0b00110, GPR, "qc.extdupr">;
+  def QC_EXTDUPRH : QCIRVInstRR<0b00111, GPR, "qc.extduprh">;
+  def QC_EXT : QCIBitManipRII<0b010, 0b01, GPRNoX0, "qc.ext">;
+  def QC_EXTD : QCIBitManipRII<0b010, 0b11, GPR, "qc.extd">;
+  def QC_EXTDR : QCIRVInstRR<0b00101, GPR, "qc.extdr">;
+  def QC_EXTDPR : QCIRVInstRR<0b01000, GPR, "qc.extdpr">;
+  def QC_EXTDPRH : QCIRVInstRR<0b01001, GPR, "qc.extdprh">;
+  def QC_COMPRESS2 : QCIRVInstI<0b0000, "qc.compress2">;
+  def QC_COMPRESS3 : QCIRVInstI<0b0001, "qc.compress3">;
+  def QC_EXPAND2 : QCIRVInstI<0b0010, "qc.expand2">;
+  def QC_EXPAND3 : QCIRVInstI<0b0011, "qc.expand3">;
+  def QC_CLO : QCIRVInstI<0b0100, "qc.clo">;
+  def QC_CTO : QCIRVInstI<0b0101, "qc.cto">;
+  def QC_BREV32 : QCIRVInstI<0b0110, "qc.brev32">;
+  def QC_C_BEXTI  : QCI_RVInst16CB_BM<0b00, "qc.c.bexti">;
+  def QC_C_BSETI  : QCI_RVInst16CB_BM<0b01, "qc.c.bseti">;
+  def QC_C_EXTU : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
+                             (ins GPRNoX0:$rd, uimm5ge6_plus1:$width),
+                             "qc.c.extu", "$rd, $width"> {
+    bits<5> rd;
+    bits<5> width;
+    let Constraints = "$rd = $rd_wb";
+    let Inst{6-2} = width{4-0};
+    let Inst{11-7} = rd;
+    let Inst{12} = 0b1;
+  }
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcibm, IsRV32]
+
 let Predicates = [HasVendorXqciac, IsRV32] in {
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
   def QC_C_MULIADD : RVInst16CL<0b001, 0b10, (outs GPRC:$rd_wb),
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 132c47ca631b6..fb0a8f94df81d 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,9 +742,9 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"},  {"xqciac"},  {"xqcicli"}, {"xqcicm"},
-      {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcilia"},
-      {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
+      {"xqcia"},   {"xqciac"}, {"xqcibm"},  {"xqcicli"},
+      {"xqcicm"},  {"xqcics"}, {"xqcicsr"}, {"xqciint"},
+      {"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"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 daab7b236879f..cbe83bb027a51 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -83,6 +83,7 @@
 ; 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-xqciac %s -o - | FileCheck --check-prefix=RV32XQCIAC %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibm %s -o - | FileCheck --check-prefix=RV32XQCIBM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli %s -o - | FileCheck --check-prefix=RV32XQCICLI %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
@@ -400,6 +401,7 @@
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
 ; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p3"
+; RV32XQCIBM: .attribute 5, "rv32i2p1_zca1p0_xqcibm0p4"
 ; RV32XQCICLI: .attribute 5, "rv32i2p1_xqcicli0p2"
 ; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
diff --git a/llvm/test/MC/RISCV/xqcibm-invalid.s b/llvm/test/MC/RISCV/xqcibm-invalid.s
new file mode 100644
index 0000000000000..0f5c1d1e6fd69
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcibm-invalid.s
@@ -0,0 +1,474 @@
+# Xqcibm - Qualcomm uC Bit Manipulation Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcibm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcibm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.compress2 x7, 5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.compress2 x7
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.compress2 x0,x5
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.compress2 x7, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.compress2 x7, x5
+
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.compress3 x10, 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.compress3 x10
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.compress3 x0, x22
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.compress3 x10, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.compress3 x10, x22
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.expand2 x23, 23
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.expand2 x23
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.expand2 x0, x23
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.expand2 x23, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.expand2 x23, x23
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.expand3 x2, 6
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.expand3 x2
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.expand3 x0, x6
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.expand3 x2, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.expand3 x2, x6
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.clo x23, 24
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.clo x23
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.clo x0, x24
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.clo x23, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.clo x23, x24
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.cto x12, 13
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.cto x12
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.cto x0, x13
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.cto x12, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.cto x12, x13
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.brev32 x20, 24
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.brev32 x20
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.brev32 x0, x24
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.brev32 x20, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.brev32 x20, x24
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.insbri x10, 20, -1024
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.insbri x0, x20, -1024
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.insbri x10, x0, -1024
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbri x10, x20
+
+# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [-1024, 1023]
+qc.insbri x10, x20, -1027
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbri x10, x20, -1024
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.insbi x0, -10, 12, 15
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbi x6, -10, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-16, 15]
+qc.insbi x6, -17, 12, 15
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [1, 32]
+qc.insbi x6, -10, 45, 15
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 31]
+qc.insbi x6, -10, 12, 65
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbi x6, -10, 12, 15
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.insb x10, 7, 6, 31
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insb x10, x7, 6
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.insb x0, x7, 6, 31
+
+# CHECK-PLUS: :[[@LINE+1]]:18: error: immediate must be an integer in the range [1, 32]
+qc.insb x10, x7, 46, 31
+
+# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 31]
+qc.insb x10, x7, 6, 61
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insb x10, x7, 6, 31
+
+
+# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
+qc.insbh x20, 12, 8, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbh x20, x12, 8
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.insbh x0, x12, 8, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [1, 32]
+qc.insbh x20, x12, 48, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 31]
+qc.insbh x20, x12, 8, 72
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbh x20, x12, 8, 12
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.extu x15, 12, 20, 20
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extu x15, x12, 20
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.extu x0, x12, 20, 20
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.extu x15, x0, 20, 20
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [1, 32]
+qc.extu x15, x12, 0, 20
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 31]
+qc.extu x15, x12, 20, 60
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extu x15, x12, 20, 20
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.ext x27, 6, 31, 1
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.ext x27, x6, 31
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.ext x0, x6, 31, 1
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.ext x27, x0, 31, 1
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [1, 32]
+qc.ext x27, x6, 0, 1
+
+# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 31]
+qc.ext x27, x6, 31, 41
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.ext x27, x6, 31, 1
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.extdu x1, 8, 8, 8
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdu x1, x8, 8
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.extdu x0, x8, 8, 8
+
+# CHECK-PLUS: :[[@LINE+1]]:18: error: immediate must be an integer in the range [1, 32]
+qc.extdu x1, x8, 48, 8
+
+# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 31]
+qc.extdu x1, x8, 8, 78
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdu x1, x8, 8, 8
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.extd x13, 21, 10, 15
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extd x13, x21, 10
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.extd x0, x21, 10, 15
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [1, 32]
+qc.extd x13, x21, 60, 15
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 31]
+qc.extd x13, x21, 10, 85
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extd x13, x21, 10, 15
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbr x10, x19, 5
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbr x10, x19
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.insbr x0, x19, x5
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbr x10, x19, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbr x10, x19, x5
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbhr x15, x4, 6
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbhr x15, x4
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.insbhr x0, x4, x6
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbhr x15, x4, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbhr x15, x4, x6
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbpr x21, x8, 9
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbpr x21, x8
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.insbpr x0, x8, x9
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbpr x21, x8, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbpr x21, x8, x9
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbprh x2, x3, 11
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.insbprh x2, x3
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.insbprh x0, x3, x11
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.insbprh x2, x3, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.insbprh x2, x3, x11
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.extdur x9, x19, 29
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdur x9, x19
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.extdur x0, x19, x29
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.extdur x9, x19, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdur x9, x19, x29
+
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.extdr x12, x31, 30
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdr x12, x31
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.extdr x0, x31, x30
+
+# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+qc.extdr x12, x31, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdr x12, x31, x30
+
+
+# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+qc.extdupr x13, x23, 3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdupr x13, x23
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.extdupr x0, x23, x3
+
+# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+qc.extdupr x13, x23, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdupr x13, x23, x3
+
+
+# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+qc.extduprh x18, x8, 9
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extduprh x18, x8
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.extduprh x0, x8, x9
+
+# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+qc.extduprh x18, x8, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extduprh x18, x8, x9
+
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.extdpr x1, x4, 15
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdpr x1, x4
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.extdpr x0, x4, x15
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.extdpr x1, x4, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdpr x1, x4, x15
+
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.extdprh x6, x24, 25
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.extdprh x6, x24
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.extdprh x0, x24, x25
+
+# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+qc.extdprh x6, x24, x0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.extdprh x6, x24, x25
+
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.c.bexti x1, 8
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.bexti x15
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [1, 31]
+qc.c.bexti x15, 43
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.c.bexti x9, 8
+
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.c.bseti x2, 10
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.bseti x12
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [1, 31]
+qc.c.bseti x12, -10
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.c.bseti x12, 30
+
+
+
+# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+qc.c.extu x0, 10
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.extu x5
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be an integer in the range [6, 32]
+qc.c.extu x17, 3
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
+qc.c.extu x17, 32
diff --git a/llvm/test/MC/RISCV/xqcibm-valid.s b/llvm/test/MC/RISCV/xqcibm-valid.s
new file mode 100644
index 0000000000000..d5603c6d52c90
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcibm-valid.s
@@ -0,0 +1,123 @@
+# Xqcibm - Qualcomm uC Bit Manipulation Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcibm -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcibm -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcibm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcibm --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.compress2   t2, t0
+# CHECK-ENC: encoding: [0x8b,0xb3,0x02,0x00]
+qc.compress2 x7, x5
+
+# CHECK-INST: qc.compress3   a0, s6
+# CHECK-ENC: encoding: [0x0b,0x35,0x0b,0x02]
+qc.compress3 x10, x22
+
+# CHECK-INST: qc.expand2 s7, s7
+# CHECK-ENC: encoding: [0x8b,0xbb,0x0b,0x04]
+qc.expand2 x23, x23
+
+# CHECK-INST: qc.expand3 sp, t1
+# CHECK-ENC: encoding: [0x0b,0x31,0x03,0x06]
+qc.expand3 x2, x6
+
+# CHECK-INST: qc.clo s7, s8
+# CHECK-ENC: encoding: [0x8b,0x3b,0x0c,0x08]
+qc.clo x23, x24
+
+# CHECK-INST: qc.cto a2, a3
+# CHECK-ENC: encoding: [0x0b,0xb6,0x06,0x0a]
+qc.cto x12, x13
+
+# CHECK-INST: qc.brev32  s4, s8
+# CHECK-ENC: encoding: [0x0b,0x3a,0x0c,0x0c]
+qc.brev32 x20, x24
+
+# CHECK-INST: qc.insbri  a0, s4, -1024
+# CHECK-ENC: encoding: [0x0b,0x05,0x0a,0xc0]
+qc.insbri x10, x20, -1024
+
+# CHECK-INST: qc.insbi   t1, -10, 32, 15
+# CHECK-ENC: encoding: [0x0b,0x13,0xfb,0x3e]
+qc.insbi x6, -10, 32, 15
+
+# CHECK-INST: qc.insb    a0, t2, 6, 31
+# CHECK-ENC: encoding: [0x0b,0x95,0xf3,0x4b]
+qc.insb x10, x7, 6, 31
+
+# CHECK-INST: qc.insbh   s4, a2, 8, 12
+# CHECK-ENC: encoding: [0x0b,0x1a,0xc6,0x8e]
+qc.insbh x20, x12, 8, 12
+
+# CHECK-INST: qc.extu    a5, a2, 20, 20
+# CHECK-ENC: encoding: [0x8b,0x27,0x46,0x27]
+qc.extu x15, x12, 20, 20
+
+# CHECK-INST: qc.ext    s11, t1, 31, 1
+# CHECK-ENC: encoding: [0x8b,0x2d,0x13,0x7c]
+qc.ext x27, x6, 31, 1
+
+# CHECK-INST: qc.extdu   ra, s0, 32, 8
+# CHECK-ENC: encoding: [0x8b,0x20,0x84,0xbe]
+qc.extdu x1, x8, 32, 8
+
+# CHECK-INST: qc.extd   a3, s5, 10, 15
+# CHECK-ENC: encoding: [0x8b,0xa6,0xfa,0xd2]
+qc.extd x13, x21, 10, 15
+
+# CHECK-INST: qc.insbr a0, s3, t0
+# CHECK-ENC: encoding: [0x0b,0xb5,0x59,0x00]
+qc.insbr x10, x19, x5
+
+# CHECK-INST: qc.insbhr    a5, tp, t1
+# CHECK-ENC: encoding: [0x8b,0x37,0x62,0x02]
+qc.insbhr x15, x4, x6
+
+# CHECK-INST: qc.insbpr    s5, s0, s1
+# CHECK-ENC: encoding: [0x8b,0x3a,0x94,0x04]
+qc.insbpr x21, x8, x9
+
+# CHECK-INST: qc.insbprh   sp, gp, a1
+# CHECK-ENC: encoding: [0x0b,0xb1,0xb1,0x06]
+qc.insbprh x2, x3, x11
+
+# CHECK-INST: qc.extdur    s1, s3, t4
+# CHECK-ENC: encoding: [0x8b,0xb4,0xd9,0x09]
+qc.extdur x9, x19, x29
+
+# CHECK-INST: qc.extdr    a2, t6, t5
+# CHECK-ENC: encoding: [0x0b,0xb6,0xef,0x0b]
+qc.extdr x12, x31, x30
+
+# CHECK-INST: qc.extdupr   a3, s7, gp
+# CHECK-ENC: encoding: [0x8b,0xb6,0x3b,0x0c]
+qc.extdupr x13, x23, x3
+
+# CHECK-INST: qc.extduprh  s2, s0, s1
+# CHECK-ENC: encoding: [0x0b,0x39,0x94,0x0e]
+qc.extduprh x18, x8, x9
+
+# CHECK-INST: qc.extdpr   ra, tp, a5
+# CHECK-ENC: encoding: [0x8b,0x30,0xf2,0x10]
+qc.extdpr x1, x4, x15
+
+# CHECK-INST: qc.extdprh  t1, s8, s9
+# CHECK-ENC: encoding: [0x0b,0x33,0x9c,0x13]
+qc.extdprh x6, x24, x25
+
+# CHECK-INST: qc.c.bexti  s1, 8
+# CHECK-ENC: encoding: [0xa1,0x90]
+qc.c.bexti x9, 8
+
+# CHECK-INST: qc.c.bseti a2, 16
+# CHECK-ENC: encoding: [0x41,0x96]
+qc.c.bseti x12, 16
+
+# CHECK-INST: qc.c.extu a5, 32
+# CHECK-ENC: encoding: [0xfe,0x17]
+qc.c.extu x15, 32
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index f734b4e25551b..c5b4d4b6a46ce 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,7 +657,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
        {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p3",
         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
         "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2",
-        "rv64i_xqcilo0p2", "rv64i_xqcilia0p2"}) {
+        "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4"}) {
     EXPECT_THAT(
         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
         ::testing::EndsWith(" is only supported for 'rv32'"));

>From 080c331ee82c0bd927bcf0f6fa5d4ac50595ddee Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Wed, 26 Feb 2025 17:13:05 +0530
Subject: [PATCH 2/8] Fix some things in Xqcibm

Change-Id: I93aecbd1b71e3fdccbbef93332a2aef39873b092
---
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td        | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 3bf7a64404e27..445716da22a7c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -296,6 +296,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM5,
   OPERAND_UIMM5_NONZERO,
   OPERAND_UIMM5_GT3,
+  OPERAND_UIMM5_PLUS1,
   OPERAND_UIMM5_GE6_PLUS1,
   OPERAND_UIMM5_LSB0,
   OPERAND_UIMM6,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 12e1f0ccfbeb6..11f56ea0c9187 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -108,6 +108,12 @@ class QCIRVInstI<bits<4> funct4, string opcodestr>
   let imm12 = {0b000, funct4, 0b00000};
 }
 
+class QCIRVInstR<bits<4> funct4, string opcodestr>
+    : RVInstR<{0b000, funct4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+              (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
+  let rs2 = 0;
+}
+
 class QCIRVInstRR<bits<5> funct5, DAGOperand InTyRs1, string opcodestr>
     : RVInstR<{0b00, funct5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
               (ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;

>From 4c7a2b3d93f505f552d295fb1a28fc742f9d2038 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Wed, 26 Feb 2025 17:28:29 +0530
Subject: [PATCH 3/8] Add support for SImm11

Change-Id: Ia85aee7e87e3a829e3f71c8937fab51c37a41414
---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 13 +++++++++++++
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |  1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td        |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index ac24db30be325..b3f11bcde5c00 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -957,6 +957,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return SignExtend64<32>(Imm);
   }
 
+  bool isSImm11() const {
+    if (!isImm())
+      return false;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    int64_t Imm;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isInt<11>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isSImm12() const {
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
     int64_t Imm;
@@ -1644,6 +1654,9 @@ 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_InvalidSImm11:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
+                                      (1 << 10) - 1);
   case Match_InvalidUImm10:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
   case Match_InvalidUImm11:
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 445716da22a7c..9c9cacbc9dd57 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -326,6 +326,7 @@ enum OperandType : unsigned {
   OPERAND_SIMM6,
   OPERAND_SIMM6_NONZERO,
   OPERAND_SIMM10_LSB0000_NONZERO,
+  OPERAND_SIMM11,
   OPERAND_SIMM12,
   OPERAND_SIMM12_LSB00000,
   OPERAND_SIMM26,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 11f56ea0c9187..44cb785d508a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -54,6 +54,8 @@ def uimm10 : RISCVUImmLeafOp<10>;
 
 def uimm11 : RISCVUImmLeafOp<11>;
 
+def simm11 : RISCVSImmLeafOp<11>;
+
 def simm26 : RISCVSImmLeafOp<26>;
 
 // 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no

>From c36792195ce879d126b63bf06eba0c97790b0975 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Fri, 28 Feb 2025 16:42:46 +0530
Subject: [PATCH 4/8] Update RISCVDisassembler.cpp and RISCVMCCodeEmitter.cpp

Change-Id: Iaedaa0e298abb2dc28082db36b3dc48d031ad8b1
---
 .../RISCV/Disassembler/RISCVDisassembler.cpp   |  9 +++++++++
 .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp  | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index e827b8d47e80f..22ef993e3ead4 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -371,6 +371,15 @@ decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
   return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
 }
 
+template <unsigned N>
+static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm,
+                                           int64_t Address,
+                                           const MCDisassembler *Decoder) {
+  assert(isUInt<N>(Imm) && "Invalid immediate");
+  Inst.addOperand(MCOperand::createImm(Imm + 1));
+  return MCDisassembler::Success;
+}
+
 template <unsigned N>
 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
                                       int64_t Address,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 06d9cce48692a..df8320107d894 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -80,6 +80,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  uint64_t getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
+                               SmallVectorImpl<MCFixup> &Fixups,
+                               const MCSubtargetInfo &STI) const;
+
   uint64_t getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
@@ -385,6 +389,20 @@ RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   return 0;
 }
 
+uint64_t
+RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
+                                        SmallVectorImpl<MCFixup> &Fixups,
+                                        const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+
+  if (MO.isImm()) {
+    uint64_t Res = MO.getImm();
+    return (Res - 1);
+  }
+
+  return getImmOpValue(MI, OpNo, Fixups, STI);
+}
+
 uint64_t
 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups,

>From 41fba70524b7e4c74ffada75bb7d33fa729a196b Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Mon, 3 Mar 2025 14:36:34 +0530
Subject: [PATCH 5/8] Update Tests

Change-Id: I91edbbc60d44450cc42440e33c2ee17a0d86c86b
---
 llvm/test/MC/RISCV/xqcibm-invalid.s           | 201 ++++++++++++------
 .../TargetParser/RISCVISAInfoTest.cpp         |   1 +
 2 files changed, 134 insertions(+), 68 deletions(-)

diff --git a/llvm/test/MC/RISCV/xqcibm-invalid.s b/llvm/test/MC/RISCV/xqcibm-invalid.s
index 0f5c1d1e6fd69..7bb305fa9fa30 100644
--- a/llvm/test/MC/RISCV/xqcibm-invalid.s
+++ b/llvm/test/MC/RISCV/xqcibm-invalid.s
@@ -4,125 +4,149 @@
 # RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcibm < %s 2>&1 \
 # RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
 
-# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:18: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:18: error: invalid operand for instruction
 qc.compress2 x7, 5
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.compress2 x7
 
-# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:14: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:14: error: invalid operand for instruction
 qc.compress2 x0,x5
 
-# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:18: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:18: error: invalid operand for instruction
 qc.compress2 x7, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.compress2 x7, x5
 
 
-# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:19: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:19: error: invalid operand for instruction
 qc.compress3 x10, 22
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.compress3 x10
 
-# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:14: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:14: error: invalid operand for instruction
 qc.compress3 x0, x22
 
-# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:19: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:19: error: invalid operand for instruction
 qc.compress3 x10, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.compress3 x10, x22
 
 
-# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:17: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:17: error: invalid operand for instruction
 qc.expand2 x23, 23
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.expand2 x23
 
-# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:12: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:12: error: invalid operand for instruction
 qc.expand2 x0, x23
 
-# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:17: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:17: error: invalid operand for instruction
 qc.expand2 x23, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.expand2 x23, x23
 
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.expand3 x2, 6
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.expand3 x2
 
-# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:12: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:12: error: invalid operand for instruction
 qc.expand3 x0, x6
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.expand3 x2, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.expand3 x2, x6
 
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.clo x23, 24
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.clo x23
 
-# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
 qc.clo x0, x24
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.clo x23, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.clo x23, x24
 
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.cto x12, 13
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.cto x12
 
-# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
 qc.cto x0, x13
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.cto x12, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.cto x12, x13
 
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.brev32 x20, 24
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.brev32 x20
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.brev32 x0, x24
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.brev32 x20, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.brev32 x20, x24
 
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.insbri x10, 20, -1024
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.insbri x0, x20, -1024
 
-# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:16: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:16: error: invalid operand for instruction
 qc.insbri x10, x0, -1024
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
@@ -135,7 +159,8 @@ qc.insbri x10, x20, -1027
 qc.insbri x10, x20, -1024
 
 
-# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:10: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:10: error: invalid operand for instruction
 qc.insbi x0, -10, 12, 15
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
@@ -160,7 +185,8 @@ qc.insb x10, 7, 6, 31
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.insb x10, x7, 6
 
-# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:9: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:9: error: invalid operand for instruction
 qc.insb x0, x7, 6, 31
 
 # CHECK-PLUS: :[[@LINE+1]]:18: error: immediate must be an integer in the range [1, 32]
@@ -179,7 +205,8 @@ qc.insbh x20, 12, 8, 12
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.insbh x20, x12, 8
 
-# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:10: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:10: error: invalid operand for instruction
 qc.insbh x0, x12, 8, 12
 
 # CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [1, 32]
@@ -192,16 +219,19 @@ qc.insbh x20, x12, 8, 72
 qc.insbh x20, x12, 8, 12
 
 
-# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:14: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:14: error: invalid operand for instruction
 qc.extu x15, 12, 20, 20
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extu x15, x12, 20
 
-# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:9: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:9: error: invalid operand for instruction
 qc.extu x0, x12, 20, 20
 
-# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:14: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:14: error: invalid operand for instruction
 qc.extu x15, x0, 20, 20
 
 # CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [1, 32]
@@ -214,16 +244,19 @@ qc.extu x15, x12, 20, 60
 qc.extu x15, x12, 20, 20
 
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.ext x27, 6, 31, 1
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.ext x27, x6, 31
 
-# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
 qc.ext x0, x6, 31, 1
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.ext x27, x0, 31, 1
 
 # CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [1, 32]
@@ -242,7 +275,8 @@ qc.extdu x1, 8, 8, 8
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdu x1, x8, 8
 
-# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:10: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:10: error: invalid operand for instruction
 qc.extdu x0, x8, 8, 8
 
 # CHECK-PLUS: :[[@LINE+1]]:18: error: immediate must be an integer in the range [1, 32]
@@ -261,7 +295,8 @@ qc.extd x13, 21, 10, 15
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extd x13, x21, 10
 
-# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:9: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:9: error: invalid operand for instruction
 qc.extd x0, x21, 10, 15
 
 # CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [1, 32]
@@ -274,160 +309,190 @@ qc.extd x13, x21, 10, 85
 qc.extd x13, x21, 10, 15
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbr x10, x19, 5
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
-qc.insbr x10, x19
+qc.insbr x10, x20
 
-# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:10: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:10: error: invalid operand for instruction
 qc.insbr x0, x19, x5
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbr x10, x19, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.insbr x10, x19, x5
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbhr x15, x4, 6
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.insbhr x15, x4
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.insbhr x0, x4, x6
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbhr x15, x4, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.insbhr x15, x4, x6
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbpr x21, x8, 9
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.insbpr x21, x8
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.insbpr x0, x8, x9
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbpr x21, x8, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.insbpr x21, x8, x9
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbprh x2, x3, 11
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.insbprh x2, x3
 
-# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:12: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:12: error: invalid operand for instruction
 qc.insbprh x0, x3, x11
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.insbprh x2, x3, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.insbprh x2, x3, x11
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.extdur x9, x19, 29
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdur x9, x19
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.extdur x0, x19, x29
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.extdur x9, x19, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.extdur x9, x19, x29
 
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.extdr x12, x31, 30
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdr x12, x31
 
-# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:10: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:10: error: invalid operand for instruction
 qc.extdr x0, x31, x30
 
-# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:20: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:20: error: invalid operand for instruction
 qc.extdr x12, x31, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.extdr x12, x31, x30
 
 
-# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:22: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:22: error: invalid operand for instruction
 qc.extdupr x13, x23, 3
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdupr x13, x23
 
-# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:12: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:12: error: invalid operand for instruction
 qc.extdupr x0, x23, x3
 
-# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:22: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:22: error: invalid operand for instruction
 qc.extdupr x13, x23, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.extdupr x13, x23, x3
 
 
-# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:22: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:22: error: invalid operand for instruction
 qc.extduprh x18, x8, 9
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extduprh x18, x8
 
-# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:13: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
 qc.extduprh x0, x8, x9
 
-# CHECK: :[[@LINE+1]]:22: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:22: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:22: error: invalid operand for instruction
 qc.extduprh x18, x8, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.extduprh x18, x8, x9
 
 
-# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:19: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:19: error: invalid operand for instruction
 qc.extdpr x1, x4, 15
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdpr x1, x4
 
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.extdpr x0, x4, x15
 
-# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:19: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:19: error: invalid operand for instruction
 qc.extdpr x1, x4, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
 qc.extdpr x1, x4, x15
 
 
-# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:21: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:21: error: invalid operand for instruction
 qc.extdprh x6, x24, 25
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
 qc.extdprh x6, x24
 
-# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:12: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:12: error: invalid operand for instruction
 qc.extdprh x0, x24, x25
 
-# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:21: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:21: error: invalid operand for instruction
 qc.extdprh x6, x24, x0
 
 # CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibm' (Qualcomm uC Bit Manipulation Extension)
@@ -460,8 +525,8 @@ qc.c.bseti x12, -10
 qc.c.bseti x12, 30
 
 
-
-# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-PLUS: :[[@LINE+2]]:11: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:11: error: invalid operand for instruction
 qc.c.extu x0, 10
 
 # CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index c5b4d4b6a46ce..e2753d730b3cd 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1121,6 +1121,7 @@ Experimental extensions
     svukte               0.3
     xqcia                0.2
     xqciac               0.3
+    xqcibm               0.4
     xqcicli              0.2
     xqcicm               0.2
     xqcics               0.2

>From d7011953859a36e938a0d24c3dcdf154fcbb08b1 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Tue, 4 Mar 2025 15:05:23 +0530
Subject: [PATCH 6/8] Update RISCVInstrInfoXqci.td and RISCVDisassembler.cpp

Change-Id: I4b8f1435ea575ab30ab3d7af5a7a37dd86b7766d
---
 .../RISCV/Disassembler/RISCVDisassembler.cpp      | 13 +++++++++++++
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td       | 15 +++++++--------
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b6e575816cf4f..c2ecaa9540511 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -341,6 +341,19 @@ static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm,
   return MCDisassembler::Success;
 }
 
+template <unsigned Width, unsigned LowerBound>
+static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm,
+                                        int64_t Address,
+                                        const MCDisassembler *Decoder) {
+  assert(isUInt<Width>(Imm) && "Invalid immediate");
+
+  if (Imm < LowerBound)
+    return MCDisassembler::Fail;
+
+  Inst.addOperand(MCOperand::createImm(Imm + 1));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,
                                               int64_t Address,
                                               const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 8b8f1d8b8f0f9..158491156d800 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -46,7 +46,7 @@ def uimm5ge6_plus1 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
   [{return (Imm >= 6) && (isUInt<5>(Imm) || (Imm == 32));}]> {
   let ParserMatchClass = UImmAsmOperand<5, "GE6Plus1">;
   let EncoderMethod = "getImmOpValueMinus1";
-  let DecoderMethod = "decodeUImmPlus1Operand<5>";
+  let DecoderMethod = "decodeUImmPlus1OperandGE<5,6>";
   let OperandType = "OPERAND_UIMM5_GE6_PLUS1";
 }
 
@@ -105,10 +105,9 @@ class QCIStore_ScaleIdx<bits<4> funct4, string opcodestr>
 }
 
 class QCIRVInstI<bits<4> funct4, string opcodestr>
-    : RVInstI<0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
-              (ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
-  let imm12 = {0b000, funct4, 0b00000};
-}
+    : RVInstIUnary<{0b000, funct4, 0b00000}, 0b011, OPC_CUSTOM_0,
+                   (outs GPRNoX0:$rd), (ins GPRNoX0:$rs1), opcodestr,
+                   "$rd, $rs1">;
 
 class QCIRVInstR<bits<4> funct4, string opcodestr>
     : RVInstR<{0b000, funct4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
@@ -123,7 +122,7 @@ class QCIRVInstRR<bits<5> funct5, DAGOperand InTyRs1, string opcodestr>
 class QCIBitManipRII<bits<3> funct3, bits<2> funct2,
                      DAGOperand InTyRs1, string opcodestr>
     : RVInstIBase<funct3, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
-                  (ins InTyRs1:$rs1, uimm5:$shamt, uimm5_plus1:$width),
+                  (ins InTyRs1:$rs1, uimm5_plus1:$width, uimm5:$shamt),
                   opcodestr, "$rd, $rs1, $width, $shamt"> {
   bits<5> shamt;
   bits<6> width;
@@ -402,8 +401,8 @@ let Predicates = [HasVendorXqcibm, IsRV32] in {
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
   def QC_INSBRI : QCIRVInstRI<0b1, simm11, "qc.insbri">;
   def QC_INSBI : RVInstIBase<0b001, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
-                             (ins simm5:$imm5, uimm5:$shamt,
-                             uimm5_plus1:$width), "qc.insbi",
+                             (ins simm5:$imm5, uimm5_plus1:$width,
+                             uimm5:$shamt), "qc.insbi",
                              "$rd, $imm5, $width, $shamt"> {
     bits<5> imm5;
     bits<5> shamt;

>From 3c4cfb703bac6f77dd9c16599814c7a371f5ca11 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Tue, 4 Mar 2025 15:25:41 +0530
Subject: [PATCH 7/8] Formatting changes

Change-Id: Ic02800302b258840b40bf409d6354c5430ca348d
---
 llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index c2ecaa9540511..b5f97ea759af1 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -343,8 +343,8 @@ static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm,
 
 template <unsigned Width, unsigned LowerBound>
 static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm,
-                                        int64_t Address,
-                                        const MCDisassembler *Decoder) {
+                                             int64_t Address,
+                                             const MCDisassembler *Decoder) {
   assert(isUInt<Width>(Imm) && "Invalid immediate");
 
   if (Imm < LowerBound)

>From 8c0cf4158bde7d623188a0a8fe8c4871aa206dd7 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Wed, 5 Mar 2025 14:51:42 +0530
Subject: [PATCH 8/8] Fix some suggested changes

Change-Id: Idd3deec94bd324b2ab2b3fbc57bec16426673ad2
---
 .../Target/RISCV/Disassembler/RISCVDisassembler.cpp    |  2 +-
 .../Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp   |  3 ++-
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td            | 10 +++++-----
 llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt       |  5 +++++
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b5f97ea759af1..6dfebc1989e92 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -347,7 +347,7 @@ static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm,
                                              const MCDisassembler *Decoder) {
   assert(isUInt<Width>(Imm) && "Invalid immediate");
 
-  if (Imm < LowerBound)
+  if ((Imm + 1) < LowerBound)
     return MCDisassembler::Fail;
 
   Inst.addOperand(MCOperand::createImm(Imm + 1));
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index df8320107d894..b8440319752f6 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -400,7 +400,8 @@ RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
     return (Res - 1);
   }
 
-  return getImmOpValue(MI, OpNo, Fixups, STI);
+  llvm_unreachable("Unhandled expression!");
+  return 0;
 }
 
 uint64_t
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 158491156d800..e47e4a993c13b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -125,10 +125,10 @@ class QCIBitManipRII<bits<3> funct3, bits<2> funct2,
                   (ins InTyRs1:$rs1, uimm5_plus1:$width, uimm5:$shamt),
                   opcodestr, "$rd, $rs1, $width, $shamt"> {
   bits<5> shamt;
-  bits<6> width;
+  bits<5> width;
 
   let Inst{31-30} = funct2;
-  let Inst{29-25} = width{4-0};
+  let Inst{29-25} = width;
   let Inst{24-20} = shamt;
 }
 
@@ -406,10 +406,10 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
                              "$rd, $imm5, $width, $shamt"> {
     bits<5> imm5;
     bits<5> shamt;
-    bits<6> width;
+    bits<5> width;
     let rs1 = imm5;
     let Inst{31-30} = 0b00;
-    let Inst{29-25} = width{4-0};
+    let Inst{29-25} = width;
     let Inst{24-20} = shamt;
   }
   def QC_INSB : QCIBitManipRII<0b001, 0b01, GPR, "qc.insb">;
@@ -443,7 +443,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
     bits<5> rd;
     bits<5> width;
     let Constraints = "$rd = $rd_wb";
-    let Inst{6-2} = width{4-0};
+    let Inst{6-2} = width;
     let Inst{11-7} = rd;
     let Inst{12} = 0b1;
   }
diff --git a/llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt b/llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
index da0c485a2ddd1..da1a630fd9c7e 100644
--- a/llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
+++ b/llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
@@ -1,4 +1,6 @@
 # RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+experimental-xqciac %s | FileCheck %s
+# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+experimental-xqcibm %s \
+# RUN: | FileCheck -check-prefixes=CHECK-XQCIBM  %s
 
 [0x00,0x00]
 # CHECK: unimp
@@ -8,3 +10,6 @@
 
 [0x00,0x00]
 # CHECK: unimp
+
+[0x92,0x17]
+# CHECK-XQCIBM-NOT: qc.c.extu a5, 4



More information about the cfe-commits mailing list