diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -15,8 +15,8 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include using namespace clang; diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -17,8 +17,8 @@ #include "llvm/Support/Error.h" #include "llvm/Support/Host.h" #include "llvm/Support/RISCVISAInfo.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/RISCVTargetParser.h" using namespace clang::driver; using namespace clang::driver::tools; diff --git a/llvm/include/llvm/CMakeLists.txt b/llvm/include/llvm/CMakeLists.txt --- a/llvm/include/llvm/CMakeLists.txt +++ b/llvm/include/llvm/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(IR) add_subdirectory(Support) add_subdirectory(Frontend) +add_subdirectory(TargetParser) # If we're doing an out-of-tree build, copy a module map for generated # header files into the build area. diff --git a/llvm/include/llvm/TargetParser/CMakeLists.txt b/llvm/include/llvm/TargetParser/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/TargetParser/CMakeLists.txt @@ -0,0 +1,4 @@ +set(LLVM_TARGET_DEFINITIONS ${CMAKE_SOURCE_DIR}/lib/Target/RISCV/RISCV.td) +tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${CMAKE_SOURCE_DIR}/lib/Target/RISCV/) +add_public_tablegen_target(RISCVTargetParserTableGen) + diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -0,0 +1,50 @@ +//===-- RISCVTargetParser - Parser for target features ----------*- C++ -*-===// +// +// 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 implements a target parser to recognise hardware features +// FOR RISC-V CPUS. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGETPARSER_RISCVTARGETPARSER_H +#define LLVM_TARGETPARSER_RISCVTARGETPARSER_H + +#include "llvm/ADT/StringRef.h" +#include + +namespace llvm { +namespace RISCV { + +// We use 64 bits as the known part in the scalable vector types. +static constexpr unsigned RVVBitsPerBlock = 64; + +enum CPUKind : unsigned { +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM, +#define TUNE_PROC(ENUM, NAME) CK_##ENUM, +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +}; + +enum FeatureKind : unsigned { + FK_INVALID = 0, + FK_NONE = 1, + FK_64BIT = 1 << 2, +}; + +bool checkCPUKind(CPUKind Kind, bool IsRV64); +bool checkTuneCPUKind(CPUKind Kind, bool IsRV64); +CPUKind parseCPUKind(StringRef CPU); +CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64); +StringRef getMArchFromMcpu(StringRef CPU); +void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64); +void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64); +bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector &Features); + +} // namespace RISCV +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.def b/llvm/include/llvm/TargetParser/RISCVTargetParser.def deleted file mode 100644 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.def +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef PROC -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) -#endif - -PROC(INVALID, {"invalid"}, FK_INVALID, {""}) -PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""}) -PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""}) -PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""}) -PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""}) -PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"}) -PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"}) -PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"}) -PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"}) -PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"}) -PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"}) -PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"}) -PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"}) -PROC(SYNTACORE_SCR1_BASE, {"syntacore-scr1-base"}, FK_NONE, {"rv32ic"}) -PROC(SYNTACORE_SCR1_MAX, {"syntacore-scr1-max"}, FK_NONE, {"rv32imc"}) - -#undef PROC - -#ifndef TUNE_PROC -#define TUNE_PROC(ENUM, NAME) -#endif - -TUNE_PROC(GENERIC, "generic") -TUNE_PROC(ROCKET, "rocket") -TUNE_PROC(SIFIVE_7, "sifive-7-series") - -#undef TUNE_PROC diff --git a/llvm/include/llvm/TargetParser/TargetParser.h b/llvm/include/llvm/TargetParser/TargetParser.h --- a/llvm/include/llvm/TargetParser/TargetParser.h +++ b/llvm/include/llvm/TargetParser/TargetParser.h @@ -154,34 +154,6 @@ IsaVersion getIsaVersion(StringRef GPU); } // namespace AMDGPU - -namespace RISCV { - -// We use 64 bits as the known part in the scalable vector types. -static constexpr unsigned RVVBitsPerBlock = 64; - -enum CPUKind : unsigned { -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM, -#define TUNE_PROC(ENUM, NAME) CK_##ENUM, -#include "RISCVTargetParser.def" -}; - -enum FeatureKind : unsigned { - FK_INVALID = 0, - FK_NONE = 1, - FK_64BIT = 1 << 2, -}; - -bool checkCPUKind(CPUKind Kind, bool IsRV64); -bool checkTuneCPUKind(CPUKind Kind, bool IsRV64); -CPUKind parseCPUKind(StringRef CPU); -CPUKind parseTuneCPUKind(StringRef CPU, bool IsRV64); -StringRef getMArchFromMcpu(StringRef CPU); -void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64); -void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64); -bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector &Features); - -} // namespace RISCV } // namespace llvm #endif diff --git a/llvm/include/llvm/module.extern.modulemap b/llvm/include/llvm/module.extern.modulemap --- a/llvm/include/llvm/module.extern.modulemap +++ b/llvm/include/llvm/module.extern.modulemap @@ -3,3 +3,4 @@ module LLVM_Extern_IR_Intrinsics_Gen {} module LLVM_Extern_IR_Intrinsics_Enum {} module LLVM_Extern_Utils_DataTypes {} +module LLVM_Extern_TargetParser_Gen {} diff --git a/llvm/include/llvm/module.install.modulemap b/llvm/include/llvm/module.install.modulemap --- a/llvm/include/llvm/module.install.modulemap +++ b/llvm/include/llvm/module.install.modulemap @@ -25,3 +25,7 @@ header "Support/DataTypes.h" export * } + +module LLVM_Extern_TargetParser_Gen { + textual header "TargetParser/RISCVTargetParserDef.inc" +} diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -391,6 +391,16 @@ extern module LLVM_Extern_Utils_DataTypes "module.extern.modulemap" +// Build the module with the tablegen-generated files needed by the +// TargetParser module before building the TargetParser module itself. +module TargetParserGen { + module RISCVTargetParserDef { + header "TargetParser/RISCVTargetParser.h" + extern module LLVM_Extern_TargetParser_Gen "module.extern.modulemap" + export * + } +} + // A module covering ADT/ and Support/. These are intertwined and // codependent, and notionally form a single module. module LLVM_Utils { @@ -427,7 +437,6 @@ textual header "TargetParser/AArch64TargetParser.def" textual header "TargetParser/ARMTargetParser.def" textual header "TargetParser/CSKYTargetParser.def" - textual header "TargetParser/RISCVTargetParser.def" textual header "TargetParser/X86TargetParser.def" textual header "TargetParser/LoongArchTargetParser.def" } diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -565,99 +565,110 @@ // RISC-V processors supported. //===----------------------------------------------------------------------===// -def : ProcessorModel<"generic-rv32", NoSchedModel, [Feature32Bit]>; -def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>; +class RISCVProcessorModelPROC f, + string default_march = "", + list tunef = []> : ProcessorModel { + string DefaultMarch = default_march; +} + +class RISCVProcessorModelTUNE_PROC f, + list tunef = []> : ProcessorModel; + +def GENERIC_RV32 : RISCVProcessorModelPROC<"generic-rv32", NoSchedModel, [Feature32Bit]>; +def GENERIC_RV64 : RISCVProcessorModelPROC<"generic-rv64", NoSchedModel, [Feature64Bit]>; // Support generic for compatibility with other targets. The triple will be used // to change to the appropriate rv32/rv64 version. def : ProcessorModel<"generic", NoSchedModel, []>; -def : ProcessorModel<"rocket-rv32", RocketModel, [Feature32Bit]>; -def : ProcessorModel<"rocket-rv64", RocketModel, [Feature64Bit]>; -def : ProcessorModel<"rocket", RocketModel, []>; - -def : ProcessorModel<"sifive-7-series", SiFive7Model, [], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-e20", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e21", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e24", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e31", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e34", RocketModel, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-e76", SiFive7Model, [Feature32Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-s21", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s51", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s54", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-s76", SiFive7Model, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"sifive-u54", RocketModel, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC]>; - -def : ProcessorModel<"sifive-u74", SiFive7Model, [Feature64Bit, - FeatureStdExtM, - FeatureStdExtA, - FeatureStdExtF, - FeatureStdExtD, - FeatureStdExtC], - [TuneSiFive7]>; - -def : ProcessorModel<"syntacore-scr1-base", SyntacoreSCR1Model, - [Feature32Bit, FeatureStdExtC], - [TuneNoDefaultUnroll]>; - -def : ProcessorModel<"syntacore-scr1-max", SyntacoreSCR1Model, - [Feature32Bit, FeatureStdExtM, FeatureStdExtC], - [TuneNoDefaultUnroll]>; +def ROCKET_RV32 : RISCVProcessorModelPROC<"rocket-rv32", RocketModel, [Feature32Bit]>; +def ROCKET_RV64 : RISCVProcessorModelPROC<"rocket-rv64", RocketModel, [Feature64Bit]>; +def ROCKET : RISCVProcessorModelTUNE_PROC<"rocket", RocketModel, []>; + +def SIFIVE_7 : RISCVProcessorModelTUNE_PROC<"sifive-7-series", SiFive7Model, [], + [TuneSiFive7]>; + +def SIFIVE_E20 : RISCVProcessorModelPROC<"sifive-e20", RocketModel, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtC], "rv32imc">; + +def SIFIVE_E21 : RISCVProcessorModelPROC<"sifive-e21", RocketModel, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], "rv32imac">; + +def SIFIVE_E24 : RISCVProcessorModelPROC<"sifive-e24", RocketModel, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], "rv32imafc">; + +def SIFIVE_E31 : RISCVProcessorModelPROC<"sifive-e31", RocketModel, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], "rv32imac">; + +def SIFIVE_E34 : RISCVProcessorModelPROC<"sifive-e34", RocketModel, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], "rv32imafc">; + +def SIFIVE_E76 : RISCVProcessorModelPROC<"sifive-e76", SiFive7Model, [Feature32Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtC], + "rv32imafc", [TuneSiFive7]>; + +def SIFIVE_S21 : RISCVProcessorModelPROC<"sifive-s21", RocketModel, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], "rv64imac">; + +def SIFIVE_S51 : RISCVProcessorModelPROC<"sifive-s51", RocketModel, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtC], "rv64imac">; + +def SIFIVE_S54 : RISCVProcessorModelPROC<"sifive-s54", RocketModel, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], "rv64gc">; + +def SIFIVE_S76 : RISCVProcessorModelPROC<"sifive-s76", SiFive7Model, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc", [TuneSiFive7]>; + +def SIFIVE_U54 : RISCVProcessorModelPROC<"sifive-u54", RocketModel, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], "rv64gc">; + +def SIFIVE_U74 : RISCVProcessorModelPROC<"sifive-u74", SiFive7Model, [Feature64Bit, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC], + "rv64gc",[TuneSiFive7] >; + +def SYNTACORE_SCR1_BASE : RISCVProcessorModelPROC<"syntacore-scr1-base", SyntacoreSCR1Model, + [Feature32Bit, FeatureStdExtC], + "rv32ic", [TuneNoDefaultUnroll]>; + +def SYNTACORE_SCR1_MAX : RISCVProcessorModelPROC<"syntacore-scr1-max", SyntacoreSCR1Model, + [Feature32Bit, FeatureStdExtM, FeatureStdExtC], + "rv32imc", [TuneNoDefaultUnroll]>; //===----------------------------------------------------------------------===// // Define the RISC-V target. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -18,7 +18,7 @@ #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLowering.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include namespace llvm { diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt --- a/llvm/lib/TargetParser/CMakeLists.txt +++ b/llvm/lib/TargetParser/CMakeLists.txt @@ -1,4 +1,3 @@ - add_llvm_component_library(LLVMTargetParser AArch64TargetParser.cpp ARMTargetParserCommon.cpp @@ -7,6 +6,7 @@ Host.cpp LoongArchTargetParser.cpp RISCVISAInfo.cpp + RISCVTargetParser.cpp TargetParser.cpp Triple.cpp X86TargetParser.cpp @@ -17,4 +17,7 @@ LINK_COMPONENTS Support + + DEPENDS + RISCVTargetParserTableGen ) diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -0,0 +1,104 @@ +//===-- TargetParser - Parser for target features ---------------*- C++ -*-===// +// +// 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 implements a target parser to recognise hardware features +// FOR RISC-V CPUS. +// +//===----------------------------------------------------------------------===// + +#include "llvm/TargetParser/RISCVTargetParser.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" + +namespace llvm { +namespace RISCV { + +struct CPUInfo { + StringLiteral Name; + CPUKind Kind; + unsigned Features; + StringLiteral DefaultMarch; + bool is64Bit() const { return (Features & FK_64BIT); } +}; + +constexpr CPUInfo RISCVCPUInfo[] = { +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \ + {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH}, +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +}; + +bool checkCPUKind(CPUKind Kind, bool IsRV64) { + if (Kind == CK_INVALID) + return false; + return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; +} + +bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { + if (Kind == CK_INVALID) + return false; +#define TUNE_PROC(ENUM, NAME) \ + if (Kind == CK_##ENUM) \ + return true; +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; +} + +CPUKind parseCPUKind(StringRef CPU) { + return llvm::StringSwitch(CPU) +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + .Default(CK_INVALID); +} + +CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { + return llvm::StringSwitch(TuneCPU) +#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) +#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) +#include "llvm/TargetParser/RISCVTargetParserDef.inc" + .Default(CK_INVALID); +} + +StringRef getMArchFromMcpu(StringRef CPU) { + CPUKind Kind = parseCPUKind(CPU); + return RISCVCPUInfo[static_cast(Kind)].DefaultMarch; +} + +void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64) { + for (const auto &C : RISCVCPUInfo) { + if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) + Values.emplace_back(C.Name); + } +} + +void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64) { + for (const auto &C : RISCVCPUInfo) { + if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) + Values.emplace_back(C.Name); + } +#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); +#include "llvm/TargetParser/RISCVTargetParserDef.inc" +} + +// Get all features except standard extension feature +bool getCPUFeaturesExceptStdExt(CPUKind Kind, + std::vector &Features) { + unsigned CPUFeatures = RISCVCPUInfo[static_cast(Kind)].Features; + + if (CPUFeatures == FK_INVALID) + return false; + + if (CPUFeatures & FK_64BIT) + Features.push_back("+64bit"); + else + Features.push_back("-64bit"); + + return true; +} + +} // namespace RISCV +} // namespace llvm diff --git a/llvm/lib/TargetParser/TargetParser.cpp b/llvm/lib/TargetParser/TargetParser.cpp --- a/llvm/lib/TargetParser/TargetParser.cpp +++ b/llvm/lib/TargetParser/TargetParser.cpp @@ -251,89 +251,3 @@ return T.isAMDGCN() ? getArchNameAMDGCN(ProcKind) : getArchNameR600(ProcKind); } - -namespace llvm { -namespace RISCV { - -struct CPUInfo { - StringLiteral Name; - CPUKind Kind; - unsigned Features; - StringLiteral DefaultMarch; - bool is64Bit() const { return (Features & FK_64BIT); } -}; - -constexpr CPUInfo RISCVCPUInfo[] = { -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \ - {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH}, -#include "llvm/TargetParser/RISCVTargetParser.def" -}; - -bool checkCPUKind(CPUKind Kind, bool IsRV64) { - if (Kind == CK_INVALID) - return false; - return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; -} - -bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { - if (Kind == CK_INVALID) - return false; -#define TUNE_PROC(ENUM, NAME) if (Kind == CK_##ENUM) return true; -#include "llvm/TargetParser/RISCVTargetParser.def" - return RISCVCPUInfo[static_cast(Kind)].is64Bit() == IsRV64; -} - -CPUKind parseCPUKind(StringRef CPU) { - return llvm::StringSwitch(CPU) -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) -#include "llvm/TargetParser/RISCVTargetParser.def" - .Default(CK_INVALID); -} - -CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { - return llvm::StringSwitch(TuneCPU) -#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) -#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) -#include "llvm/TargetParser/RISCVTargetParser.def" - .Default(CK_INVALID); -} - -StringRef getMArchFromMcpu(StringRef CPU) { - CPUKind Kind = parseCPUKind(CPU); - return RISCVCPUInfo[static_cast(Kind)].DefaultMarch; -} - -void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64) { - for (const auto &C : RISCVCPUInfo) { - if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) - Values.emplace_back(C.Name); - } -} - -void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64) { - for (const auto &C : RISCVCPUInfo) { - if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) - Values.emplace_back(C.Name); - } -#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); -#include "llvm/TargetParser/RISCVTargetParser.def" -} - -// Get all features except standard extension feature -bool getCPUFeaturesExceptStdExt(CPUKind Kind, - std::vector &Features) { - unsigned CPUFeatures = RISCVCPUInfo[static_cast(Kind)].Features; - - if (CPUFeatures == FK_INVALID) - return false; - - if (CPUFeatures & FK_64BIT) - Features.push_back("+64bit"); - else - Features.push_back("-64bit"); - - return true; -} - -} // namespace RISCV -} // namespace llvm diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -45,6 +45,7 @@ CompressInstEmitter.cpp RegisterBankEmitter.cpp RegisterInfoEmitter.cpp + RISCVTargetDefEmitter.cpp SDNodeProperties.cpp SearchableTableEmitter.cpp SubtargetEmitter.cpp diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp new file mode 100644 --- /dev/null +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -0,0 +1,62 @@ +//===- RISCVTargetDefEmitter.cpp - Generate lists of RISCV CPUs -----------===// +// +// 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 tablegen backend emits the include file needed by the target +// parser to parse the RISC-V CPUs. +// +//===----------------------------------------------------------------------===// + +#include "TableGenBackends.h" +#include "llvm/TableGen/Record.h" + +using namespace llvm; + +static std::string getEnumFeatures(const Record &Rec) { + std::vector Features = Rec.getValueAsListOfDefs("Features"); + if (find_if(Features, [](const Record *R) { + return R->getName() == "Feature64Bit"; + }) != Features.end()) + return "FK_64BIT"; + + return "FK_NONE"; +} + +void llvm::EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS) { + using MapTy = std::pair>; + using RecordMap = std::map, std::less<>>; + const RecordMap &Map = RK.getDefs(); + + OS << "#ifndef PROC\n" + << "#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)\n" + << "#endif\n\n"; + + OS << "PROC(INVALID, {\"invalid\"}, FK_INVALID, {\"\"})\n"; + // Iterate on all definition records. + for (const MapTy &Def : Map) { + const Record &Rec = *(Def.second); + if (Rec.isSubClassOf("RISCVProcessorModelPROC")) + OS << "PROC(" << Rec.getName() << ", " + << "{\"" << Rec.getValueAsString("Name") << "\"}," + << getEnumFeatures(Rec) << ", " + << "{\"" << Rec.getValueAsString("DefaultMarch") << "\"})\n"; + } + OS << "\n#undef PROC\n"; + OS << "\n"; + OS << "#ifndef TUNE_PROC\n" + << "#define TUNE_PROC(ENUM, NAME)\n" + << "#endif\n\n"; + OS << "TUNE_PROC(GENERIC, \"generic\")\n"; + for (const MapTy &Def : Map) { + const Record &Rec = *(Def.second); + if (Rec.isSubClassOf("RISCVProcessorModelTUNE_PROC")) + OS << "TUNE_PROC(" << Rec.getName() << ", " + << "\"" << Rec.getValueAsString("Name") << "\")\n"; + } + + OS << "\n#undef TUNE_PROC\n"; +} diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -58,6 +58,7 @@ GenDirectivesEnumDecl, GenDirectivesEnumImpl, GenDXILOperation, + GenRISCVTargetDef, }; namespace llvm { @@ -141,8 +142,9 @@ clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl", "Generate directive related implementation code"), clEnumValN(GenDXILOperation, "gen-dxil-operation", - "Generate DXIL operation information"))); - + "Generate DXIL operation information"), + clEnumValN(GenRISCVTargetDef, "gen-riscv-target-def", + "Generate the list of CPU for RISCV"))); cl::OptionCategory PrintEnumsCat("Options for -print-enums"); cl::opt Class("class", cl::desc("Print Enum list for this class"), cl::value_desc("class name"), @@ -278,6 +280,9 @@ case GenDXILOperation: EmitDXILOperation(Records, OS); break; + case GenRISCVTargetDef: + EmitRISCVTargetDef(Records, OS); + break; } return false; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -94,7 +94,7 @@ void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS); void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS); void EmitDXILOperation(RecordKeeper &RK, raw_ostream &OS); - +void EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace #endif