aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorquic_hchandel <quic_hchandel@quicinc.com>2025-02-24 21:34:29 +0530
committerGitHub <noreply@github.com>2025-02-24 08:04:29 -0800
commit538b898a836ac6efc3b0ec12cf27b511608d2e64 (patch)
tree2dab95a68e3a38910d750e98324d37bc295a309c /llvm/lib
parentb66ec64b5b634cbf760d69d1629e462268aa1cbd (diff)
downloadllvm-538b898a836ac6efc3b0ec12cf27b511608d2e64.zip
llvm-538b898a836ac6efc3b0ec12cf27b511608d2e64.tar.gz
llvm-538b898a836ac6efc3b0ec12cf27b511608d2e64.tar.bz2
[RISCV] Add Qualcomm uC Xqcilia (Large Immediate Arithmetic) extension (#124706)
This extension adds eight 48 bit large arithmetic instructions. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp14
-rw-r--r--llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp2
-rw-r--r--llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h1
-rw-r--r--llvm/lib/Target/RISCV/RISCVFeatures.td8
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td48
-rw-r--r--llvm/lib/TargetParser/RISCVISAInfo.cpp5
6 files changed, 76 insertions, 2 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 6d4466b..650ad48 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1056,6 +1056,16 @@ public:
isInt<26>(fixImmediateForRV32(Imm, isRV64Imm()));
}
+ bool isSImm32() const {
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ if (!isImm())
+ return false;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isInt<32>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
/// getStartLoc - Gets location of the first token of this operand
SMLoc getStartLoc() const override { return StartLoc; }
/// getEndLoc - Gets location of the last token of this operand
@@ -1665,6 +1675,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm26:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
(1 << 25) - 1);
+ case Match_InvalidSImm32:
+ return generateImmOutOfRangeError(Operands, ErrorInfo,
+ std::numeric_limits<int32_t>::min(),
+ std::numeric_limits<uint32_t>::max());
case Match_InvalidRnumArg: {
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 53208b4..8c07d87 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -767,6 +767,8 @@ DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
for (size_t i = Size; i-- != 0;) {
Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
}
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilia, DecoderTableXqcilia48,
+ "Qualcomm uC Large Immediate Arithmetic 48bit");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilo, DecoderTableXqcilo48,
"Qualcomm uC Large Offset Load Store 48bit");
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 2e5b03c..80ff18d9 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -327,6 +327,7 @@ enum OperandType : unsigned {
OPERAND_SIMM12,
OPERAND_SIMM12_LSB00000,
OPERAND_SIMM26,
+ OPERAND_SIMM32,
OPERAND_CLUI_IMM,
OPERAND_VTYPEI10,
OPERAND_VTYPEI11,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 26d46af..1a93371 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1358,6 +1358,14 @@ def HasVendorXqciint
AssemblerPredicate<(all_of FeatureVendorXqciint),
"'Xqciint' (Qualcomm uC Interrupts Extension)">;
+def FeatureVendorXqcilia
+ : RISCVExperimentalExtension<0, 2, "Qualcomm uC Large Immediate Arithmetic Extension",
+ [FeatureStdExtZca]>;
+def HasVendorXqcilia
+ : Predicate<"Subtarget->hasVendorXqcilia()">,
+ AssemblerPredicate<(all_of FeatureVendorXqcilia),
+ "'Xqcilia' (Qualcomm uC Large Immediate Arithmetic 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 1f042b0..3a8039f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -34,6 +34,21 @@ def uimm11 : RISCVUImmLeafOp<11>;
def simm26 : RISCVSImmLeafOp<26>;
+// 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no
+// sign-/zero-extension. This is represented internally as a signed 32-bit value.
+def simm32 : RISCVOp<XLenVT> {
+ let ParserMatchClass = SImmAsmOperand<32, "">;
+ let EncoderMethod = "getImmOpValue";
+ let DecoderMethod = "decodeSImmOperand<32>";
+ let OperandType = "OPERAND_SIMM32";
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (MCOp.evaluateAsConstantImm(Imm))
+ return isInt<32>(Imm);
+ return false;
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
@@ -245,6 +260,25 @@ class QCIRVInstESStore<bits<3> funct3, bits<2> funct2, string opcodestr>
(ins GPRMem:$rs2, GPR:$rs1, simm26:$imm),
opcodestr, "$rs2, ${imm}(${rs1})">;
+class QCIRVInstEAI<bits<3> funct3, bits<1> funct1, string opcodestr>
+ : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm32:$imm),
+ opcodestr, "$rd, $imm", [], InstFormatOther> {
+ bits<5> rd;
+ bits<32> imm;
+
+ let Constraints = "$rd = $rd_wb";
+ let Inst{47-16} = imm{31-0};
+ let Inst{15} = funct1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Inst{6-0} = 0b0011111;
+}
+
+class QCIRVInstEI<bits<3> funct3, bits<2> funct2, string opcodestr>
+ : QCIRVInstEIBase<funct3, funct2, (outs GPRNoX0:$rd),
+ (ins GPRNoX0:$rs1, simm26:$imm), opcodestr,
+ "$rd, $rs1, $imm">;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -435,6 +469,20 @@ let Predicates = [HasVendorXqcilo, IsRV32], DecoderNamespace = "Xqcilo" in {
def QC_E_SW : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">;
} // Predicates = [HasVendorXqcilo, IsRV32], DecoderNamespace = "Xqcilo"
+let Predicates = [HasVendorXqcilia, IsRV32], DecoderNamespace = "Xqcilia" in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ def QC_E_XORAI : QCIRVInstEAI<0b001, 0b0, "qc.e.xorai">;
+ def QC_E_ORAI : QCIRVInstEAI<0b001, 0b1, "qc.e.orai" >;
+ def QC_E_ADDAI : QCIRVInstEAI<0b010, 0b0, "qc.e.addai">;
+ def QC_E_ANDAI : QCIRVInstEAI<0b010, 0b1, "qc.e.andai">;
+
+ def QC_E_XORI : QCIRVInstEI<0b011, 0b00, "qc.e.xori">;
+ def QC_E_ORI : QCIRVInstEI<0b011, 0b01, "qc.e.ori" >;
+ def QC_E_ADDI : QCIRVInstEI<0b011, 0b10, "qc.e.addi">;
+ def QC_E_ANDI : QCIRVInstEI<0b011, 0b11, "qc.e.andi">;
+} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqcilia, IsRV32], DecoderNamespace = "Xqcilia"
+
//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index c78d60fd8..132c47c 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,8 +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"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
+ {"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"},
+ {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcilia"},
+ {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
if (HasI && HasE)
return getIncompatibleError("i", "e");