https://github.com/hchandel created https://github.com/llvm/llvm-project/pull/121037
This extension adds 3 instructions that perform load-store address calculation. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. >From 304147a932684d7ccc1a8343655bb64a0c7e238f Mon Sep 17 00:00:00 2001 From: Harsh Chandel <hchan...@qti.qualcomm.com> Date: Tue, 24 Dec 2024 13:00:04 +0530 Subject: [PATCH] [RISCV] Add Qualcomm uC Xqciac (Load-Store Adress calculation) extension This extension adds 3 instructions that perform load-store address calculation. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. Change-Id: I0b444c049d919b7bf350af438694c538f669a32d --- .../Driver/print-supported-extensions-riscv.c | 1 + llvm/docs/RISCVUsage.rst | 3 ++ llvm/docs/ReleaseNotes.md | 2 + .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 12 +++++ .../RISCV/Disassembler/RISCVDisassembler.cpp | 6 +++ .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 + llvm/lib/Target/RISCV/RISCVFeatures.td | 8 +++ llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 38 ++++++++++++++ llvm/lib/TargetParser/RISCVISAInfo.cpp | 2 +- llvm/test/CodeGen/RISCV/attributes.ll | 2 + llvm/test/MC/RISCV/xqciac-invalid.s | 43 ++++++++++++++++ llvm/test/MC/RISCV/xqciac-valid.s | 49 +++++++++++++++++++ .../TargetParser/RISCVISAInfoTest.cpp | 5 +- 13 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 llvm/test/MC/RISCV/xqciac-invalid.s create mode 100644 llvm/test/MC/RISCV/xqciac-valid.s diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 8344c1aa399737..8e46690cce5a63 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: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) +// CHECK-NEXT: xqciac 0.2 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) // CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR 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 f6a0dd4bf2383c..22600f5720553e 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -429,6 +429,9 @@ The current vendor extensions supported are: ``experimental-Xqcia`` LLVM implements `version 0.2 of the Qualcomm uC 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. +``experimental-Xqciac`` + LLVM implements `version 0.2 of the Qualcomm uC Load-Store Address Calculation 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-Xqcics`` LLVM implements `version 0.2 of the Qualcomm uC Conditional Select 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 2835ace34bff83..9cb8c53f6bba19 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -222,6 +222,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqciac` (Load-Store Address Calculation) + extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select) extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 9dcf2e973e6c58..4c1fd5aa41e2b7 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -734,6 +734,16 @@ struct RISCVOperand final : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_None; } + bool isUImm5GT3() const { + if (!isImm()) + return false; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + int64_t Imm; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isUInt<5>(Imm) && (Imm > 3) && + VK == RISCVMCExpr::VK_RISCV_None; + } + bool isUImm8GE32() const { int64_t Imm; RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; @@ -1520,6 +1530,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); case Match_InvalidUImm5NonZero: return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); + case Match_InvalidUImm5GT3: + return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1); case Match_InvalidUImm6: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); case Match_InvalidUImm7: diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 99017195185fd3..57443d3f38e3cb 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -692,6 +692,9 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC Conditional Select custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32, "Qualcomm uC Load Store Multiple custom opcode table"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXqciac, DecoderTableXqciac32, + "Qualcomm uC Load-Store Address Calculation custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; @@ -718,6 +721,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, TRY_TO_DECODE_FEATURE( RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16, "Zcmp table (16-bit Push/Pop & Double Move Instructions)"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXqciac, DecoderTableXqciac16, + "Qualcomm uC Load-Store Address Calculation custom 16bit opcode table"); TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc), DecoderTableXwchc16, "WCH QingKe XW custom opcode table"); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index b9f4db065f2159..7fb5fc7a831308 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -302,6 +302,7 @@ enum OperandType : unsigned { OPERAND_UIMM4, OPERAND_UIMM5, OPERAND_UIMM5_NONZERO, + OPERAND_UIMM5_GT3, OPERAND_UIMM5_LSB0, OPERAND_UIMM6, OPERAND_UIMM6_LSB0, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index dfc5658806abb8..916b140c5bde75 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1274,6 +1274,14 @@ def HasVendorXqcilsm AssemblerPredicate<(all_of FeatureVendorXqcilsm), "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">; +def FeatureVendorXqciac + : RISCVExperimentalExtension<0, 2, "Qualcomm uC Load-Store Address Calculation Extension", + [FeatureStdExtZca]>; +def HasVendorXqciac + : Predicate<"Subtarget->hasVendorXqciac()">, + AssemblerPredicate<(all_of FeatureVendorXqciac), + "'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)">; + //===----------------------------------------------------------------------===// // LLVM specific features and extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 05b559178bfe63..4b8d9d17b6ab5b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -21,6 +21,13 @@ def uimm5nonzero : RISCVOp<XLenVT>, let OperandType = "OPERAND_UIMM5_NONZERO"; } +def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT, + [{return (Imm > 3) && isUInt<5>(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<5, "GT3">; + let DecoderMethod = "decodeUImmOperand<5>"; + let OperandType = "OPERAND_UIMM5_GT3"; +} + def uimm11 : RISCVUImmLeafOp<11>; //===----------------------------------------------------------------------===// @@ -184,6 +191,37 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 } // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" +let Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac" in { +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { + def QC_C_MULADDI : RVInst16CL<0b001, 0b10, (outs GPRC:$rd_wb), + (ins GPRC:$rd, GPRC:$rs1, uimm5:$uimm), + "qc.c.muladdi", "$rd, $rs1, $uimm"> { + let Constraints = "$rd = $rd_wb"; + bits<5> uimm; + + let Inst{12-10} = uimm{3-1}; + let Inst{6} = uimm{0}; + let Inst{5} = uimm{4}; + } + + def QC_MULADDI : RVInstI<0b110, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb), + (ins GPRNoX0:$rd, GPRNoX0:$rs1, simm12:$imm12), + "qc.muladdi", "$rd, $rs1, $imm12"> { + let Constraints = "$rd = $rd_wb"; + } + + def QC_SHLADD : RVInstRBase<0b011, OPC_CUSTOM_0, (outs GPR:$rd), + (ins GPRMem:$rs1, GPRNoX0:$rs2, uimm5gt3:$shamt), + "qc.shladd", "$rd, $rs1, $rs2, $shamt"> { + bits<5> shamt; + + let Inst{31-30} = 0b01; + let Inst{29-25} = shamt; + } + +} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +} // Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac" + let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in { def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">; def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">; diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index cafc9d304e83a7..e4e459a77b5f8f 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() { bool HasZvl = MinVLen != 0; bool HasZcmt = Exts.count("zcmt") != 0; static constexpr StringLiteral XqciExts[] = { - {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}}; + {"xqcia"}, {"xqciac"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}}; if (HasI && HasE) return getIncompatibleError("i", "e"); diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index f63bc944ccf22e..3f2b2c94707835 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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciac %s -o - | FileCheck --check-prefix=RV32XQCIAC %s ; 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-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s @@ -391,6 +392,7 @@ ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0" ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2" ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2" +; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p2" ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2" ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2" ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2" diff --git a/llvm/test/MC/RISCV/xqciac-invalid.s b/llvm/test/MC/RISCV/xqciac-invalid.s new file mode 100644 index 00000000000000..4e0182aff9cc2c --- /dev/null +++ b/llvm/test/MC/RISCV/xqciac-invalid.s @@ -0,0 +1,43 @@ +# Xqciac - Qualcomm uC Load-Store Address Calculation Extension +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciac < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s +# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciac < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s + +# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction +qc.c.muladdi x5, x10, 4 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.c.muladdi x15 + +# CHECK-IMM: :[[@LINE+1]]:24: error: immediate must be an integer in the range [0, 31] +qc.c.muladdi x10, x15, 32 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.c.muladdi x10, x15, 20 + + +# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction +qc.muladdi x0, x10, 1048577 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.muladdi x10 + +# CHECK-IMM: :[[@LINE+1]]:22: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] +qc.muladdi x10, x15, 8589934592 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.muladdi x10, x15, 577 + + +# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction +qc.shladd 0, x10, 1048577 + +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +qc.shladd x10 + +# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [4, 31] +qc.shladd x10, x15, x11, 2 + +# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +qc.shladd x10, x15, x11, 5 diff --git a/llvm/test/MC/RISCV/xqciac-valid.s b/llvm/test/MC/RISCV/xqciac-valid.s new file mode 100644 index 00000000000000..6e97d8cc447e14 --- /dev/null +++ b/llvm/test/MC/RISCV/xqciac-valid.s @@ -0,0 +1,49 @@ +# Xqciac - Qualcomm uC Load-Store Address Calculation Extension +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqciac -M no-aliases --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \ +# RUN: | llvm-objdump --mattr=+experimental-xqciac --no-print-imm-hex -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# CHECK-INST: qc.c.muladdi a0, a1, 0 +# CHECK-ENC: encoding: [0x8a,0x21] +qc.c.muladdi x10, x11, 0 + +# CHECK-INST: qc.c.muladdi a0, a1, 31 +# CHECK-ENC: encoding: [0xea,0x3d] +qc.c.muladdi x10, x11, 31 + +# CHECK-INST: qc.c.muladdi a0, a1, 16 +# CHECK-ENC: encoding: [0xaa,0x21] +qc.c.muladdi x10, x11, 16 + + +# CHECK-INST: qc.muladdi tp, t0, 1234 +# CHECK-ENC: encoding: [0x0b,0xe2,0x22,0x4d] +qc.muladdi x4, x5, 1234 + +# CHECK-INST: qc.muladdi a0, a1, -2048 +# CHECK-ENC: encoding: [0x0b,0xe5,0x05,0x80] +qc.muladdi x10, x11, -2048 + +# CHECK-INST: qc.muladdi a0, a1, 2047 +# CHECK-ENC: encoding: [0x0b,0xe5,0xf5,0x7f] +qc.muladdi x10, x11, 2047 + + +# CHECK-INST: qc.shladd tp, t0, t1, 12 +# CHECK-ENC: encoding: [0x0b,0xb2,0x62,0x58] +qc.shladd x4, x5, x6, 12 + +# CHECK-INST: qc.shladd a0, a1, a2, 4 +# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x48] +qc.shladd x10, x11, x12, 4 + +# CHECK-INST: qc.shladd a0, a1, a2, 31 +# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x7e] +qc.shladd x10, x11, x12, 31 diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index ed334f00eb93a4..176cf82ac34b13 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -654,8 +654,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) { } for (StringRef Input : - {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqcicsr0p2", - "rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) { + {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2", + "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) { EXPECT_THAT( toString(RISCVISAInfo::parseArchString(Input, true).takeError()), ::testing::EndsWith(" is only supported for 'rv32'")); @@ -1113,6 +1113,7 @@ Experimental extensions ssctr 1.0 svukte 0.3 xqcia 0.2 + xqciac 0.2 xqcics 0.2 xqcicsr 0.2 xqcilsm 0.2 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits