https://github.com/u4f3 updated https://github.com/llvm/llvm-project/pull/130012
>From 52cfa2c358ba20ec20f023828ba2d8bcccb38e83 Mon Sep 17 00:00:00 2001 From: u4f3 <ricoaf...@gmail.com> Date: Fri, 7 Mar 2025 15:01:57 +0800 Subject: [PATCH] [RISCV] Add Qualcomn uC Xqcili (load large immediates) extension The Xqcili extension includes a two instructions that load large immediates than is available with the base RISC-V ISA. 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. --- .../Driver/print-supported-extensions-riscv.c | 1 + llvm/docs/RISCVUsage.rst | 3 ++ llvm/docs/ReleaseNotes.md | 2 + .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 13 ++++++ .../RISCV/Disassembler/RISCVDisassembler.cpp | 5 +- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 + llvm/lib/Target/RISCV/RISCVFeatures.td | 8 ++++ llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 15 ++++++ llvm/lib/TargetParser/RISCVISAInfo.cpp | 6 +-- llvm/test/CodeGen/RISCV/attributes.ll | 2 + llvm/test/MC/RISCV/xqcili-invalid.s | 32 +++++++++++++ llvm/test/MC/RISCV/xqcili-valid.s | 46 +++++++++++++++++++ .../TargetParser/RISCVISAInfoTest.cpp | 4 +- 13 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 llvm/test/MC/RISCV/xqcili-invalid.s create mode 100644 llvm/test/MC/RISCV/xqcili-valid.s diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index d9335fe502bb6..912a3ad4b6d6e 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -202,6 +202,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: 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) // CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension) diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 831e8fd5d186b..32a65d898bb31 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -456,6 +456,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-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. + ``experimental-Xqcilia`` LLVM implements `version 0.2 of the Qualcomm uC Large Immediate Arithmetic 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 3d608c636a8f6..be465bfe5dc6b 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -107,6 +107,8 @@ Changes to the PowerPC Backend Changes to the RISC-V Backend ----------------------------- +* 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) extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcibm` (Bit Manipulation) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b342c18bece08..372e2e2ad8ba1 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1076,6 +1076,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_None; } + bool isSImm20() const { + if (!isImm()) + return false; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + int64_t Imm; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) && + isInt<20>(fixImmediateForRV32(Imm, isRV64Imm())); + } + bool isSImm26() const { if (!isImm()) return false; @@ -1712,6 +1722,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSImm26: return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25), (1 << 25) - 1); + case Match_InvalidSImm20: + return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19), + (1 << 19) - 1); case Match_InvalidSImm32: return generateImmOutOfRangeError(Operands, ErrorInfo, std::numeric_limits<int32_t>::min(), diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index de742ac428de2..29d450e842b68 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -660,8 +660,9 @@ static constexpr FeatureBitset XqciFeatureGroup = { RISCV::FeatureVendorXqcibm, RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm, RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr, RISCV::FeatureVendorXqciint, - RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo, - RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisls, + RISCV::FeatureVendorXqcili, 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..96ffbfd5476b5 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -329,6 +329,7 @@ enum OperandType : unsigned { OPERAND_SIMM11, OPERAND_SIMM12, OPERAND_SIMM12_LSB00000, + OPERAND_SIMM20, OPERAND_SIMM26, OPERAND_SIMM32, OPERAND_CLUI_IMM, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 21119f624339c..1480d700fbc81 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1359,6 +1359,14 @@ def HasVendorXqciint AssemblerPredicate<(all_of FeatureVendorXqciint), "'Xqciint' (Qualcomm uC Interrupts Extension)">; +def FeatureVendorXqcili + : RISCVExperimentalExtension<0, 2, "Qualcomm uC Load Large Immediate Extension", + [FeatureStdExtZca]>; + +def HasVendorXqcili : Predicate<"Subtarget->hasVendorXqcili()">, + AssemblerPredicate<(all_of FeatureVendorXqcili), + "'Xqcili' (Qualcomm uC Load Large Immediate Extension)">; + def FeatureVendorXqcilia : RISCVExperimentalExtension<0, 2, "Qualcomm uC Large Immediate Arithmetic Extension", [FeatureStdExtZca]>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 32cfade8697b9..a8e642d04fd3a 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -56,6 +56,8 @@ def uimm11 : RISCVUImmLeafOp<11>; def simm11 : RISCVSImmLeafOp<11>; +def simm20 : RISCVSImmLeafOp<20>; + def simm26 : RISCVSImmLeafOp<26>; // 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no @@ -591,6 +593,19 @@ let Predicates = [HasVendorXqcilo, IsRV32] in { def QC_E_SW : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">; } // Predicates = [HasVendorXqcilo, 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), + "qc.li", "$rd, $imm20"> { + let Inst{31} = imm20{19}; + let Inst{30-16} = imm20{14-0}; + let Inst{15-12} = imm20{18-15}; + } + + def QC_E_LI : QCIRVInstEAI<0b000, 0b0, "qc.e.li">; +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +} // Predicates = [HasVendorXqcili, IsRV32] + let Predicates = [HasVendorXqcilia, IsRV32] in { let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { def QC_E_XORAI : QCIRVInstEAI<0b001, 0b0, "qc.e.xorai">; diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index dd74f79f04b92..e9373085941da 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"}, {"xqcibm"}, {"xqcicli"}, {"xqcicm"}, + {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcili"}, {"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 5d4d96a52a0fd..659de283a1a7e 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -90,6 +90,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-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 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s @@ -412,6 +413,7 @@ ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2" ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2" ; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4" +; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2" ; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2" ; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2" ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2" diff --git a/llvm/test/MC/RISCV/xqcili-invalid.s b/llvm/test/MC/RISCV/xqcili-invalid.s new file mode 100644 index 0000000000000..0c4b4f04e86e9 --- /dev/null +++ b/llvm/test/MC/RISCV/xqcili-invalid.s @@ -0,0 +1,32 @@ +# Xqcili - Qualcomm uC Load Large Immediate Extension +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcili < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS,CHECK-IMM %s +# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcili < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS,CHECK-EXT %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.e.li 9, 33554432 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.e.li x9 + +# CHECK-IMM: :[[@LINE+1]]:13: error: immediate must be an integer in the range [-2147483648, 4294967295] +qc.e.li x9, 4294967296 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension) +qc.e.li x9, 4294967295 + + +# CHECK-PLUS: :[[@LINE+2]]:7: error: register must be a GPR excluding zero (x0) +# CHECK-MINUS: :[[@LINE+1]]:7: error: invalid operand for instruction +qc.li x0, 114514 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.li x10 + +# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [-524288, 524287] +qc.li x10, 33554432 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension) +qc.li x10, 114514 diff --git a/llvm/test/MC/RISCV/xqcili-valid.s b/llvm/test/MC/RISCV/xqcili-valid.s new file mode 100644 index 0000000000000..5e372c3dbd82f --- /dev/null +++ b/llvm/test/MC/RISCV/xqcili-valid.s @@ -0,0 +1,46 @@ +# Xqcili - Qualcomm uC Load Large Immediate Extension +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcili -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s + +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcili -M no-aliases --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcili -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s + +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcili --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# CHECK-INST: qc.e.li a0, -1 +# CHECK-ENC: encoding: [0x1f,0x05,0xff,0xff,0xff,0xff] +qc.e.li x10, 4294967295 + +# CHECK-INST: qc.e.li a0, -2147483648 +# CHECK-ENC: encoding: [0x1f,0x05,0x00,0x00,0x00,0x80] +qc.e.li x10, -2147483648 + +# CHECK-INST: qc.e.li s1, -33554432 +# CHECK-ENC: encoding: [0x9f,0x04,0x00,0x00,0x00,0xfe] +qc.e.li x9, -33554432 + +# CHECK-INST: qc.e.li s1, 33554431 +# CHECK-ENC: encoding: [0x9f,0x04,0xff,0xff,0xff,0x01] +qc.e.li x9, 33554431 + +# CHECK-INST: qc.li s1, 524287 +# CHECK-ENC: encoding: [0x9b,0xf4,0xff,0x7f] +qc.li x9, 524287 + +# CHECK-INST: qc.li s1, -524288 +# CHECK-ENC: encoding: [0x9b,0x04,0x00,0x80] +qc.li x9, -524288 + +# CHECK-INST: qc.li a0, 12345 +# CHECK-ENC: encoding: [0x1b,0x05,0x39,0x30] +qc.li x10, 12345 + +# CHECK-INST: qc.li a0, -12346 +# CHECK-ENC: encoding: [0x1b,0xf5,0xc6,0xcf] +qc.li x10, -12346 diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index e24b2d47f6bc4..27f91ca8dd4bd 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_xqciint0p4", - "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4"}) { + "rv64i_xqcilo0p2", "rv64i_xqcili0p2", "rv64i_xqcilia0p2", + "rv64i_xqcibm0p4"}) { EXPECT_THAT( toString(RISCVISAInfo::parseArchString(Input, true).takeError()), ::testing::EndsWith(" is only supported for 'rv32'")); @@ -1133,6 +1134,7 @@ Experimental extensions xqcics 0.2 xqcicsr 0.2 xqciint 0.4 + xqcili 0.2 xqcilia 0.2 xqcilo 0.2 xqcilsm 0.2 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits