Author: Sudharsan Veeravalli Date: 2024-11-29T10:26:00+05:30 New Revision: 8fcbba82d6c8038c4a0c5859275523414107b198
URL: https://github.com/llvm/llvm-project/commit/8fcbba82d6c8038c4a0c5859275523414107b198 DIFF: https://github.com/llvm/llvm-project/commit/8fcbba82d6c8038c4a0c5859275523414107b198.diff LOG: [RISCV] Add Qualcomm uC Xqcisls (Scaled Load Store) extension (#117987) This extension adds 8 load/store instructions with a scaled index addressing mode. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. Added: llvm/test/MC/RISCV/xqcisls-invalid.s llvm/test/MC/RISCV/xqcisls-valid.s Modified: clang/test/Driver/print-supported-extensions-riscv.c llvm/docs/RISCVUsage.rst llvm/docs/ReleaseNotes.md 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 02edfc03e59cac..70b7a96daf1daf 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -189,6 +189,7 @@ // CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) +// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: // CHECK-NEXT: Supported Profiles // CHECK-NEXT: rva20s64 diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index a7000baa69d806..230bf66fcf461b 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -429,6 +429,9 @@ The current vendor extensions supported are: ``experimental-Xqcicsr`` LLVM implements `version 0.2 of the Qualcomm uC CSR 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-Xqcisls`` + LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store 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 C Intrinsics ========================= diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 8b155d77bbb397..6d50839d68953e 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -213,6 +213,8 @@ Changes to the RISC-V Backend between e.g. F and Zfinx code. * Adds experimental assembler support for the Qualcomm uC 'Xqcicsr` (CSR) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store) + extension. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index e4f7ee323cf20b..95658f24f79e1c 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -684,6 +684,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "CORE-V Immediate Branching custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicsr, DecoderTableXqcicsr32, "Qualcomm uC CSR custom opcode table"); + TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32, + "Qualcomm uC Scaled Load Store custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 48ae378c0e67ef..95a37a76836729 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1351,6 +1351,14 @@ def HasVendorXqcicsr AssemblerPredicate<(all_of FeatureVendorXqcicsr), "'Xqcicsr' (Qualcomm uC CSR Extension)">; +def FeatureVendorXqcisls + : RISCVExperimentalExtension<"xqcisls", 0, 2, + "'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">; +def HasVendorXqcisls + : Predicate<"Subtarget->hasVendorXqcisls()">, + AssemblerPredicate<(all_of FeatureVendorXqcisls), + "'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">; + //===----------------------------------------------------------------------===// // LLVM specific features and extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 570fe23d744e14..5f560aa0cc7bc0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -22,6 +22,29 @@ // Instruction Class Templates //===----------------------------------------------------------------------===// +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +class QCILoad_ScaleIdx<bits<4> func4, string opcodestr> + : RVInstRBase<0b111, OPC_CUSTOM_0, + (outs GPR:$rd), (ins GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt), + opcodestr, "$rd, $rs1, $rs2, $shamt"> { + bits<3> shamt; + let Inst{31-28} = func4; + let Inst{27-25} = shamt; +} +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { +// rd corresponds to the source for the store 'rs3' described in the spec. +class QCIStore_ScaleIdx<bits<4> func4, string opcodestr> + : RVInstRBase<0b110, OPC_CUSTOM_1, (outs), + (ins GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt), + opcodestr, "$rd, $rs1, $rs2, $shamt"> { + bits<3> shamt; + let Inst{31-28} = func4; + let Inst{27-25} = shamt; +} +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -37,3 +60,15 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { "$rd, $rs1, $rs2">; } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 } // Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr" + +let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in { + def QC_LRB : QCILoad_ScaleIdx<0b1000, "qc.lrb">; + def QC_LRH : QCILoad_ScaleIdx<0b1001, "qc.lrh">; + def QC_LRW : QCILoad_ScaleIdx<0b1010, "qc.lrw">; + def QC_LRBU : QCILoad_ScaleIdx<0b1011, "qc.lrbu">; + def QC_LRHU : QCILoad_ScaleIdx<0b1100, "qc.lrhu">; + + def QC_SRB : QCIStore_ScaleIdx<0b1101, "qc.srb">; + def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">; + def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">; +} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index cc5be59572e040..5673866f9d9d9d 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -741,6 +741,7 @@ Error RISCVISAInfo::checkDependency() { bool HasVector = Exts.count("zve32x") != 0; bool HasZvl = MinVLen != 0; bool HasZcmt = Exts.count("zcmt") != 0; + static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}}; if (HasI && HasE) return getIncompatibleError("i", "e"); @@ -771,9 +772,9 @@ Error RISCVISAInfo::checkDependency() { return getIncompatibleError("xwchc", "zcb"); } - if (Exts.count("xqcicsr") != 0 && (XLen != 32)) { - return getError("'xqcicsr' is only supported for 'rv32'"); - } + for (auto Ext : XqciExts) + if (Exts.count(Ext.str()) && (XLen != 32)) + return getError("'" + Twine(Ext) + "'" + " is only supported for 'rv32'"); return Error::success(); } diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 554ae89357f72c..8a3d5e5cfe6216 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -82,6 +82,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s ; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck --check-prefix=RV32XWCHC %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s ; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s ; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s @@ -387,6 +388,7 @@ ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0" ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2" ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2" +; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2" ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0" ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0" ; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0" diff --git a/llvm/test/MC/RISCV/xqcisls-invalid.s b/llvm/test/MC/RISCV/xqcisls-invalid.s new file mode 100644 index 00000000000000..4cd2a14975a946 --- /dev/null +++ b/llvm/test/MC/RISCV/xqcisls-invalid.s @@ -0,0 +1,132 @@ +# Xqcisls - Qualcomm uC Scaled Load Store Extension +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisls < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s +# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisls < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s + +# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction +qc.lrb x5, x2, x0, 4 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.lrb x5, x2, x4 + +# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7] +qc.lrb x5, x2, x4, 12 + +# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction +qc.lrb x5, 2, x4, 4 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.lrb x5, x2, x4, 4 + + +# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction +qc.lrh x1, x12, x0, 2 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.lrh x1, x12, x6 + +# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 7] +qc.lrh x1, x12, x6, 22 + +# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction +qc.lrh x1, 12, x6, 2 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.lrh x1, x12, x6, 2 + + +# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction +qc.lrw x15, x7, x0, 1 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.lrw x15, x7, x14 + +# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7] +qc.lrw x15, x7, x14, 11 + +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +qc.lrw x15, 7, x14, 1 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.lrw x15, x7, x14, 1 + + +# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction +qc.lrbu x9, x11, x0, 7 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.lrbu x9, x11, x4 + +# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7] +qc.lrbu x9, x11, x4, 37 + +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +qc.lrbu x9, 11, x4, 7 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.lrbu x9, x11, x4, 7 + + +# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction +qc.lrhu x16, x6, x0, 4 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.lrhu x16, x6, x10 + +# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7] +qc.lrhu x16, x6, x10, 44 + +# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction +qc.lrhu x16, 6, x10, 4 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.lrhu x16, x6, x10, 4 + + +# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction +qc.srb x0, x2, x0, 3 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.srb x0, x2, x8 + +# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7] +qc.srb x0, x2, x8, 93 + +# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction +qc.srb x0, 2, x8, 3 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.srb x0, x2, x8, 3 + + +# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction +qc.srh x13, x0, x0, 6 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.srh x13, x0, x20 + +# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7] +qc.srh x13, x0, x20, 76 + +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +qc.srh x13, 0, x20, 6 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.srh x13, x0, x20, 6 + + +# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction +qc.srw x17, x18, x0, 0 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.srw x17, x18, x19 + +# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7] +qc.srw x17, x18, x19, 10 + +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +qc.srw x17, 18, x19, 0 + +# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) +qc.srw x17, x18, x19, 0 diff --git a/llvm/test/MC/RISCV/xqcisls-valid.s b/llvm/test/MC/RISCV/xqcisls-valid.s new file mode 100644 index 00000000000000..ae8370afc6c6e2 --- /dev/null +++ b/llvm/test/MC/RISCV/xqcisls-valid.s @@ -0,0 +1,43 @@ +# Xqcisls - Qualcomm uC Scaled Load Store Extension +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcisls -M no-aliases --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqcisls --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# CHECK-INST: qc.lrb t0, sp, tp, 4 +# CHECK-ENC: encoding: [0x8b,0x72,0x41,0x88] +qc.lrb x5, x2, x4, 4 + +# CHECK-INST: qc.lrh ra, a2, t1, 2 +# CHECK-ENC: encoding: [0x8b,0x70,0x66,0x94] +qc.lrh x1, x12, x6, 2 + +# CHECK-INST: qc.lrw a5, t2, a4, 1 +# CHECK-ENC: encoding: [0x8b,0xf7,0xe3,0xa2] +qc.lrw x15, x7, x14, 1 + +# CHECK-INST: qc.lrbu s1, a1, tp, 7 +# CHECK-ENC: encoding: [0x8b,0xf4,0x45,0xbe] +qc.lrbu x9, x11, x4, 7 + +# CHECK-INST: qc.lrhu a6, t1, a0, 4 +# CHECK-ENC: encoding: [0x0b,0x78,0xa3,0xc8] +qc.lrhu x16, x6, x10, 4 + +# CHECK-INST: qc.srb zero, sp, s0, 3 +# CHECK-ENC: encoding: [0x2b,0x60,0x81,0xd6] +qc.srb x0, x2, x8, 3 + +# CHECK-INST: qc.srh a3, zero, s4, 6 +# CHECK-ENC: encoding: [0xab,0x66,0x40,0xed] +qc.srh x13, x0, x20, 6 + +# CHECK-INST: qc.srw a7, s2, s3, 0 +# CHECK-ENC: encoding: [0xab,0x68,0x39,0xf1] +qc.srw x17, x18, x19, 0 diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index 4b450e23627168..23f1d832773ccf 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -652,6 +652,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) { EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), "'xwchc' and 'zcb' extensions are incompatible"); } + + for (StringRef Input : {"rv64i_xqcisls0p2"}) { + EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), + "'xqcisls' is only supported for 'rv32'"); + } } TEST(ParseArchString, MissingDepency) { @@ -1105,6 +1110,7 @@ Experimental extensions ssctr 1.0 svukte 0.3 xqcicsr 0.2 + xqcisls 0.2 Supported Profiles rva20s64 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits