aboutsummaryrefslogtreecommitdiff
path: root/backend/utils/TableGen/MCPseudoLoweringEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/utils/TableGen/MCPseudoLoweringEmitter.cpp')
-rw-r--r--backend/utils/TableGen/MCPseudoLoweringEmitter.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/backend/utils/TableGen/MCPseudoLoweringEmitter.cpp b/backend/utils/TableGen/MCPseudoLoweringEmitter.cpp
new file mode 100644
index 0000000..5afa911
--- /dev/null
+++ b/backend/utils/TableGen/MCPseudoLoweringEmitter.cpp
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "TableGenBackends.h"
+
+#include <cstddef>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <string_view>
+
+namespace rcc::targetgen {
+
+std::string emitMCPseudoLowering(const NormalizedTargetModel &Model, std::string_view SourceName) {
+ std::ostringstream Output;
+ Output << "// SPDX-License-Identifier: GPL-3.0-or-later\n\n";
+ Output << "// This file is generated by rcc-tblgen from ";
+ appendQuoted(Output, SourceName);
+ Output << ". Do not edit it manually.\n\n";
+ Output << "#ifdef GET_MC_PSEUDO_LOWERING\n\n";
+ Output << "[[nodiscard]] Expected<std::optional<mc::MCInst>>\n"
+ "lowerGeneratedMCPseudo(const MachineInstr &Instruction,\n"
+ " MachineMCContext &Context) {\n"
+ " switch (Instruction.opcode().value()) {\n"
+ " default:\n"
+ " return std::optional<mc::MCInst>{};\n";
+ for (const NormalizedMCPseudoExpansion &Expansion : Model.MCPseudoExpansions) {
+ Output << " case " << Expansion.PseudoOpcode << ": {\n"
+ << " mc::MCInst Result(mc::MCOpcode::fromValue(" << Expansion.ResultOpcode
+ << "));\n"
+ " Result.setFlags(Instruction.flags().rawValue());\n"
+ " Result.setSourceIdentity(Instruction.stableID().value());\n"
+ " Result.reserveOperands("
+ << Expansion.Operands.size() << ");\n";
+ for (std::size_t Index = 0; Index < Expansion.Operands.size(); ++Index) {
+ const NormalizedMCPseudoOperand &Operand = Expansion.Operands[Index];
+ switch (Operand.Kind) {
+ case NormalizedMCPseudoOperandKind::SourceOperand:
+ Output << " const MachineOperand *Operand" << Index << " = Instruction.operandAt("
+ << Operand.Value << ");\n"
+ << " if (Operand" << Index << " == nullptr)\n"
+ << " return makeUnexpected(ErrorCode::AssemblyLoweringFailed,\n"
+ " \"MC pseudo has too few operands\");\n"
+ << " auto Lowered" << Index << " =\n"
+ << " lowerOperand(*Operand" << Index
+ << ", Instruction.function(), Context);\n"
+ << " if (!Lowered" << Index << ")\n"
+ << " return std::unexpected(Lowered" << Index << ".error());\n"
+ << " Result.addOperand(std::move(*Lowered" << Index << "));\n";
+ break;
+ case NormalizedMCPseudoOperandKind::Register:
+ Output << " Result.addOperand(mc::MCOperand::registerOperand(\n"
+ " mc::MCRegister::fromValue("
+ << Operand.Value << ")));\n";
+ break;
+ case NormalizedMCPseudoOperandKind::Immediate:
+ Output << " Result.addOperand(mc::MCOperand::immediate(" << Operand.Immediate << "));\n";
+ break;
+ }
+ }
+ Output << " return std::optional<mc::MCInst>{std::move(Result)};\n"
+ " }\n";
+ }
+ Output << " }\n"
+ "}\n\n"
+ "#endif // GET_MC_PSEUDO_LOWERING\n";
+ return Output.str();
+}
+
+} // namespace rcc::targetgen