summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp13
-rw-r--r--llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp8
-rw-r--r--llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h1
-rw-r--r--llvm/lib/Target/RISCV/RISCV.td6
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp3
-rw-r--r--llvm/lib/Target/RISCV/RISCVSubtarget.cpp1
-rw-r--r--llvm/lib/Target/RISCV/RISCVSubtarget.h2
-rw-r--r--llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp40
-rw-r--r--llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h8
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
OpenPOWER on IntegriCloud