Author: quic_hchandel Date: 2025-03-20T11:14:53+05:30 New Revision: 0744d4926a0c567b0f10d19f0478b7a4bf960a19
URL: https://github.com/llvm/llvm-project/commit/0744d4926a0c567b0f10d19f0478b7a4bf960a19 DIFF: https://github.com/llvm/llvm-project/commit/0744d4926a0c567b0f10d19f0478b7a4bf960a19.diff LOG: [RISCV] Add Qualcomm uC Xqcilb (Long Branch) extension (#131996) This extension adds two long branch instructions. 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. Co-authored-by: Sudharsan Veeravalli <quic_...@quicinc.com> Added: llvm/test/MC/RISCV/xqcilb-invalid.s llvm/test/MC/RISCV/xqcilb-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/RISCVFeatures.td llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td llvm/lib/TargetParser/RISCVISAInfo.cpp llvm/test/CodeGen/RISCV/attributes.ll 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 35de2820ef84f..40b8eb6217240 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -205,6 +205,7 @@ // CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqciint 0.4 'Xqciint' (Qualcomm uC Interrupts Extension) +// CHECK-NEXT: xqcilb 0.2 'Xqcilb' (Qualcomm uC Long Branch Extension) // CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension) // CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension) // CHECK-NEXT: xqcilo 0.2 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension) diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index d6ac226dad5e6..28d09cffa95c0 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -461,6 +461,9 @@ The current vendor extensions supported are: ``experimental-Xqciint`` LLVM implements `version 0.4 of the Qualcomm uC Interrupts 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-Xqcilb`` + LLVM implements `version 0.2 of the Qualcomm uC Long Branch 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-Xqcili`` LLVM implements `version 0.2 of the Qualcomm uC Load Large 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 30d66b4a77a71..205c2ad25f23e 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -114,6 +114,8 @@ Changes to the PowerPC Backend Changes to the RISC-V Backend ----------------------------- +* Adds experimental assembler support for the Qualcomm uC 'Xqcilb` (Long Branch) + extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcili` (Load Large Immediate) extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcilia` (Large Immediate Arithmetic) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index ce25380cbdda2..d3500e3e44c50 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1144,6 +1144,17 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_None; } + bool isSImm32Lsb0() const { + if (!isImm()) + return false; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_None; + int64_t Imm; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && + isShiftedInt<31, 1>(fixImmediateForRV32(Imm, isRV64Imm())) && + VK == RISCVMCExpr::VK_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 @@ -1777,6 +1788,11 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError(Operands, ErrorInfo, std::numeric_limits<int32_t>::min(), std::numeric_limits<uint32_t>::max()); + case Match_InvalidSImm32Lsb0: + return generateImmOutOfRangeError( + Operands, ErrorInfo, std::numeric_limits<int32_t>::min(), + std::numeric_limits<int32_t>::max() - 1, + "operand must be a multiple of 2 bytes in the range "); 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 05bb6d30cc9a7..5abf15a404dfb 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -667,10 +667,10 @@ static constexpr FeatureBitset XqciFeatureGroup = { RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm, RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm, RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr, - RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcili, - RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo, - RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim, - RISCV::FeatureVendorXqcisls, + RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilb, + RISCV::FeatureVendorXqcili, RISCV::FeatureVendorXqcilia, + RISCV::FeatureVendorXqcilo, RISCV::FeatureVendorXqcilsm, + RISCV::FeatureVendorXqcisim, RISCV::FeatureVendorXqcisls, }; static constexpr FeatureBitset XSfVectorGroup = { diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index f23a855e7049f..761cfbea76734 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1374,6 +1374,14 @@ def HasVendorXqciint AssemblerPredicate<(all_of FeatureVendorXqciint), "'Xqciint' (Qualcomm uC Interrupts Extension)">; +def FeatureVendorXqcilb + : RISCVExperimentalExtension<0, 2, "Qualcomm uC Long Branch Extension", + [FeatureStdExtZca]>; + +def HasVendorXqcilb : Predicate<"Subtarget->hasVendorXqcilb()">, + AssemblerPredicate<(all_of FeatureVendorXqcilb), + "'Xqcilb' (Qualcomm uC Long Branch Extension)">; + def FeatureVendorXqcili : RISCVExperimentalExtension<0, 2, "Qualcomm uC Load Large Immediate Extension", [FeatureStdExtZca]>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 59fd13c6d683a..c009bd3b24682 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -96,6 +96,21 @@ def simm32 : RISCVOp<XLenVT> { }]; } +// A 32-bit signed immediate where the least significant bit is zero. +def simm32_lsb0 : Operand<OtherVT> { + let ParserMatchClass = SImmAsmOperand<32, "Lsb0">; + let PrintMethod = "printBranchOperand"; + let EncoderMethod = "getImmOpValueAsr1"; + let DecoderMethod = "decodeSImmOperandAndLsl1<32>"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + return isShiftedInt<31, 1>(Imm); + }]; + let OperandType = "OPERAND_PCREL"; +} + //===----------------------------------------------------------------------===// // Instruction Formats //===----------------------------------------------------------------------===// @@ -413,6 +428,24 @@ class QCIRVInstEI<bits<3> funct3, bits<2> funct2, string opcodestr> (ins GPRNoX0:$rs1, simm26:$imm), opcodestr, "$rd, $rs1, $imm">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class QCIRVInst48EJ<bits<2> func2, string opcodestr> + : RVInst48<(outs), (ins simm32_lsb0:$imm31), + opcodestr, "$imm31", [], InstFormatOther> { + bits<31> imm31; + + let Inst{47-32} = imm31{30-15}; + let Inst{31} = imm31{11}; + let Inst{30-25} = imm31{9-4}; + let Inst{24-20} = 0b00000; + let Inst{19-17} = imm31{14-12}; + let Inst{16-15} = func2; + let Inst{14-12} = 0b100; + let Inst{11-8} = imm31{3-0}; + let Inst{7} = imm31{10}; + let Inst{6-0} = 0b0011111; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -677,6 +710,13 @@ let Predicates = [HasVendorXqcilo, IsRV32] in { def QC_E_SW : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">; } // Predicates = [HasVendorXqcilo, IsRV32] +let Predicates = [HasVendorXqcilb, IsRV32] in { + let isCall = 1, Defs = [X1] in + def QC_E_JAL : QCIRVInst48EJ<0b01, "qc.e.jal">; + let isBranch = 1, isTerminator = 1, isBarrier = 1 in + def QC_E_J : QCIRVInst48EJ<0b00, "qc.e.j">; +} // Predicates = [HasVendorXqcilb, IsRV32] + let Predicates = [HasVendorXqcili, IsRV32] in { let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20:$imm20), diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index 11d4b3746e94d..4cb263b028625 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -744,9 +744,10 @@ Error RISCVISAInfo::checkDependency() { bool HasXqccmp = Exts.count("xqccmp") != 0; static constexpr StringLiteral XqciExts[] = { - {"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"}, - {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcili"}, - {"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}}; + {"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, + {"xqcicli"}, {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, + {"xqciint"}, {"xqcilb"}, {"xqcili"}, {"xqcilia"}, + {"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}}; static constexpr StringLiteral ZcdOverlaps[] = { {"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}}; diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 344438e554ce6..82b2b25add735 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -91,6 +91,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilb %s -o - | FileCheck --check-prefix=RV32XQCILB %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck --check-prefix=RV32XQCILI %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %s @@ -418,6 +419,7 @@ ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2" ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2" ; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4" +; RV32XQCILB: .attribute 5, "rv32i2p1_zca1p0_xqcilb0p2" ; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2" ; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2" ; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2" diff --git a/llvm/test/MC/RISCV/xqcilb-invalid.s b/llvm/test/MC/RISCV/xqcilb-invalid.s new file mode 100644 index 0000000000000..1a9009b26b691 --- /dev/null +++ b/llvm/test/MC/RISCV/xqcilb-invalid.s @@ -0,0 +1,24 @@ +# Xqcilb - Qualcomm uC Long Branch Extension +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilb < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s +# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilb < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.e.j + +# CHECK-PLUS: :[[@LINE+1]]:9: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646] +qc.e.j -2147483649 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilb' (Qualcomm uC Long Branch Extension) +qc.e.j -2147483648 + + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.e.jal + +# CHECK-PLUS: :[[@LINE+1]]:10: error: operand must be a multiple of 2 bytes in the range [-2147483648, 2147483646] +qc.e.jal 2147483649 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilb' (Qualcomm uC Long Branch Extension) +qc.e.jal 2147483640 diff --git a/llvm/test/MC/RISCV/xqcilb-valid.s b/llvm/test/MC/RISCV/xqcilb-valid.s new file mode 100644 index 0000000000000..1c722e3b3173e --- /dev/null +++ b/llvm/test/MC/RISCV/xqcilb-valid.s @@ -0,0 +1,26 @@ +# Xqcilb - Qualcomm uC Long Branch Extension +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilb -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilb < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcilb -M no-aliases --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-OBJ %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilb -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilb < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcilb --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-OBJ %s + +# CHECK-INST: qc.e.j -2147483648 +# CHECK-OBJ: qc.e.j 0x80000000 +# CHECK-ENC: encoding: [0x1f,0x40,0x00,0x00,0x00,0x80] +qc.e.j -2147483648 + +# CHECK-INST: qc.e.jal 2147483640 +# CHECK-OBJ: qc.e.jal 0x7ffffffe +# CHECK-ENC: encoding: [0x9f,0xcc,0x0e,0xfe,0xff,0x7f] +qc.e.jal 2147483640 + +# CHECK-INST: qc.e.jal -116 +# CHECK-OBJ: qc.e.jal 0xffffff98 +# CHECK-ENC: encoding: [0x9f,0xc6,0x0e,0xf8,0xff,0xff] +qc.e.jal 0xffffff8c diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index c734f8a66d289..e609189b086e9 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -663,7 +663,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) { "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2", "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4", "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4", - "rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2"}) { + "rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2", + "rv64i_xqcilb0p2"}) { EXPECT_THAT( toString(RISCVISAInfo::parseArchString(Input, true).takeError()), ::testing::EndsWith(" is only supported for 'rv32'")); @@ -1150,6 +1151,7 @@ Experimental extensions xqcics 0.2 xqcicsr 0.2 xqciint 0.4 + xqcilb 0.2 xqcili 0.2 xqcilia 0.2 xqcilo 0.2 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits