From 444db30751380e8fe459bfeae4c5bb2a93c596eb Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 13 Aug 2026 13:10:47 +0800 Subject: [TableGen] Split the target description generator --- backend/utils/TableGen/rcc-tblgen.cpp | 110 ++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 backend/utils/TableGen/rcc-tblgen.cpp (limited to 'backend/utils/TableGen/rcc-tblgen.cpp') diff --git a/backend/utils/TableGen/rcc-tblgen.cpp b/backend/utils/TableGen/rcc-tblgen.cpp new file mode 100644 index 0000000..3e4e093 --- /dev/null +++ b/backend/utils/TableGen/rcc-tblgen.cpp @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "TableGenBackends.h" +#include "rcc/Support/TextDiagnostic.h" + +#include +#include +#include +#include +#include +#include + +namespace { + +struct CommandLine final { + std::string InputPath; + std::string RegisterHeaderPath; + std::string InstructionHeaderPath; + std::string TablesPath; +}; + +[[nodiscard]] bool parseCommandLine(int ArgumentCount, char *Arguments[], CommandLine &Result) { + for (int Index = 1; Index < ArgumentCount; ++Index) { + const std::string_view Argument(Arguments[Index]); + if (Argument == "--input" || Argument == "--register-header" || + Argument == "--instruction-header" || Argument == "--tables") { + if (Index + 1 >= ArgumentCount) { + std::cerr << "rcc-tblgen: missing value for " << Argument << '\n'; + return false; + } + std::string *Destination = nullptr; + if (Argument == "--input") + Destination = &Result.InputPath; + else if (Argument == "--register-header") + Destination = &Result.RegisterHeaderPath; + else if (Argument == "--instruction-header") + Destination = &Result.InstructionHeaderPath; + else + Destination = &Result.TablesPath; + *Destination = Arguments[++Index]; + continue; + } + std::cerr << "rcc-tblgen: unknown argument '" << Argument << "'\n"; + return false; + } + if (!Result.InputPath.empty() && !Result.RegisterHeaderPath.empty() && + !Result.InstructionHeaderPath.empty() && !Result.TablesPath.empty()) { + return true; + } + std::cerr << "usage: rcc-tblgen --input --register-header " + "--instruction-header --tables \n"; + return false; +} + +[[nodiscard]] bool writeFile(const std::filesystem::path &Path, std::string_view Contents) { + std::error_code Error; + std::filesystem::create_directories(Path.parent_path(), Error); + if (Error) { + std::cerr << "rcc-tblgen: cannot create output directory for '" << Path.string() + << "': " << Error.message() << '\n'; + return false; + } + std::ofstream Output(Path, std::ios::binary | std::ios::trunc); + if (!Output) { + std::cerr << "rcc-tblgen: cannot open output '" << Path.string() << "'\n"; + return false; + } + Output.write(Contents.data(), static_cast(Contents.size())); + if (Output) { + Output.close(); + return true; + } + std::cerr << "rcc-tblgen: cannot write output '" << Path.string() << "'\n"; + return false; +} + +} // namespace + +int main(int ArgumentCount, char *Arguments[]) { + CommandLine Command; + if (!parseCommandLine(ArgumentCount, Arguments, Command)) + return 1; + + std::ifstream Input(Command.InputPath, std::ios::binary); + if (!Input) { + std::cerr << "rcc-tblgen: cannot open input '" << Command.InputPath << "'\n"; + return 1; + } + const std::string SourceText{std::istreambuf_iterator(Input), + std::istreambuf_iterator()}; + const rcc::targetgen::DescriptionGenerationResult Result = + rcc::targetgen::generateDescription(Command.InputPath, SourceText); + if (!Result.succeeded()) { + const rcc::TextSource Source(Command.InputPath, SourceText); + for (const rcc::TextDiagnostic &Diagnostic : Result.Diagnostics) + std::cerr << rcc::formatTextDiagnostic(Diagnostic, Source) << '\n'; + return 1; + } + + if (!Result.Output) { + std::cerr << "rcc-tblgen: successful generation produced no output\n"; + return 1; + } + const rcc::targetgen::GeneratedDescription &Output = Result.Output.value(); + return writeFile(Command.RegisterHeaderPath, Output.RegisterHeader) && + writeFile(Command.InstructionHeaderPath, Output.InstructionHeader) && + writeFile(Command.TablesPath, Output.TargetTables) + ? 0 + : 1; +} -- cgit v1.2.3