diff options
author | quic_hchandel <quic_hchandel@quicinc.com> | 2025-02-24 21:34:29 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-24 08:04:29 -0800 |
commit | 538b898a836ac6efc3b0ec12cf27b511608d2e64 (patch) | |
tree | 2dab95a68e3a38910d750e98324d37bc295a309c /llvm/lib | |
parent | b66ec64b5b634cbf760d69d1629e462268aa1cbd (diff) | |
download | llvm-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.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFeatures.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 48 | ||||
-rw-r--r-- | llvm/lib/TargetParser/RISCVISAInfo.cpp | 5 |
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"); |