[clang] 6e7e46c - [RISCV] Add Qualcomm uC Xqcibm (Bit Manipulation) extension (#129504)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 5 22:31:56 PST 2025
Author: quic_hchandel
Date: 2025-03-06T12:01:53+05:30
New Revision: 6e7e46cafeccab761d31e6404ceb0cdef4c18bd4
URL: https://github.com/llvm/llvm-project/commit/6e7e46cafeccab761d31e6404ceb0cdef4c18bd4
DIFF: https://github.com/llvm/llvm-project/commit/6e7e46cafeccab761d31e6404ceb0cdef4c18bd4.diff
LOG: [RISCV] Add Qualcomm uC Xqcibm (Bit Manipulation) extension (#129504)
This extension adds thirty eight bit manipulation instructions.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.6
This patch adds assembler only support.
Co-authored-by: Sudharsan Veeravalli <quic_svs at quicinc.com>
Added:
llvm/test/MC/RISCV/xqcibm-invalid.s
llvm/test/MC/RISCV/xqcibm-valid.s
Modified:
clang/test/Driver/print-supported-extensions-riscv.c
llvm/docs/RISCVUsage.rst
llvm/docs/ReleaseNotes.md
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
llvm/lib/TargetParser/RISCVISAInfo.cpp
llvm/test/CodeGen/RISCV/attributes.ll
llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Removed:
################################################################################
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 4d6e112f4e387..69b76f0c4c4cd 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -196,6 +196,7 @@
// CHECK-NEXT: xqccmp 0.1 'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves)
// CHECK-NEXT: xqcia 0.4 '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 63185fe67440c..62c6a4fd80fd4 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -438,6 +438,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 e7eaa60b88c63..fe3b508d5c5b0 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.
* Adds experimental assembler and code generation support for the Qualcomm
'Xqccmp' extension, which is a frame-pointer convention compatible version of
Zcmp.
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 541979a0f70e8..44c19f5da1e26 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;
@@ -937,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;
@@ -1562,6 +1592,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:
@@ -1620,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/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 61deaa827a6df..6dfebc1989e92 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 + 1) < 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) {
@@ -371,6 +384,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,
@@ -629,11 +651,11 @@ static constexpr FeatureBitset XRivosFeatureGroup = {
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 886c23861841a..863bfc76d45c0 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -296,6 +296,8 @@ enum OperandType : unsigned {
OPERAND_UIMM5,
OPERAND_UIMM5_NONZERO,
OPERAND_UIMM5_GT3,
+ OPERAND_UIMM5_PLUS1,
+ OPERAND_UIMM5_GE6_PLUS1,
OPERAND_UIMM5_LSB0,
OPERAND_UIMM6,
OPERAND_UIMM6_LSB0,
@@ -324,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/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 06d9cce48692a..b8440319752f6 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,21 @@ 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);
+ }
+
+ llvm_unreachable("Unhandled expression!");
+ return 0;
+}
+
uint64_t
RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 6ebabe9dc4b2d..35db027509d94 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 1f4bd60e7d4c8..e47e4a993c13b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -28,10 +28,34 @@ 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 = "decodeUImmPlus1OperandGE<5,6>";
+ let OperandType = "OPERAND_UIMM5_GE6_PLUS1";
+}
+
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
@@ -80,6 +104,11 @@ class QCIStore_ScaleIdx<bits<4> funct4, string opcodestr>
}
}
+class QCIRVInstI<bits<4> funct4, string opcodestr>
+ : 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),
(ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
@@ -90,6 +119,30 @@ 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_plus1:$width, uimm5:$shamt),
+ opcodestr, "$rd, $rs1, $width, $shamt"> {
+ bits<5> shamt;
+ bits<5> width;
+
+ let Inst{31-30} = funct2;
+ let Inst{29-25} = width;
+ 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 +238,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 +397,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_plus1:$width,
+ uimm5:$shamt), "qc.insbi",
+ "$rd, $imm5, $width, $shamt"> {
+ bits<5> imm5;
+ bits<5> shamt;
+ bits<5> width;
+ let rs1 = imm5;
+ let Inst{31-30} = 0b00;
+ let Inst{29-25} = width;
+ 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;
+ 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 932db759cb7ac..dd74f79f04b92 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"}};
bool HasZcmp = Exts.count("zcmp") != 0;
bool HasXqccmp = Exts.count("xqccmp") != 0;
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 7023f2577152b..85e5a71fc7b62 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -84,6 +84,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqccmp %s -o - | FileCheck --check-prefix=RV32XQCCMP %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
@@ -405,6 +406,7 @@
; RV32XQCCMP: .attribute 5, "rv32i2p1_zca1p0_xqccmp0p1"
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p4"
; 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/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
diff --git a/llvm/test/MC/RISCV/xqcibm-invalid.s b/llvm/test/MC/RISCV/xqcibm-invalid.s
new file mode 100644
index 0000000000000..7bb305fa9fa30
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcibm-invalid.s
@@ -0,0 +1,539 @@
+# 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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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
+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-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
+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-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]
+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-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]
+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-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-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-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]
+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-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-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-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]
+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-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]
+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-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]
+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-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, x20
+
+# 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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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)
+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-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
+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 0ca8add7e85b4..00dc160c39a36 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,7 +657,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
{"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "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'"));
@@ -1127,6 +1127,7 @@ Experimental extensions
xqccmp 0.1
xqcia 0.4
xqciac 0.3
+ xqcibm 0.4
xqcicli 0.2
xqcicm 0.2
xqcics 0.2
More information about the cfe-commits
mailing list