diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCV.td | 6 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVSubtarget.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVSubtarget.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h | 8 |
9 files changed, 67 insertions, 15 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 4202d5bfe19..ae7b648460b 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -47,6 +47,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); } RISCVTargetStreamer &getTargetStreamer() { MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); @@ -910,11 +911,15 @@ 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. -static bool matchRegisterNameHelper(unsigned &RegNo, StringRef Name) { +// failure, returns true and sets RegNo to 0. If IsRV32E then registers +// x16-x31 will be rejected. +static bool matchRegisterNameHelper(bool IsRV32E, unsigned &RegNo, + StringRef Name) { RegNo = MatchRegisterName(Name); if (RegNo == 0) RegNo = MatchRegisterAltName(Name); + if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) + RegNo = 0; return RegNo == 0; } @@ -926,7 +931,7 @@ bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, RegNo = 0; StringRef Name = getLexer().getTok().getIdentifier(); - if (matchRegisterNameHelper(RegNo, Name)) + if (matchRegisterNameHelper(isRV32E(), RegNo, Name)) return Error(StartLoc, "invalid register name"); getParser().Lex(); // Eat identifier token. @@ -954,7 +959,7 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, case AsmToken::Identifier: StringRef Name = getLexer().getTok().getIdentifier(); unsigned RegNo; - matchRegisterNameHelper(RegNo, Name); + matchRegisterNameHelper(isRV32E(), RegNo, Name); if (RegNo == 0) { if (HadParens) diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 26d5bca8de2..0ec22fa80e1 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -69,7 +69,13 @@ static const unsigned GPRDecoderTable[] = { static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder) { - if (RegNo > array_lengthof(GPRDecoderTable)) + const FeatureBitset &FeatureBits = + static_cast<const MCDisassembler *>(Decoder) + ->getSubtargetInfo() + .getFeatureBits(); + bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; + + if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15)) return MCDisassembler::Fail; // We must define our own mapping from RegNo to register identifier. diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index 54d58480e10..248ef20f927 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -36,6 +36,7 @@ public: TargetOptions(Options) { TargetABI = RISCVABI::computeTargetABI( STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName()); + RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits()); } ~RISCVAsmBackend() override {} diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 3936da677a5..b166418a622 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -54,6 +54,12 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">, def RV64 : HwMode<"+64bit">; def RV32 : HwMode<"-64bit">; +def FeatureRV32E + : SubtargetFeature<"e", "IsRV32E", "true", + "Implements RV32E (provides 16 rather than 32 GPRs)">; +def IsRV32E : Predicate<"Subtarget->isRV32E()">, + AssemblerPredicate<"FeatureRV32E">; + def FeatureRelax : SubtargetFeature<"relax", "EnableLinkerRelax", "true", "Enable Linker relaxation.">; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 94bd948c694..12e07143b7b 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -43,6 +43,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, const RISCVSubtarget &STI) : TargetLowering(TM), Subtarget(STI) { + if (Subtarget.isRV32E()) + report_fatal_error("Codegen not yet implemented for RV32E"); + RISCVABI::ABI ABI = Subtarget.getTargetABI(); assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index 0c7355cab38..6902ed75d85 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -39,6 +39,7 @@ RISCVSubtarget &RISCVSubtarget::initializeSubtargetDependencies( } TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName); + RISCVFeatures::validate(TT, getFeatureBits()); return *this; } diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 6c10ee44fd6..106ff49f021 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -36,6 +36,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { bool HasStdExtD = false; bool HasStdExtC = false; bool HasRV64 = false; + bool IsRV32E = false; bool EnableLinkerRelax = false; unsigned XLen = 32; MVT XLenVT = MVT::i32; @@ -80,6 +81,7 @@ public: bool hasStdExtD() const { return HasStdExtD; } bool hasStdExtC() const { return HasStdExtC; } bool is64Bit() const { return HasRV64; } + bool isRV32E() const { return IsRV32E; } bool enableLinkerRelax() const { return EnableLinkerRelax; } MVT getXLenVT() const { return XLenVT; } unsigned getXLen() const { return XLen; } diff --git a/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp index bb967cb0248..bc5395768ca 100644 --- a/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp @@ -22,15 +22,18 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, .Case("lp64d", ABI_LP64D) .Default(ABI_Unknown); + bool IsRV64 = TT.isArch64Bit(); + bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; + if (!ABIName.empty() && TargetABI == ABI_Unknown) { errs() << "'" << ABIName << "' is not a recognized ABI for this target (ignoring target-abi)\n"; - } else if (ABIName.startswith("ilp32") && TT.isArch64Bit()) { + } else if (ABIName.startswith("ilp32") && IsRV64) { errs() << "32-bit ABIs are not supported for 64-bit targets (ignoring " "target-abi)\n"; TargetABI = ABI_Unknown; - } else if (ABIName.startswith("lp64") && !TT.isArch64Bit()) { + } else if (ABIName.startswith("lp64") && !IsRV64) { errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring " "target-abi)\n"; TargetABI = ABI_Unknown; @@ -44,17 +47,34 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, "doesn't support the D instruction set extension (ignoring " "target-abi)\n"; TargetABI = ABI_Unknown; + } else if (IsRV32E && TargetABI != ABI_ILP32E && TargetABI != ABI_Unknown) { + errs() + << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n"; + TargetABI = ABI_Unknown; } - // For now, default to the ilp32/lp64 if no explicit ABI is given or an - // invalid/unrecognised string is given. In the future, it might be worth - // changing this to default to ilp32f/lp64f and ilp32d/lp64d when hardware - // support for floating point is present. - if (TargetABI == ABI_Unknown) { - TargetABI = TT.isArch64Bit() ? ABI_LP64 : ABI_ILP32; - } + if (TargetABI != ABI_Unknown) + return TargetABI; - return TargetABI; + // For now, default to the ilp32/ilp32e/lp64 ABI if no explicit ABI is given + // or an invalid/unrecognised string is given. In the future, it might be + // worth changing this to default to ilp32f/lp64f and ilp32d/lp64d when + // hardware support for floating point is present. + if (IsRV32E) + return ABI_ILP32E; + if (IsRV64) + return ABI_LP64; + return ABI_ILP32; } } // namespace RISCVABI + +namespace RISCVFeatures { + +void validate(const Triple &TT, const FeatureBitset &FeatureBits) { + if (TT.isArch64Bit() && FeatureBits[RISCV::FeatureRV32E]) + report_fatal_error("RV32E can't be enabled for an RV64 target"); +} + +} // namespace RISCVFeatures + } // namespace llvm diff --git a/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h index 4ace9ddbfcd..1ccd2254f50 100644 --- a/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h @@ -172,6 +172,14 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, } // namespace RISCVABI +namespace RISCVFeatures { + +// Validates if the given combination of features are valid for the target +// triple. Exits with report_fatal_error if not. +void validate(const Triple &TT, const FeatureBitset &FeatureBits); + +} // namespace RISCVFeatures + } // namespace llvm #endif |