[llvm] 480202f - [RISCV] Add Zilsd and Zclsd Extensions (#131094)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 19 08:53:45 PDT 2025
Author: dong-miao
Date: 2025-03-19T08:53:41-07:00
New Revision: 480202f0d16f7dbc5c650aea6e8dfd9eca5b999d
URL: https://github.com/llvm/llvm-project/commit/480202f0d16f7dbc5c650aea6e8dfd9eca5b999d
DIFF: https://github.com/llvm/llvm-project/commit/480202f0d16f7dbc5c650aea6e8dfd9eca5b999d.diff
LOG: [RISCV] Add Zilsd and Zclsd Extensions (#131094)
This commit adds the Load/Store pair instructions (Zilsd) and Compressed
Load/Store pair instructions (Zclsd).
[Specification
link](https://github.com/riscv/riscv-isa-manual/blob/main/src/zilsd.adoc).
Added:
llvm/lib/Target/RISCV/RISCVInstrInfoZclsd.td
llvm/lib/Target/RISCV/RISCVInstrInfoZilsd.td
llvm/test/MC/RISCV/rv32zclsd-invalid.s
llvm/test/MC/RISCV/rv32zclsd-valid.s
llvm/test/MC/RISCV/rv32zilsd-invalid.s
llvm/test/MC/RISCV/rv32zilsd-valid.s
Modified:
clang/test/Driver/print-supported-extensions-riscv.c
clang/test/Preprocessor/riscv-target-features.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/RISCVInstrInfo.td
llvm/lib/TargetParser/RISCVISAInfo.cpp
llvm/test/CodeGen/RISCV/attributes.ll
llvm/test/MC/RISCV/attribute-arch.s
llvm/test/MC/RISCV/rv64c-valid.s
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 019106abfabc3..35de2820ef84f 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -29,6 +29,7 @@
// CHECK-NEXT: zihintntl 1.0 'Zihintntl' (Non-Temporal Locality Hints)
// CHECK-NEXT: zihintpause 2.0 'Zihintpause' (Pause Hint)
// CHECK-NEXT: zihpm 2.0 'Zihpm' (Hardware Performance Counters)
+// CHECK-NEXT: zilsd 1.0 'Zilsd' (Load/Store Pair Instructions)
// CHECK-NEXT: zimop 1.0 'Zimop' (May-Be-Operations)
// CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication)
// CHECK-NEXT: za128rs 1.0 'Za128rs' (Reservation Set Size of at Most 128 Bytes)
@@ -50,6 +51,7 @@
// CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions)
// CHECK-NEXT: zce 1.0 'Zce' (Compressed extensions for microcontrollers)
// CHECK-NEXT: zcf 1.0 'Zcf' (Compressed Single-Precision Floating-Point Instructions)
+// CHECK-NEXT: zclsd 1.0 'Zclsd' (Compressed Load/Store Pair Instructions)
// CHECK-NEXT: zcmop 1.0 'Zcmop' (Compressed May-Be-Operations)
// CHECK-NEXT: zcmp 1.0 'Zcmp' (sequenced instructions for code-size reduction)
// CHECK-NEXT: zcmt 1.0 'Zcmt' (table jump instructions for code-size reduction)
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index c219771135275..67e4dfc3db3e9 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -108,6 +108,7 @@
// CHECK-NOT: __riscv_zcd {{.*$}}
// CHECK-NOT: __riscv_zce {{.*$}}
// CHECK-NOT: __riscv_zcf {{.*$}}
+// CHECK-NOT: __riscv_zclsd {{.*$}}
// CHECK-NOT: __riscv_zcmop {{.*$}}
// CHECK-NOT: __riscv_zcmp {{.*$}}
// CHECK-NOT: __riscv_zcmt {{.*$}}
@@ -133,6 +134,7 @@
// CHECK-NOT: __riscv_zihintntl {{.*$}}
// CHECK-NOT: __riscv_zihintpause {{.*$}}
// CHECK-NOT: __riscv_zihpm {{.*$}}
+// CHECK-NOT: __riscv_zilsd {{.*$}}
// CHECK-NOT: __riscv_zimop {{.*$}}
// CHECK-NOT: __riscv_zk {{.*$}}
// CHECK-NOT: __riscv_zkn {{.*$}}
@@ -922,6 +924,11 @@
// RUN: -o - | FileCheck --check-prefix=CHECK-ZCF-EXT %s
// CHECK-ZCF-EXT: __riscv_zcf 1000000{{$}}
+// RUN: %clang --target=riscv32-unknown-linux-gnu \
+// RUN: -march=rv32i_zclsd1p0 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZCLSD-EXT %s
+// CHECK-ZCLSD-EXT: __riscv_zclsd 1000000{{$}}
+
// RUN: %clang --target=riscv32-unknown-linux-gnu \
// RUN: -march=rv32i_zcmop1p0 -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZCMOP-EXT %s
@@ -1118,6 +1125,11 @@
// RUN: -o - | FileCheck --check-prefix=CHECK-ZIHPM-EXT %s
// CHECK-ZIHPM-EXT: __riscv_zihpm 2000000{{$}}
+// RUN: %clang --target=riscv32-unknown-linux-gnu \
+// RUN: -march=rv32i_zilsd1p0 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZILSD-EXT %s
+// CHECK-ZILSD-EXT: __riscv_zilsd 1000000{{$}}
+
// RUN: %clang --target=riscv32-unknown-linux-gnu \
// RUN: -march=rv32i_zimop1p0 -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZIMOP-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index cf7be8b2c5c96..d6ac226dad5e6 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -179,6 +179,7 @@ on support follow.
``Zcb`` Supported
``Zcd`` Supported
``Zcf`` Supported
+ ``Zclsd`` Assembly Support
``Zcmop`` Supported
``Zcmp`` Supported
``Zcmt`` Assembly Support
@@ -205,6 +206,7 @@ on support follow.
``Zihintntl`` Supported
``Zihintpause`` Assembly Support
``Zihpm`` (`See Note <#riscv-i2p1-note>`__)
+ ``Zilsd`` Assembly Support
``Zimop`` Supported
``Zkn`` Supported
``Zknd`` Supported (`See note <#riscv-scalar-crypto-note2>`__)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index b191a840d9803..30d66b4a77a71 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -128,6 +128,10 @@ Changes to the RISC-V Backend
* Added non-quadratic ``log-vrgather`` cost model for ``vrgather.vv`` instruction
* Adds experimental assembler support for the Qualcomm uC 'Xqcisim` (Simulation Hint)
extension.
+* Adds assembler support for the 'Zilsd` (Load/Store Pair Instructions)
+ extension.
+* Adds assembler support for the 'Zclsd` (Compressed Load/Store Pair Instructions)
+ extension.
Changes to the WebAssembly Backend
----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 433e95d2bca19..ce25380cbdda2 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -487,6 +487,18 @@ struct RISCVOperand final : public MCParsedAsmOperand {
Reg.RegNum);
}
+ bool isGPRPairC() const {
+ return Kind == KindTy::Register &&
+ RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
+ Reg.RegNum);
+ }
+
+ bool isGPRPairNoX0() const {
+ return Kind == KindTy::Register &&
+ RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
+ Reg.RegNum);
+ }
+
bool isGPRF16() const {
return Kind == KindTy::Register &&
RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(Reg.RegNum);
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index e3c4cc36ee822..05bb6d30cc9a7 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -224,6 +224,22 @@ static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo >= 8 || RegNo % 2)
+ return MCDisassembler::Fail;
+
+ const RISCVDisassembler *Dis =
+ static_cast<const RISCVDisassembler *>(Decoder);
+ const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
+ MCRegister Reg = RI->getMatchingSuperReg(
+ RISCV::X8 + RegNo, RISCV::sub_gpr_even,
+ &RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID]);
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 74224b2e150e4..f23a855e7049f 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -176,6 +176,13 @@ def HasStdExtZicfiss : Predicate<"Subtarget->hasStdExtZicfiss()">,
"'Zicfiss' (Shadow stack)">;
def NoHasStdExtZicfiss : Predicate<"!Subtarget->hasStdExtZicfiss()">;
+def FeatureStdExtZilsd
+ : RISCVExtension<1, 0,
+ "Load/Store Pair Instructions">;
+def HasStdExtZilsd : Predicate<"Subtarget->hasStdExtZilsd()">,
+ AssemblerPredicate<(all_of FeatureStdExtZilsd),
+ "'Zilsd' (Load/Store pair instructions)">;
+
// Multiply Extensions
def FeatureStdExtZmmul
@@ -401,6 +408,14 @@ def FeatureStdExtZcf
"Compressed Single-Precision Floating-Point Instructions",
[FeatureStdExtF, FeatureStdExtZca]>;
+def FeatureStdExtZclsd
+ : RISCVExtension<1, 0,
+ "Compressed Load/Store Pair Instructions",
+ [FeatureStdExtZilsd,FeatureStdExtZca]>;
+def HasStdExtZclsd : Predicate<"Subtarget->hasStdExtZclsd()">,
+ AssemblerPredicate<(all_of FeatureStdExtZclsd),
+ "'Zclsd' (Compressed Load/Store pair instructions)">;
+
def FeatureStdExtZcmp
: RISCVExtension<1, 0,
"sequenced instructions for code-size reduction",
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 6be4fb1db602d..02398219c5105 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2144,11 +2144,13 @@ include "RISCVInstrInfoZimop.td"
include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZicfiss.td"
+include "RISCVInstrInfoZilsd.td"
// Compressed
include "RISCVInstrInfoC.td"
include "RISCVInstrInfoZc.td"
include "RISCVInstrInfoZcmop.td"
+include "RISCVInstrInfoZclsd.td"
//===----------------------------------------------------------------------===//
// Vendor extensions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZclsd.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZclsd.td
new file mode 100644
index 0000000000000..d130025b450d6
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZclsd.td
@@ -0,0 +1,107 @@
+//===-- RISCVInstrInfoZclsd.td -----------------------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instructions from the standard 'Zclsd',
+// Compressed Load/Store pair instructions extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+def GPRPairNoX0RV32Operand : AsmOperandClass {
+ let Name = "GPRPairNoX0RV32";
+ let ParserMethod = "parseGPRPair<false>";
+ let PredicateMethod = "isGPRPairNoX0";
+ let RenderMethod = "addRegOperands";
+}
+
+def GPRPairNoX0RV32 : RegisterOperand<GPRPairNoX0> {
+ let ParserMatchClass = GPRPairNoX0RV32Operand;
+}
+
+def GPRPairCRV32Operand : AsmOperandClass {
+ let Name = "GPRPairCRV32";
+ let ParserMethod = "parseGPRPair<false>";
+ let PredicateMethod = "isGPRPairC";
+ let RenderMethod = "addRegOperands";
+}
+
+def GPRPairCRV32 : RegisterOperand<GPRPairC> {
+ let ParserMatchClass = GPRPairCRV32Operand;
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class PairCStackLoad<bits<3> funct3, string OpcodeStr,
+ DAGOperand RC, DAGOperand opnd>
+ : RVInst16CI<funct3, 0b10, (outs RC:$rd), (ins SPMem:$rs1, opnd:$imm),
+ OpcodeStr, "$rd, ${imm}(${rs1})">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class PairCStackStore<bits<3> funct3, string OpcodeStr,
+ DAGOperand RC, DAGOperand opnd>
+ : RVInst16CSS<funct3, 0b10, (outs), (ins RC:$rs2, SPMem:$rs1, opnd:$imm),
+ OpcodeStr, "$rs2, ${imm}(${rs1})">;
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class PairCLoad_ri<bits<3> funct3, string OpcodeStr,
+ DAGOperand RC, DAGOperand opnd>
+ : RVInst16CL<funct3, 0b00, (outs RC:$rd), (ins GPRCMem:$rs1, opnd:$imm),
+ OpcodeStr, "$rd, ${imm}(${rs1})">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class PairCStore_rri<bits<3> funct3, string OpcodeStr,
+ DAGOperand RC, DAGOperand opnd>
+ : RVInst16CS<funct3, 0b00, (outs), (ins RC:$rs2,GPRCMem:$rs1, opnd:$imm),
+ OpcodeStr, "$rs2, ${imm}(${rs1})">;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZclsd, IsRV32], DecoderNamespace = "ZcOverlap" in {
+def C_LDSP_RV32 : PairCStackLoad<0b011, "c.ldsp", GPRPairNoX0RV32, uimm9_lsb000>,
+ Sched<[WriteLDD, ReadMemBase]> {
+ let Inst{4-2} = imm{8-6};
+}
+
+def C_SDSP_RV32 : PairCStackStore<0b111, "c.sdsp", GPRPairRV32, uimm9_lsb000>,
+ Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
+ let Inst{9-7} = imm{8-6};
+}
+
+def C_LD_RV32 : PairCLoad_ri<0b011, "c.ld", GPRPairCRV32, uimm8_lsb000>,
+ Sched<[WriteLDD, ReadMemBase]> {
+ bits<8> imm;
+ let Inst{12-10} = imm{5-3};
+ let Inst{6-5} = imm{7-6};
+}
+
+def C_SD_RV32 : PairCStore_rri<0b111, "c.sd", GPRPairCRV32, uimm8_lsb000>,
+ Sched<[WriteSTD, ReadStoreData, ReadMemBase]> {
+ bits<8> imm;
+ let Inst{12-10} = imm{5-3};
+ let Inst{6-5} = imm{7-6};
+}
+}// Predicates = [HasStdExtZclsd, IsRV32], DecoderNamespace = "ZcOverlap"
+
+//===----------------------------------------------------------------------===//
+// Compress Instruction tablegen backend.
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZclsd, IsRV32] in {
+def : CompressPat<(LD_RV32 GPRPairNoX0RV32:$rd, SPMem:$rs1, uimm9_lsb000:$imm),
+ (C_LDSP_RV32 GPRPairNoX0RV32:$rd, SPMem:$rs1, uimm9_lsb000:$imm)>;
+def : CompressPat<(SD_RV32 GPRPairRV32:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
+ (C_SDSP_RV32 GPRPairRV32:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
+def : CompressPat<(LD_RV32 GPRPairCRV32:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm),
+ (C_LD_RV32 GPRPairCRV32:$rd, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
+def : CompressPat<(SD_RV32 GPRPairCRV32:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm),
+ (C_SD_RV32 GPRPairCRV32:$rs2, GPRCMem:$rs1, uimm8_lsb000:$imm)>;
+} // Predicates = [HasStdExtZclsd, IsRV32]
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilsd.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilsd.td
new file mode 100644
index 0000000000000..a8923ae317a3f
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilsd.td
@@ -0,0 +1,38 @@
+//===-- RISCVInstrInfoZilsd.td -----------------------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instructions from the standard 'Zilsd',
+// Load/Store pair instructions extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class PairLoad_ri<string opcodestr, DAGOperand RC>
+ : RVInstI<0b011, OPC_LOAD, (outs RC:$rd),
+ (ins GPRMem:$rs1, simm12:$imm12),
+ opcodestr, "${rd}, ${imm12}(${rs1})">;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class PairStore_rri<string opcodestr, DAGOperand RC>
+ : RVInstS<0b011, OPC_STORE, (outs),
+ (ins RC:$rs2, GPRMem:$rs1, simm12:$imm12),
+ opcodestr, "${rs2}, ${imm12}(${rs1})">;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZilsd, IsRV32], DecoderNamespace = "RV32Only" in {
+def LD_RV32 : PairLoad_ri<"ld", GPRPairRV32>, Sched<[WriteLDD, ReadMemBase]>;
+def SD_RV32 : PairStore_rri<"sd", GPRPairRV32>, Sched<[WriteSTD, ReadStoreData,
+ ReadMemBase]>;
+} // Predicates = [HasStdExtZilsd, IsRV32], DecoderNamespace = "RV32Only"
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d10c334330a14..11d4b3746e94d 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -780,6 +780,14 @@ Error RISCVISAInfo::checkDependency() {
return getIncompatibleError("xwchc", "zcb");
}
+ if (Exts.count("zclsd") != 0) {
+ if (XLen != 32)
+ return getError("'zclsd' is only supported for 'rv32'");
+
+ if (Exts.count("zcf") != 0)
+ return getIncompatibleError("zclsd", "zcf");
+ }
+
for (auto Ext : XqciExts)
if (Exts.count(Ext.str()) && (XLen != 32))
return getError("'" + Twine(Ext) + "'" + " is only supported for 'rv32'");
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index a5cbc7f0cf882..344438e554ce6 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -128,7 +128,9 @@
; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+zvkt %s -o - | FileCheck --check-prefix=RV32ZVKT %s
; RUN: llc -mtriple=riscv32 -mattr=+zvfh %s -o - | FileCheck --check-prefix=RV32ZVFH %s
; RUN: llc -mtriple=riscv32 -mattr=+zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %s
+; RUN: llc -mtriple=riscv32 -mattr=+zilsd %s -o - | FileCheck --check-prefix=RV32ZILSD %s
; RUN: llc -mtriple=riscv32 -mattr=+zimop %s -o - | FileCheck --check-prefix=RV32ZIMOP %s
+; RUN: llc -mtriple=riscv32 -mattr=+zclsd %s -o - | FileCheck --check-prefix=RV32ZCLSD %s
; RUN: llc -mtriple=riscv32 -mattr=+zcmop %s -o - | FileCheck --check-prefix=RV32ZCMOP %s
; RUN: llc -mtriple=riscv32 -mattr=+smaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SMAIA %s
; RUN: llc -mtriple=riscv32 -mattr=+ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SSAIA %s
@@ -453,7 +455,9 @@
; RV32ZVKT: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvkt1p0_zvl32b1p0"
; RV32ZVFH: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0"
; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0"
+; RV32ZILSD: .attribute 5, "rv32i2p1_zilsd1p0"
; RV32ZIMOP: .attribute 5, "rv32i2p1_zimop1p0"
+; RV32ZCLSD: .attribute 5, "rv32i2p1_zilsd1p0_zca1p0_zclsd1p0"
; RV32ZCMOP: .attribute 5, "rv32i2p1_zca1p0_zcmop1p0"
; RV32SMAIA: .attribute 5, "rv32i2p1_smaia1p0"
; RV32SSAIA: .attribute 5, "rv32i2p1_ssaia1p0"
diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index a8bb9b7e6cef1..574b4cb45437e 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -255,6 +255,9 @@
.attribute arch, "rv32izcb1p0"
# CHECK: attribute 5, "rv32i2p1_zca1p0_zcb1p0"
+.attribute arch, "rv32izclsd1p0"
+# CHECK: attribute 5, "rv32i2p1_zilsd1p0_zca1p0_zclsd1p0"
+
.attribute arch, "rv32izcmp1p0"
# CHECK: attribute 5, "rv32i2p1_zca1p0_zcmp1p0"
@@ -429,6 +432,9 @@
.attribute arch, "rv32i_zicfiss1p0"
# CHECK: .attribute 5, "rv32i2p1_zicfiss1p0_zicsr2p0_zimop1p0"
+.attribute arch, "rv32i_zilsd1p0"
+# CHECK: .attribute 5, "rv32i2p1_zilsd1p0"
+
.attribute arch, "rv64i_xsfvfwmaccqqq"
# CHECK: attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin1p0_zvl32b1p0_xsfvfwmaccqqq1p0"
diff --git a/llvm/test/MC/RISCV/rv32zclsd-invalid.s b/llvm/test/MC/RISCV/rv32zclsd-invalid.s
new file mode 100644
index 0000000000000..78e391c56ab87
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zclsd-invalid.s
@@ -0,0 +1,22 @@
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zclsd < %s 2>&1 | FileCheck %s
+
+## GPRPairC
+c.ld t1, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
+c.sd s2, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
+
+## GPRPairNoX0
+c.ldsp x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+c.ldsp zero, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
+
+## uimm9_lsb000
+c.ldsp t1, 512(sp) # CHECK: :[[@LINE]]:12: error: immediate must be a multiple of 8 bytes in the range [0, 504]
+c.sdsp t1, -8(sp) # CHECK: :[[@LINE]]:12: error: immediate must be a multiple of 8 bytes in the range [0, 504]
+## uimm8_lsb000
+c.ld s0, -8(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 8 bytes in the range [0, 248]
+c.sd s0, 256(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 8 bytes in the range [0, 248]
+
+# Invalid register names
+c.ld a1, 4(sp) # CHECK: :[[@LINE]]:6: error: register must be even
+c.sd a3, 4(sp) # CHECK: :[[@LINE]]:6: error: register must be even
+c.ldsp ra, 4(sp) # CHECK: :[[@LINE]]:8: error: register must be even
+c.ldsp t0, 4(sp) # CHECK: :[[@LINE]]:8: error: register must be even
diff --git a/llvm/test/MC/RISCV/rv32zclsd-valid.s b/llvm/test/MC/RISCV/rv32zclsd-valid.s
new file mode 100644
index 0000000000000..1afe5a0b2760b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zclsd-valid.s
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zclsd -M no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zclsd< %s \
+# RUN: | llvm-objdump --mattr=+zclsd --no-print-imm-hex -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: c.ldsp t1, 176(sp)
+# CHECK-ASM: encoding: [0x4a,0x73]
+c.ldsp t1, 176(sp)
+# CHECK-ASM-AND-OBJ: c.sdsp t1, 360(sp)
+# CHECK-ASM: encoding: [0x9a,0xf6]
+c.sdsp t1, 360(sp)
+# CHECK-ASM-AND-OBJ: c.ld a4, 0(a3)
+# CHECK-ASM: encoding: [0x98,0x62]
+c.ld a4, 0(a3)
+# CHECK-ASM-AND-OBJ: c.sd s0, 248(a3)
+# CHECK-ASM: encoding: [0xe0,0xfe]
+c.sd s0, 248(a3)
diff --git a/llvm/test/MC/RISCV/rv32zilsd-invalid.s b/llvm/test/MC/RISCV/rv32zilsd-invalid.s
new file mode 100644
index 0000000000000..421358c29d68c
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zilsd-invalid.s
@@ -0,0 +1,12 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zilsd < %s 2>&1 | FileCheck %s
+
+# Out of range immediates
+## simm12
+ld t1, -2049(a0) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+sd t1, 2048(a0) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+# Invalid register names
+ld t2, (4)a0 # CHECK: :[[@LINE]]:4: error: register must be even
+ld s3, (4)a0 # CHECK: :[[@LINE]]:4: error: register must be even
+sd t2, (10)s2 # CHECK: :[[@LINE]]:4: error: register must be even
+sd a7, (10)s2 # CHECK: :[[@LINE]]:4: error: register must be even
diff --git a/llvm/test/MC/RISCV/rv32zilsd-valid.s b/llvm/test/MC/RISCV/rv32zilsd-valid.s
new file mode 100644
index 0000000000000..d9f81e6dd7fac
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zilsd-valid.s
@@ -0,0 +1,25 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zilsd -M no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zilsd < %s \
+# RUN: | llvm-objdump --mattr=+zilsd --no-print-imm-hex -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: ld t1, 12(a0)
+# CHECK-ASM: encoding: [0x03,0x33,0xc5,0x00]
+ld t1, 12(a0)
+# CHECK-ASM-AND-OBJ: ld a0, 4(a2)
+# CHECK-ASM: encoding: [0x03,0x35,0x46,0x00]
+ld a0, +4(a2)
+# CHECK-ASM-AND-OBJ: ld t1, -2048(a4)
+# CHECK-ASM: encoding: [0x03,0x33,0x07,0x80]
+ld t1, -2048(a4)
+# CHECK-ASM-AND-OBJ: ld t1, 2047(a4)
+# CHECK-ASM: encoding: [0x03,0x33,0xf7,0x7f]
+ld t1, 2047(a4)
+
+# CHECK-ASM-AND-OBJ: sd s0, 2047(a0)
+# CHECK-ASM: encoding: [0xa3,0x3f,0x85,0x7e]
+sd s0, 2047(a0)
+# CHECK-ASM-AND-OBJ: sd a0, -2048(a2)
+# CHECK-ASM: encoding: [0x23,0x30,0xa6,0x80]
+sd a0, -2048(a2)
diff --git a/llvm/test/MC/RISCV/rv64c-valid.s b/llvm/test/MC/RISCV/rv64c-valid.s
index f8736e5d5453b..9f53c6a3b4b0a 100644
--- a/llvm/test/MC/RISCV/rv64c-valid.s
+++ b/llvm/test/MC/RISCV/rv64c-valid.s
@@ -19,31 +19,29 @@
# TODO: more exhaustive testing of immediate encoding.
-# CHECK-ASM-AND-OBJ: c.ldsp ra, 0(sp)
-# CHECK-ASM: encoding: [0x82,0x60]
+# CHECK-ASM-AND-OBJ: c.ldsp s0, 0(sp)
+# CHECK-ASM: encoding: [0x02,0x64]
# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores){{$}}
-# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set{{$}}
-c.ldsp ra, 0(sp)
-# CHECK-ASM-AND-OBJ: c.sdsp ra, 504(sp)
-# CHECK-ASM: encoding: [0x86,0xff]
+# CHECK-NO-RV64: error: instruction requires the following: 'Zclsd' (Compressed Load/Store pair instructions){{$}}
+c.ldsp s0, 0(sp)
+# CHECK-ASM-AND-OBJ: c.sdsp s2, 504(sp)
+# CHECK-ASM: encoding: [0xca,0xff]
# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores){{$}}
-# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set{{$}}
-c.sdsp ra, 504(sp)
+# CHECK-NO-RV64: error: instruction requires the following: 'Zclsd' (Compressed Load/Store pair instructions){{$}}
+c.sdsp s2, 504(sp)
# CHECK-ASM-AND-OBJ: c.ld a4, 0(a3)
# CHECK-ASM: encoding: [0x98,0x62]
# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores){{$}}
-# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set{{$}}
+# CHECK-NO-RV64: error: instruction requires the following: 'Zclsd' (Compressed Load/Store pair instructions){{$}}
c.ld a4, 0(a3)
-# CHECK-ASM-AND-OBJ: c.sd a5, 248(a3)
-# CHECK-ASM: encoding: [0xfc,0xfe]
+# CHECK-ASM-AND-OBJ: c.sd a2, 248(a3)
+# CHECK-ASM: encoding: [0xf0,0xfe]
# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores){{$}}
-# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set{{$}}
-c.sd a5, 248(a3)
+# CHECK-NO-RV64: error: instruction requires the following: 'Zclsd' (Compressed Load/Store pair instructions){{$}}
+c.sd a2, 248(a3)
# CHECK-ASM-AND-OBJ: c.subw a3, a4
# CHECK-ASM: encoding: [0x99,0x9e]
-# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores){{$}}
-# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set{{$}}
c.subw a3, a4
# CHECK-ASM-AND-OBJ: c.addw a0, a2
# CHECK-ASM: encoding: [0x31,0x9d]
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 04082a89124ee..c734f8a66d289 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -653,6 +653,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
"'xwchc' and 'zcb' extensions are incompatible");
}
+ for (StringRef Input : {"rv32i_zcf_zclsd"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "'zclsd' and 'zcf' extensions are incompatible");
+ }
+
for (StringRef Input :
{"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
@@ -969,6 +974,7 @@ R"(All available -march extensions for RISC-V
zihintntl 1.0
zihintpause 2.0
zihpm 2.0
+ zilsd 1.0
zimop 1.0
zmmul 1.0
za128rs 1.0
@@ -990,6 +996,7 @@ R"(All available -march extensions for RISC-V
zcd 1.0
zce 1.0
zcf 1.0
+ zclsd 1.0
zcmop 1.0
zcmp 1.0
zcmt 1.0
More information about the llvm-commits
mailing list