mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 23:36:06 +00:00
[RISCV][MC] Add support for RV64E
Implement MC support for the recently ratified RV64E base instruction set. Differential Revision: https://reviews.llvm.org/D143570
This commit is contained in:
parent
6aa7cc037f
commit
c39dd7c1db
@ -198,11 +198,6 @@
|
||||
|
||||
// Testing specific messages and unsupported extensions.
|
||||
|
||||
// RUN: %clang --target=riscv64-unknown-elf -march=rv64e -### %s \
|
||||
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV64E %s
|
||||
// RV64E: error: invalid arch name 'rv64e',
|
||||
// RV64E: standard user-level extension 'e' requires 'rv32'
|
||||
|
||||
// RUN: %clang --target=riscv32-unknown-elf -march=rv32imC -### %s \
|
||||
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-LOWER %s
|
||||
// RV32-LOWER: error: invalid arch name 'rv32imC',
|
||||
@ -223,11 +218,6 @@
|
||||
// RV32-ORDER: error: invalid arch name 'rv32imcq',
|
||||
// RV32-ORDER: standard user-level extension not given in canonical order 'q'
|
||||
|
||||
// RUN: %clang --target=riscv32-unknown-elf -march=rv64e -### %s \
|
||||
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV64-EER %s
|
||||
// RV64-EER: error: invalid arch name 'rv64e',
|
||||
// RV64-EER: standard user-level extension 'e' requires 'rv32'
|
||||
|
||||
// RUN: %clang --target=riscv32-unknown-elf -march=rv32izve32f -### %s \
|
||||
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ZVE32F-ER %s
|
||||
// RV32-ZVE32F-ER: error: invalid arch name 'rv32izve32f',
|
||||
|
@ -33,10 +33,6 @@
|
||||
// DEFAULT-LINUX-SAME: "-target-feature" "+d"
|
||||
// DEFAULT-LINUX-SAME: "-target-feature" "+c"
|
||||
|
||||
// RUN: not %clang -cc1 -triple riscv64-unknown-elf -target-feature +e 2>&1 | FileCheck %s -check-prefix=RV64-WITH-E
|
||||
|
||||
// RV64-WITH-E: error: invalid feature combination: standard user-level extension 'e' requires 'rv32'
|
||||
|
||||
// RUN: not %clang -c --target=riscv64-linux-gnu -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
|
||||
// RUN: not %clang -c --target=riscv64 -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
|
||||
// RUN: %clang -### -c --target=riscv64 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
|
||||
|
@ -15,9 +15,9 @@ supported variations of the RISC-V specification. It lives in the
|
||||
Base ISAs
|
||||
=========
|
||||
|
||||
The specification defines four base instruction sets: RV32I, RV32E, RV64I,
|
||||
and RV128I. Currently, LLVM fully supports RV32I, and RV64I. RV32E is
|
||||
supported by the assembly-based tools only. RV128I is not supported.
|
||||
The specification defines five base instruction sets: RV32I, RV32E, RV64I,
|
||||
RV64E, and RV128I. Currently, LLVM fully supports RV32I, and RV64I. RV32E and
|
||||
RV64E are supported by the assembly-based tools only. RV128I is not supported.
|
||||
|
||||
To specify the target triple:
|
||||
|
||||
@ -27,7 +27,7 @@ To specify the target triple:
|
||||
Architecture Description
|
||||
============ ==============================================================
|
||||
``riscv32`` RISC-V with XLEN=32 (i.e. RV32I or RV32E)
|
||||
``riscv64`` RISC-V with XLEN=64 (i.e. RV64I)
|
||||
``riscv64`` RISC-V with XLEN=64 (i.e. RV64I or RV64E)
|
||||
============ ==============================================================
|
||||
|
||||
To select an E variant ISA (e.g. RV32E instead of RV32I), use the base
|
||||
|
@ -144,6 +144,7 @@ Changes to the RISC-V Backend
|
||||
* Adds support for the vendor-defined XTHeadCmo (cache management operations) extension.
|
||||
* Adds support for the vendor-defined XTHeadSync (multi-core synchronization instructions) extension.
|
||||
* Added support for the vendor-defined XTHeadFMemIdx (indexed memory operations for floating point) extension.
|
||||
* Assembler support for RV64E was added.
|
||||
|
||||
Changes to the WebAssembly Backend
|
||||
----------------------------------
|
||||
|
@ -584,8 +584,9 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
|
||||
bool HasRV64 = Arch.startswith("rv64");
|
||||
// ISA string must begin with rv32 or rv64.
|
||||
if (!(Arch.startswith("rv32") || HasRV64) || (Arch.size() < 5)) {
|
||||
return createStringError(errc::invalid_argument,
|
||||
"string must begin with rv32{i,e,g} or rv64{i,g}");
|
||||
return createStringError(
|
||||
errc::invalid_argument,
|
||||
"string must begin with rv32{i,e,g} or rv64{i,e,g}");
|
||||
}
|
||||
|
||||
unsigned XLen = HasRV64 ? 64 : 32;
|
||||
@ -601,14 +602,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
|
||||
default:
|
||||
return createStringError(errc::invalid_argument,
|
||||
"first letter should be 'e', 'i' or 'g'");
|
||||
case 'e': {
|
||||
// Extension 'e' is not allowed in rv64.
|
||||
if (HasRV64)
|
||||
return createStringError(
|
||||
errc::invalid_argument,
|
||||
"standard user-level extension 'e' requires 'rv32'");
|
||||
break;
|
||||
}
|
||||
case 'e':
|
||||
case 'i':
|
||||
break;
|
||||
case 'g':
|
||||
@ -828,8 +822,6 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
|
||||
}
|
||||
|
||||
Error RISCVISAInfo::checkDependency() {
|
||||
bool IsRv32 = XLen == 32;
|
||||
bool HasE = Exts.count("e") != 0;
|
||||
bool HasD = Exts.count("d") != 0;
|
||||
bool HasF = Exts.count("f") != 0;
|
||||
bool HasZfinx = Exts.count("zfinx") != 0;
|
||||
@ -839,11 +831,6 @@ Error RISCVISAInfo::checkDependency() {
|
||||
bool HasZve64d = Exts.count("zve64d") != 0;
|
||||
bool HasZvl = MinVLen != 0;
|
||||
|
||||
if (HasE && !IsRv32)
|
||||
return createStringError(
|
||||
errc::invalid_argument,
|
||||
"standard user-level extension 'e' requires 'rv32'");
|
||||
|
||||
if (HasF && HasZfinx)
|
||||
return createStringError(errc::invalid_argument,
|
||||
"'f' and 'zfinx' extensions are incompatible");
|
||||
@ -1115,6 +1102,8 @@ StringRef RISCVISAInfo::computeDefaultABI() const {
|
||||
} else if (XLen == 64) {
|
||||
if (hasExtension("d"))
|
||||
return "lp64d";
|
||||
if (hasExtension("e"))
|
||||
return "lp64e";
|
||||
return "lp64";
|
||||
}
|
||||
llvm_unreachable("Invalid XLEN");
|
||||
|
@ -67,7 +67,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
|
||||
|
||||
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
|
||||
bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
|
||||
bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
|
||||
bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureRVE); }
|
||||
|
||||
RISCVTargetStreamer &getTargetStreamer() {
|
||||
assert(getParser().getStreamer().getTargetStreamer() &&
|
||||
@ -1352,9 +1352,9 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
|
||||
// Attempts to match Name as a register (either using the default name or
|
||||
// alternative ABI names), setting RegNo to the matching register. Upon
|
||||
// failure, returns true and sets RegNo to 0. If IsRV32E then registers
|
||||
// failure, returns true and sets RegNo to 0. If IsRVE then registers
|
||||
// x16-x31 will be rejected.
|
||||
static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo,
|
||||
static bool matchRegisterNameHelper(bool IsRVE, MCRegister &RegNo,
|
||||
StringRef Name) {
|
||||
RegNo = MatchRegisterName(Name);
|
||||
// The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
|
||||
@ -1366,7 +1366,7 @@ static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo,
|
||||
static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
|
||||
if (RegNo == RISCV::NoRegister)
|
||||
RegNo = MatchRegisterAltName(Name);
|
||||
if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
|
||||
if (IsRVE && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
|
||||
RegNo = RISCV::NoRegister;
|
||||
return RegNo == RISCV::NoRegister;
|
||||
}
|
||||
@ -1387,7 +1387,7 @@ OperandMatchResultTy RISCVAsmParser::tryParseRegister(MCRegister &RegNo,
|
||||
RegNo = 0;
|
||||
StringRef Name = getLexer().getTok().getIdentifier();
|
||||
|
||||
if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name))
|
||||
if (matchRegisterNameHelper(isRVE(), (MCRegister &)RegNo, Name))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
getParser().Lex(); // Eat identifier token.
|
||||
@ -1420,7 +1420,7 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
|
||||
case AsmToken::Identifier:
|
||||
StringRef Name = getLexer().getTok().getIdentifier();
|
||||
MCRegister RegNo;
|
||||
matchRegisterNameHelper(isRV32E(), RegNo, Name);
|
||||
matchRegisterNameHelper(isRVE(), RegNo, Name);
|
||||
|
||||
if (RegNo == RISCV::NoRegister) {
|
||||
if (HadParens)
|
||||
@ -1908,7 +1908,7 @@ OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
MCRegister RegNo;
|
||||
matchRegisterNameHelper(isRV32E(), RegNo, Name);
|
||||
matchRegisterNameHelper(isRVE(), RegNo, Name);
|
||||
|
||||
if (RegNo == RISCV::NoRegister)
|
||||
return MatchOperand_NoMatch;
|
||||
@ -1927,7 +1927,7 @@ OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
|
||||
|
||||
StringRef Name = getLexer().getTok().getIdentifier();
|
||||
MCRegister RegNo;
|
||||
matchRegisterNameHelper(isRV32E(), RegNo, Name);
|
||||
matchRegisterNameHelper(isRVE(), RegNo, Name);
|
||||
|
||||
if (RegNo == RISCV::NoRegister)
|
||||
return MatchOperand_NoMatch;
|
||||
|
@ -61,9 +61,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
|
||||
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
bool IsRV32E = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureRV32E);
|
||||
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureRVE);
|
||||
|
||||
if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
|
||||
if (RegNo >= 32 || (IsRVE && RegNo >= 16))
|
||||
return MCDisassembler::Fail;
|
||||
|
||||
MCRegister Reg = RISCV::X0 + RegNo;
|
||||
|
@ -40,7 +40,7 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
|
||||
StringRef ABIName) {
|
||||
auto TargetABI = getTargetABI(ABIName);
|
||||
bool IsRV64 = TT.isArch64Bit();
|
||||
bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
|
||||
bool IsRVE = FeatureBits[RISCV::FeatureRVE];
|
||||
|
||||
if (!ABIName.empty() && TargetABI == ABI_Unknown) {
|
||||
errs()
|
||||
@ -54,11 +54,18 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
|
||||
errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring "
|
||||
"target-abi)\n";
|
||||
TargetABI = ABI_Unknown;
|
||||
} else if (IsRV32E && TargetABI != ABI_ILP32E && TargetABI != ABI_Unknown) {
|
||||
} else if (!IsRV64 && IsRVE && TargetABI != ABI_ILP32E &&
|
||||
TargetABI != ABI_Unknown) {
|
||||
// TODO: move this checking to RISCVTargetLowering and RISCVAsmParser
|
||||
errs()
|
||||
<< "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n";
|
||||
TargetABI = ABI_Unknown;
|
||||
} else if (IsRV64 && IsRVE && TargetABI != ABI_LP64E &&
|
||||
TargetABI != ABI_Unknown) {
|
||||
// TODO: move this checking to RISCVTargetLowering and RISCVAsmParser
|
||||
errs()
|
||||
<< "Only the lp64e ABI is supported for RV64E (ignoring target-abi)\n";
|
||||
TargetABI = ABI_Unknown;
|
||||
}
|
||||
|
||||
if (TargetABI != ABI_Unknown)
|
||||
@ -80,6 +87,7 @@ ABI getTargetABI(StringRef ABIName) {
|
||||
.Case("lp64", ABI_LP64)
|
||||
.Case("lp64f", ABI_LP64F)
|
||||
.Case("lp64d", ABI_LP64D)
|
||||
.Case("lp64e", ABI_LP64E)
|
||||
.Default(ABI_Unknown);
|
||||
return TargetABI;
|
||||
}
|
||||
@ -101,8 +109,6 @@ void validate(const Triple &TT, const FeatureBitset &FeatureBits) {
|
||||
report_fatal_error("RV64 target requires an RV64 CPU");
|
||||
if (!TT.isArch64Bit() && !FeatureBits[RISCV::Feature32Bit])
|
||||
report_fatal_error("RV32 target requires an RV32 CPU");
|
||||
if (TT.isArch64Bit() && FeatureBits[RISCV::FeatureRV32E])
|
||||
report_fatal_error("RV32E can't be enabled for an RV64 target");
|
||||
if (FeatureBits[RISCV::Feature32Bit] &&
|
||||
FeatureBits[RISCV::Feature64Bit])
|
||||
report_fatal_error("RV32 and RV64 can't be combined");
|
||||
|
@ -408,6 +408,7 @@ enum ABI {
|
||||
ABI_LP64,
|
||||
ABI_LP64F,
|
||||
ABI_LP64D,
|
||||
ABI_LP64E,
|
||||
ABI_Unknown
|
||||
};
|
||||
|
||||
|
@ -103,6 +103,7 @@ void RISCVTargetELFStreamer::finish() {
|
||||
EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
|
||||
break;
|
||||
case RISCVABI::ABI_ILP32E:
|
||||
case RISCVABI::ABI_LP64E:
|
||||
EFlags |= ELF::EF_RISCV_RVE;
|
||||
break;
|
||||
case RISCVABI::ABI_Unknown:
|
||||
|
@ -47,10 +47,10 @@ void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) {
|
||||
}
|
||||
|
||||
void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
|
||||
if (STI.hasFeature(RISCV::FeatureRV32E))
|
||||
emitAttribute(RISCVAttrs::STACK_ALIGN, RISCVAttrs::ALIGN_4);
|
||||
else
|
||||
emitAttribute(RISCVAttrs::STACK_ALIGN, RISCVAttrs::ALIGN_16);
|
||||
if (STI.hasFeature(RISCV::FeatureRVE))
|
||||
report_fatal_error("Codegen not yet implemented for RVE");
|
||||
|
||||
emitAttribute(RISCVAttrs::STACK_ALIGN, RISCVAttrs::ALIGN_16);
|
||||
|
||||
auto ParseResult = RISCVFeatures::parseFeatureBits(
|
||||
STI.hasFeature(RISCV::Feature64Bit), STI.getFeatureBits());
|
||||
|
@ -589,11 +589,11 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
|
||||
defvar RV32 = DefaultMode;
|
||||
def RV64 : HwMode<"+64bit", [IsRV64]>;
|
||||
|
||||
def FeatureRV32E
|
||||
: SubtargetFeature<"e", "IsRV32E", "true",
|
||||
"Implements RV32E (provides 16 rather than 32 GPRs)">;
|
||||
def IsRV32E : Predicate<"Subtarget->isRV32E()">,
|
||||
AssemblerPredicate<(all_of FeatureRV32E)>;
|
||||
def FeatureRVE
|
||||
: SubtargetFeature<"e", "IsRVE", "true",
|
||||
"Implements RV{32,64}E (provides 16 rather than 32 GPRs)">;
|
||||
def IsRVE : Predicate<"Subtarget->isRVE()">,
|
||||
AssemblerPredicate<(all_of FeatureRVE)>;
|
||||
|
||||
def FeatureRelax
|
||||
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",
|
||||
|
@ -76,8 +76,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
||||
const RISCVSubtarget &STI)
|
||||
: TargetLowering(TM), Subtarget(STI) {
|
||||
|
||||
if (Subtarget.isRV32E())
|
||||
report_fatal_error("Codegen not yet implemented for RV32E");
|
||||
if (Subtarget.isRVE())
|
||||
report_fatal_error("Codegen not yet implemented for RVE");
|
||||
|
||||
RISCVABI::ABI ABI = Subtarget.getTargetABI();
|
||||
assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
|
||||
|
@ -1,5 +0,0 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: not --crash llc -mtriple=riscv64 -mattr=+e < %s 2>&1 \
|
||||
; RUN: | FileCheck -check-prefix=RV64E %s
|
||||
|
||||
; RV64E: LLVM ERROR: RV32E can't be enabled for an RV64 target
|
@ -1,7 +0,0 @@
|
||||
; RUN: not --crash llc -mtriple=riscv32 -mattr=+e < %s 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: LLVM ERROR: Codegen not yet implemented for RV32E
|
||||
|
||||
define void @nothing() nounwind {
|
||||
ret void
|
||||
}
|
8
llvm/test/CodeGen/RISCV/rve.ll
Normal file
8
llvm/test/CodeGen/RISCV/rve.ll
Normal file
@ -0,0 +1,8 @@
|
||||
; RUN: not --crash llc -mtriple=riscv32 -mattr=+e < %s 2>&1 | FileCheck %s
|
||||
; RUN: not --crash llc -mtriple=riscv64 -mattr=+e < %s 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: LLVM ERROR: Codegen not yet implemented for RVE
|
||||
|
||||
define void @nothing() nounwind {
|
||||
ret void
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
## Arch string without version.
|
||||
|
||||
# RUN: llvm-mc %s -triple=riscv32 -filetype=asm | FileCheck %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -filetype=asm | FileCheck %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -filetype=asm \
|
||||
# RUN: | FileCheck --check-prefixes=CHECK,CHECK-RV64 %s
|
||||
|
||||
.attribute arch, "rv32i"
|
||||
# CHECK: attribute 5, "rv32i2p0"
|
||||
@ -15,6 +16,9 @@
|
||||
.attribute arch, "rv32e"
|
||||
# CHECK: attribute 5, "rv32e2p0"
|
||||
|
||||
.attribute arch, "rv64e"
|
||||
# CHECK-RV64: attribute 5, "rv64e2p0"
|
||||
|
||||
.attribute arch, "rv32i2_m2"
|
||||
# CHECK: attribute 5, "rv32i2p0_m2p0"
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
# RUN: llvm-mc -triple=riscv32 -mattr=+e -filetype=obj < %s \
|
||||
# RUN: | llvm-readobj --file-headers - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-RVE %s
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+e -filetype=obj < %s \
|
||||
# RUN: | llvm-readobj --file-headers - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-RVE %s
|
||||
# RUN: llvm-mc -triple=riscv32 -mattr=+experimental-ztso -filetype=obj < %s | llvm-readobj --file-headers - | FileCheck -check-prefixes=CHECK-TSO %s
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+experimental-ztso -filetype=obj < %s | llvm-readobj --file-headers - | FileCheck -check-prefixes=CHECK-TSO %s
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
# RUN: not llvm-mc %s -triple=riscv64 -filetype=asm 2>&1 | FileCheck %s
|
||||
|
||||
.attribute arch, "foo"
|
||||
# CHECK: [[@LINE-1]]:18: error: invalid arch name 'foo', string must begin with rv32{i,e,g} or rv64{i,g}
|
||||
# CHECK: [[@LINE-1]]:18: error: invalid arch name 'foo', string must begin with rv32{i,e,g} or rv64{i,e,g}
|
||||
|
||||
.attribute arch, "rv32i2p0_y2p0"
|
||||
# CHECK: [[@LINE-1]]:18: error: invalid arch name 'rv32i2p0_y2p0', invalid standard user-level extension 'y'
|
||||
|
@ -1,4 +0,0 @@
|
||||
# RUN: not --crash llvm-mc -triple riscv64 -mattr=+e < %s 2>&1 \
|
||||
# RUN: | FileCheck %s -check-prefix=RV64E
|
||||
|
||||
# RV64E: LLVM ERROR: RV32E can't be enabled for an RV64 target
|
@ -2,9 +2,13 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 < %s \
|
||||
# RUN: | llvm-objdump --mattr=+e -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
|
||||
# RUN: not llvm-mc -triple riscv64 -mattr=+e < %s 2>&1 | FileCheck %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 < %s \
|
||||
# RUN: | llvm-objdump --mattr=+e -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
|
||||
|
||||
# Perform a simple check that registers x16-x31 (and the equivalent ABI names)
|
||||
# are rejected for RV32E, when both assembling and disassembling.
|
||||
# are rejected for RV32E/RV64E, when both assembling and disassembling.
|
||||
|
||||
|
||||
# CHECK-DIS: 37 18 00 00 <unknown>
|
||||
|
@ -3,6 +3,11 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+e < %s \
|
||||
# RUN: | llvm-objdump -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -mattr=+e -show-encoding \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+e < %s \
|
||||
# RUN: | llvm-objdump -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
|
||||
|
||||
# This file provides a basic test for RV32E, checking that the expected
|
||||
# set of registers and instructions are accepted.
|
||||
|
36
llvm/test/MC/RISCV/rv64e-valid.s
Normal file
36
llvm/test/MC/RISCV/rv64e-valid.s
Normal file
@ -0,0 +1,36 @@
|
||||
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -mattr=+e -show-encoding \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+e < %s \
|
||||
# RUN: | llvm-objdump -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s
|
||||
|
||||
# This file provides a basic test for RV64E, checking that the expected
|
||||
# set of registers and instructions are accepted. It only tests instructions
|
||||
# that are not valid in RV32E.
|
||||
|
||||
# CHECK-ASM-AND-OBJ: ld a4, 25(a5)
|
||||
ld x14, 25(x15)
|
||||
# CHECK-ASM-AND-OBJ: sd a2, 36(a3)
|
||||
sd a2, 36(a3)
|
||||
|
||||
# CHECK-ASM-AND-OBJ: addiw a4, a5, 37
|
||||
addiw a4, a5, 37
|
||||
# CHECK-ASM-AND-OBJ: slliw t1, t1, 31
|
||||
slliw t1, t1, 31
|
||||
# CHECK-ASM-AND-OBJ: srliw a0, a4, 0
|
||||
srliw a0, a4, 0
|
||||
# CHECK-ASM-AND-OBJ: sraiw a1, sp, 15
|
||||
sraiw a1, sp, 15
|
||||
# CHECK-ASM-AND-OBJ: slliw t0, t1, 13
|
||||
slliw t0, t1, 13
|
||||
|
||||
# CHECK-ASM-AND-OBJ: addw ra, zero, zero
|
||||
addw ra, zero, zero
|
||||
# CHECK-ASM-AND-OBJ: subw t0, t2, t1
|
||||
subw t0, t2, t1
|
||||
# CHECK-ASM-AND-OBJ: sllw a5, a4, a3
|
||||
sllw a5, a4, a3
|
||||
# CHECK-ASM-AND-OBJ: srlw a0, s0, t0
|
||||
srlw a0, s0, t0
|
||||
# CHECK-ASM-AND-OBJ: sraw t0, a3, zero
|
||||
sraw t0, a3, zero
|
@ -32,6 +32,8 @@
|
||||
# RUN: | FileCheck -check-prefix=RV32EF-LP64F %s
|
||||
# RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV32EFD-LP64D %s
|
||||
# RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64e %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV32E-LP64E %s
|
||||
|
||||
# RV32I-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
# RV32IF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
@ -39,6 +41,7 @@
|
||||
# RV32E-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
# RV32EF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
# RV32EFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
# RV32E-LP64E: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
|
||||
|
||||
# RUN: llvm-mc -triple=riscv32 -target-abi ilp32f < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV32I-ILP32F %s
|
||||
@ -76,4 +79,18 @@
|
||||
# RV32EFD-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
|
||||
# RV32EFD-ILP32D: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
|
||||
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+e -target-abi lp64 < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV64EF-LP64F %s
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV64EF-LP64F %s
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV64EFD-LP64F %s
|
||||
# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64d < %s 2>&1 \
|
||||
# RUN: | FileCheck -check-prefix=RV64EFD-LP64D %s
|
||||
|
||||
# RV64E-LP64: Only the lp64e ABI is supported for RV64E (ignoring target-abi)
|
||||
# RV64EF-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi)
|
||||
# RV64EFD-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi)
|
||||
# RV64EFD-LP64D: Only the lp64e ABI is supported for RV64E (ignoring target-abi)
|
||||
|
||||
nop
|
||||
|
@ -47,6 +47,10 @@
|
||||
# RUN: | llvm-readobj --file-headers - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-RVE %s
|
||||
|
||||
# RUN: llvm-mc -triple=riscv64 -target-abi lp64e -filetype=obj < %s \
|
||||
# RUN: | llvm-readobj --file-headers - \
|
||||
# RUN: | FileCheck -check-prefix=CHECK-RVE %s
|
||||
|
||||
# CHECK-NONE: Flags [ (0x0)
|
||||
# CHECK-NONE-NEXT: ]
|
||||
|
||||
|
@ -109,7 +109,7 @@ TEST(ParseArchString, RejectsUpperCase) {
|
||||
TEST(ParseArchString, RejectsInvalidBaseISA) {
|
||||
for (StringRef Input : {"rv32", "rv64", "rv65i"}) {
|
||||
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
|
||||
"string must begin with rv32{i,e,g} or rv64{i,g}");
|
||||
"string must begin with rv32{i,e,g} or rv64{i,e,g}");
|
||||
}
|
||||
for (StringRef Input : {"rv32j", "rv64k", "rv32_i"}) {
|
||||
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
|
||||
@ -118,11 +118,9 @@ TEST(ParseArchString, RejectsInvalidBaseISA) {
|
||||
}
|
||||
|
||||
TEST(ParseArchString, RejectsUnsupportedBaseISA) {
|
||||
EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64e", true).takeError()),
|
||||
"standard user-level extension 'e' requires 'rv32'");
|
||||
for (StringRef Input : {"rv128i", "rv128g"}) {
|
||||
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
|
||||
"string must begin with rv32{i,e,g} or rv64{i,g}");
|
||||
"string must begin with rv32{i,e,g} or rv64{i,e,g}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,6 +165,15 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) {
|
||||
EXPECT_EQ(InfoRV64I.getXLen(), 64U);
|
||||
EXPECT_EQ(InfoRV64I.getFLen(), 0U);
|
||||
|
||||
auto MaybeRV64E = RISCVISAInfo::parseArchString("rv64e", true);
|
||||
ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
|
||||
RISCVISAInfo &InfoRV64E = **MaybeRV64E;
|
||||
RISCVISAInfo::OrderedExtensionMap ExtsRV64E = InfoRV64E.getExtensions();
|
||||
EXPECT_EQ(ExtsRV64E.size(), 1UL);
|
||||
EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVExtensionInfo{2, 0}));
|
||||
EXPECT_EQ(InfoRV64E.getXLen(), 64U);
|
||||
EXPECT_EQ(InfoRV64E.getFLen(), 0U);
|
||||
|
||||
auto MaybeRV64G = RISCVISAInfo::parseArchString("rv64g", true);
|
||||
ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded());
|
||||
RISCVISAInfo &InfoRV64G = **MaybeRV64G;
|
||||
|
Loading…
x
Reference in New Issue
Block a user