[clang] [llvm] [RISCV] Add Qualcomm uC Xqcibi (Branch Immediate) extension (PR #130779)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 11 07:19:40 PDT 2025
https://github.com/hchandel created https://github.com/llvm/llvm-project/pull/130779
This extension adds twelve conditional branch instructions that use an immediate operand for the source.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7.0
This patch adds assembler only support.
>From ed67e38e0e2d8dbdf67bd2e5123b49f3271e9e58 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <quic_hchandel at quicinc.com>
Date: Tue, 11 Mar 2025 13:01:34 +0530
Subject: [PATCH] [RISCV] Add Qualcomm uC Xqcibi (Branch Immediate) extension
This extension adds twelve conditional branch instructions that use an
immediate operand for the source.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7.0
This patch adds assembler only support.
Change-Id: I20307dd485ec0234bc08b0ad3940563b9779ea70
---
.../Driver/print-supported-extensions-riscv.c | 1 +
llvm/docs/RISCVUsage.rst | 3 +
llvm/docs/ReleaseNotes.md | 2 +
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 42 ++++
.../RISCV/Disassembler/RISCVDisassembler.cpp | 11 +-
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 3 +
llvm/lib/Target/RISCV/RISCVFeatures.td | 8 +
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 68 ++++++
llvm/lib/TargetParser/RISCVISAInfo.cpp | 6 +-
llvm/test/CodeGen/RISCV/attributes.ll | 2 +
llvm/test/MC/RISCV/xqcibi-invalid.s | 208 ++++++++++++++++++
llvm/test/MC/RISCV/xqcibi-valid.s | 71 ++++++
.../TargetParser/RISCVISAInfoTest.cpp | 4 +-
13 files changed, 420 insertions(+), 9 deletions(-)
create mode 100644 llvm/test/MC/RISCV/xqcibi-invalid.s
create mode 100644 llvm/test/MC/RISCV/xqcibi-valid.s
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 69b76f0c4c4cd..87140220fea9b 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: xqcibi 0.2 'Xqcibi' (Qualcomm uC Branch Immediate 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)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 62c6a4fd80fd4..ecf63eda38723 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-Xqcibi``
+ LLVM implements `version 0.2 of the Qualcomm uC Branch 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.
+
``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.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index d7a80ae93aa34..2f537b33577c4 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -111,6 +111,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcibm` (Bit Manipulation)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcibi` (Branch Immediate)
+ 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 b342c18bece08..eb8396224a128 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -825,6 +825,17 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}
+ bool isSImm5NonZero() const {
+ if (!isImm())
+ return false;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ int64_t Imm;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && Imm != 0 &&
+ isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isSImm6() const {
if (!isImm())
return false;
@@ -1012,6 +1023,27 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}
+ bool isSImm16NonZero() const {
+ if (!isImm())
+ return false;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ int64_t Imm;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && Imm != 0 &&
+ isInt<16>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
+ bool isUImm16NonZero() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isUInt<16>(Imm) && (Imm != 0) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isUImm20LUI() const {
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
int64_t Imm;
@@ -1607,6 +1639,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm5:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
(1 << 4) - 1);
+ case Match_InvalidSImm5NonZero:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
+ "immediate must be non-zero in the range");
case Match_InvalidSImm6:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
(1 << 5) - 1);
@@ -1661,6 +1697,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
+ case Match_InvalidUImm16NonZero:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 15) - 1);
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
@@ -1678,6 +1716,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
"immediate must be a multiple of 2 bytes in the range");
+ case Match_InvalidSImm16NonZero:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
+ "immediate must be non-zero in the range");
case Match_InvalidUImm20LUI:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
"operand must be a symbol with "
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index de742ac428de2..677d7764f6aa1 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -657,11 +657,12 @@ static constexpr FeatureBitset XRivosFeatureGroup = {
static constexpr FeatureBitset XqciFeatureGroup = {
RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
- RISCV::FeatureVendorXqcibm, RISCV::FeatureVendorXqcicli,
- RISCV::FeatureVendorXqcicm, RISCV::FeatureVendorXqcics,
- RISCV::FeatureVendorXqcicsr, RISCV::FeatureVendorXqciint,
- RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
- RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisls,
+ RISCV::FeatureVendorXqcibi, 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 863bfc76d45c0..962549c84d50d 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
OPERAND_UIMM11,
OPERAND_UIMM12,
OPERAND_UIMM16,
+ OPERAND_UIMM16_NONZERO,
OPERAND_UIMM20,
OPERAND_UIMMLOG2XLEN,
OPERAND_UIMMLOG2XLEN_NONZERO,
@@ -322,6 +323,7 @@ enum OperandType : unsigned {
OPERAND_UIMM64,
OPERAND_ZERO,
OPERAND_SIMM5,
+ OPERAND_SIMM5_NONZERO,
OPERAND_SIMM5_PLUS1,
OPERAND_SIMM6,
OPERAND_SIMM6_NONZERO,
@@ -329,6 +331,7 @@ enum OperandType : unsigned {
OPERAND_SIMM11,
OPERAND_SIMM12,
OPERAND_SIMM12_LSB00000,
+ OPERAND_SIMM16_NONZERO,
OPERAND_SIMM26,
OPERAND_SIMM32,
OPERAND_CLUI_IMM,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 35db027509d94..82b24ead6058e 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1374,6 +1374,14 @@ def HasVendorXqcibm
AssemblerPredicate<(all_of FeatureVendorXqcibm),
"'Xqcibm' (Qualcomm uC Bit Manipulation Extension)">;
+def FeatureVendorXqcibi
+ : RISCVExperimentalExtension<0, 2, "Qualcomm uC Branch Immediate Extension",
+ [FeatureStdExtZca]>;
+def HasVendorXqcibi
+ : Predicate<"Subtarget->hasVendorXqcibi()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcibi),
+ "'Xqcibi' (Qualcomm uC Branch Immediate 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 8e84a01821f56..3fa8f52ec40b1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -54,8 +54,29 @@ def uimm10 : RISCVUImmLeafOp<10>;
def uimm11 : RISCVUImmLeafOp<11>;
+def uimm16nonzero : RISCVOp<XLenVT>,
+ ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<16>(Imm);}]> {
+ let ParserMatchClass = UImmAsmOperand<16, "NonZero">;
+ let DecoderMethod = "decodeUImmNonZeroOperand<16>";
+ let OperandType = "OPERAND_UIMM16_NONZERO";
+}
+
+def simm5nonzero : RISCVOp<XLenVT>,
+ ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<5>(Imm);}]> {
+ let ParserMatchClass = SImmAsmOperand<5, "NonZero">;
+ let DecoderMethod = "decodeSImmNonZeroOperand<5>";
+ let OperandType = "OPERAND_SIMM5_NONZERO";
+}
+
def simm11 : RISCVSImmLeafOp<11>;
+def simm16nonzero : RISCVOp<XLenVT>,
+ ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<16>(Imm);}]> {
+ let ParserMatchClass = SImmAsmOperand<16, "NonZero">;
+ let DecoderMethod = "decodeSImmNonZeroOperand<16>";
+ let OperandType = "OPERAND_SIMM16_NONZERO";
+}
+
def simm26 : RISCVSImmLeafOp<26>;
// 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no
@@ -259,6 +280,34 @@ class QCIRVInst16CI_RS1<bits<5> funct5, string OpcodeStr>
let Inst{6-2} = funct5{4-0};
}
+class QCIBranchInst_rii<bits<3> funct3, DAGOperand InTyImm5, string opcodestr>
+ : RVInstB<funct3, OPC_CUSTOM_3, (outs),
+ (ins GPRNoX0:$rs1, InTyImm5:$rs2, simm13_lsb0:$imm12),
+ opcodestr, "$rs1, $rs2, $imm12"> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+class QCIBranchInst48_rii<bits<5> funct5, DAGOperand InTyImm16, string opcodestr>
+ : RVInst48<(outs), (ins GPRNoX0:$rs1, InTyImm16:$imm16, simm13_lsb0:$imm12),
+ opcodestr, "$rs1, $imm16, $imm12", [], InstFormatOther> {
+ bits<5> rs1;
+ bits<16> imm16;
+ bits<12> imm12;
+
+ let Inst{47-32} = imm16;
+ let Inst{31} = imm12{11};
+ let Inst{30-25} = imm12{9-4};
+ let Inst{24-20} = funct5;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = 0b100;
+ let Inst{11-8} = imm12{3-0};
+ let Inst{7} = imm12{10};
+ let Inst{6-0} = 0b0011111;
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
let hasSideEffects = 1 in
class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>
: RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {
@@ -397,6 +446,25 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
} // Predicates = [HasVendorXqcia, IsRV32]
+let Predicates = [HasVendorXqcibi, IsRV32] in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ def QC_BEQI : QCIBranchInst_rii<0b000, simm5nonzero, "qc.beqi">;
+ def QC_BNEI : QCIBranchInst_rii<0b001, simm5nonzero, "qc.bnei">;
+ def QC_BLTI : QCIBranchInst_rii<0b100, simm5nonzero, "qc.blti">;
+ def QC_BGEI : QCIBranchInst_rii<0b101, simm5nonzero, "qc.bgei">;
+ def QC_BLTUI : QCIBranchInst_rii<0b110, uimm5nonzero, "qc.bltui">;
+ def QC_BGEUI : QCIBranchInst_rii<0b111, uimm5nonzero, "qc.bgeui">;
+
+ def QC_E_BEQI : QCIBranchInst48_rii<0b11000, simm16nonzero, "qc.e.beqi">;
+ def QC_E_BNEI : QCIBranchInst48_rii<0b11001, simm16nonzero, "qc.e.bnei">;
+ def QC_E_BLTI : QCIBranchInst48_rii<0b11100, simm16nonzero, "qc.e.blti">;
+ def QC_E_BGEI : QCIBranchInst48_rii<0b11101, simm16nonzero, "qc.e.bgei">;
+ def QC_E_BLTUI : QCIBranchInst48_rii<0b11110, uimm16nonzero, "qc.e.bltui">;
+ def QC_E_BGEUI : QCIBranchInst48_rii<0b11111, uimm16nonzero, "qc.e.bgeui">;
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+
+} // Predicates = [HasVendorXqcibi, IsRV32]
+
let Predicates = [HasVendorXqcibm, IsRV32] in {
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
def QC_INSBRI : QCIRVInstRI<0b1, simm11, "qc.insbri">;
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index dd74f79f04b92..251e4789a6bf1 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"}, {"xqcibm"}, {"xqcicli"},
- {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"},
- {"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
+ {"xqcia"}, {"xqciac"}, {"xqcibi"}, {"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 85e5a71fc7b62..ff5ec438f4df8 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-xqcibi %s -o - | FileCheck --check-prefix=RV32XQCIBI %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
@@ -406,6 +407,7 @@
; RV32XQCCMP: .attribute 5, "rv32i2p1_zca1p0_xqccmp0p1"
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p4"
; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p3"
+; RV32XQCIBI: .attribute 5, "rv32i2p1_zca1p0_xqcibi0p2"
; RV32XQCIBM: .attribute 5, "rv32i2p1_zca1p0_xqcibm0p4"
; RV32XQCICLI: .attribute 5, "rv32i2p1_xqcicli0p2"
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
diff --git a/llvm/test/MC/RISCV/xqcibi-invalid.s b/llvm/test/MC/RISCV/xqcibi-invalid.s
new file mode 100644
index 0000000000000..11b3b8f513632
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcibi-invalid.s
@@ -0,0 +1,208 @@
+# Xqcibi - Qualcomm uC Branch Immediate Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcibi < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcibi < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# 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.beqi x0, 12, 346
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.beqi x8, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be non-zero in the range [-16, 15]
+qc.beqi x8, 22, 346
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.beqi x8, 12, 1211
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.beqi x8, 12, 346
+
+
+# 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.bnei x0, 15, 4094
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.bnei x4, 15
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be non-zero in the range [-16, 15]
+qc.bnei x4, -45, 4094
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.bnei x4, 15, 5000
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.bnei x4, 15, 4094
+
+
+# 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.bgei x0, 1, -4096
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.bgei x10, 1
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be non-zero in the range [-16, 15]
+qc.bgei x10, 21, -4096
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.bgei x10, 1, -4098
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.bgei x10, 1, -4096
+
+
+# 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.blti x0, 6, 2000
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.blti x1, 6
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be non-zero in the range [-16, 15]
+qc.blti x1, 56, 2000
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.blti x1, 6, 12000
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.blti x1, 6, 2000
+
+
+# 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.bgeui x0, 11, 128
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.bgeui x12, 11
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the range [1, 31]
+qc.bgeui x12, 41, 128
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.bgeui x12, 11, 11128
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.bgeui x12, 11, 128
+
+
+# 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.bltui x0, 7, 666
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.bltui x2, 7
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.bltui x2, -7, 666
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.bltui x2, 7, -6666
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.bltui x2, 7, 666
+
+
+# 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.e.beqi x0, 1, 2
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.beqi x1, 1
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be non-zero in the range [-32768, 32767]
+qc.e.beqi x1, 32768, 2
+
+# CHECK-PLUS: :[[@LINE+1]]:18: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.beqi x1, 1, 21
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.beqi x1, 1, 2
+
+
+# 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.e.bnei x0, 115, 4094
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.bnei x4, 115
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be non-zero in the range [-32768, 32767]
+qc.e.bnei x4, -33115, 4094
+
+# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.bnei x4, 115, 211
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.bnei x4, 115, 4094
+
+
+# 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.e.bgei x0, -32768, -4096
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.bgei x10, -32768
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be non-zero in the range [-32768, 32767]
+qc.e.bgei x10, -32769, -4096
+
+# CHECK-PLUS: :[[@LINE+1]]:24: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.bgei x10, -32768, -4097
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.bgei x10, -32768, -4096
+
+
+# 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.e.blti x0, 32767, 2000
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.blti x1, 32767
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be non-zero in the range [-32768, 32767]
+qc.e.blti x1, 42767, 2000
+
+# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.blti x1, 32767, 2001
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.blti x1, 32767, 2000
+
+
+# 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.e.bgeui x0, 711, 128
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.bgeui x12, 711
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be an integer in the range [1, 32767]
+qc.e.bgeui x12, 0, 128
+
+# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.bgeui x12, 711, 129
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.bgeui x12, 711, 128
+
+
+# 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.e.bltui x0, 7, 666
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.bltui x2, 7
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be an integer in the range [1, 32767]
+qc.e.bltui x2, -7, 666
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
+qc.e.bltui x2, 7, 667
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcibi' (Qualcomm uC Branch Immediate Extension)
+qc.e.bltui x2, 7, 666
diff --git a/llvm/test/MC/RISCV/xqcibi-valid.s b/llvm/test/MC/RISCV/xqcibi-valid.s
new file mode 100644
index 0000000000000..194f02f041771
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcibi-valid.s
@@ -0,0 +1,71 @@
+# Xqcibi - Qualcomm uC Branch Immediate Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcibi -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibi < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcibi -M no-aliases -d - \
+# RUN: | FileCheck -check-prefix=CHECK-OBJ %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcibi -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibi < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqcibi -d - \
+# RUN: | FileCheck -check-prefix=CHECK-OBJ %s
+
+# CHECK-INST: qc.beqi s0, 12, 346
+# CHECK-OBJ: qc.beqi s0, 0xc, 0x15a
+# CHECK-ENC: encoding: [0x7b,0x0d,0xc4,0x14]
+qc.beqi x8, 12, 346
+
+# CHECK-INST: qc.bnei tp, 15, 4094
+# CHECK-OBJ: qc.bnei tp, 0xf, 0x1002
+# CHECK-ENC: encoding: [0xfb,0x1f,0xf2,0x7e]
+qc.bnei x4, 15, 4094
+
+# CHECK-INST: qc.bgei a0, 1, -4096
+# CHECK-OBJ: qc.bgei a0, 0x1, 0xfffff008
+# CHECK-ENC: encoding: [0x7b,0x50,0x15,0x80]
+qc.bgei x10, 1, -4096
+
+# CHECK-INST: qc.blti ra, 6, 2000
+# CHECK-OBJ: qc.blti ra, 0x6, 0x7dc
+# CHECK-ENC: encoding: [0x7b,0xc8,0x60,0x7c]
+qc.blti x1, 6, 2000
+
+# CHECK-INST: qc.bgeui a2, 11, 128
+# CHECK-OBJ: qc.bgeui a2, 0xb, 0x90
+# CHECK-ENC: encoding: [0x7b,0x70,0xb6,0x08]
+qc.bgeui x12, 11, 128
+
+# CHECK-INST: qc.bltui sp, 7, 666
+# CHECK-OBJ: qc.bltui sp, 0x7, 0x2ae
+# CHECK-ENC: encoding: [0x7b,0x6d,0x71,0x28]
+qc.bltui x2, 7, 666
+
+# CHECK-INST: qc.e.beqi ra, 1, 2
+# CHECK-OBJ: qc.e.beqi ra, 0x1, 0x1a
+# CHECK-ENC: encoding: [0x1f,0xc1,0x80,0x01,0x01,0x00]
+qc.e.beqi x1, 1, 2
+
+# CHECK-INST: qc.e.bnei tp, 115, 4094
+# CHECK-OBJ: qc.e.bnei tp, 0x73, 0x101c
+# CHECK-ENC: encoding: [0x9f,0x4f,0x92,0x7f,0x73,0x00]
+qc.e.bnei x4, 115, 4094
+
+# CHECK-INST: qc.e.bgei a0, -32768, -4096
+# CHECK-OBJ: qc.e.bgei a0, -0x8000, 0xfffff024
+# CHECK-ENC: encoding: [0x1f,0x40,0xd5,0x81,0x00,0x80]
+qc.e.bgei x10, -32768, -4096
+
+# CHECK-INST: qc.e.blti ra, 32767, 2000
+# CHECK-OBJ: qc.e.blti ra, 0x7fff, 0x7fa
+# CHECK-ENC: encoding: [0x1f,0xc8,0xc0,0x7d,0xff,0x7f]
+qc.e.blti x1, 32767, 2000
+
+# CHECK-INST: qc.e.bgeui a2, 711, 128
+# CHECK-OBJ: qc.e.bgeui a2, 0x2c7, 0xb0
+# CHECK-ENC: encoding: [0x1f,0x40,0xf6,0x09,0xc7,0x02]
+qc.e.bgeui x12, 711, 128
+
+# CHECK-INST: qc.e.bltui sp, 7, 666
+# CHECK-OBJ: qc.e.bltui sp, 0x7, 0x2d0
+# CHECK-ENC: encoding: [0x1f,0x4d,0xe1,0x29,0x07,0x00]
+qc.e.bltui x2, 7, 666
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 00dc160c39a36..503d261d7f153 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -657,7 +657,8 @@ 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_xqcibm0p4"}) {
+ "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
+ "rv64i_xqcibi0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1127,6 +1128,7 @@ Experimental extensions
xqccmp 0.1
xqcia 0.4
xqciac 0.3
+ xqcibi 0.2
xqcibm 0.4
xqcicli 0.2
xqcicm 0.2
More information about the cfe-commits
mailing list