// SPDX-License-Identifier: GPL-3.0-or-later #include "TableGenBackends.h" #include #include #include #include #include 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>\n" "lowerGeneratedMCPseudo(const MachineInstr &Instruction,\n" " MachineMCContext &Context) {\n" " switch (Instruction.opcode().value()) {\n" " default:\n" " return std::optional{};\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{std::move(Result)};\n" " }\n"; } Output << " }\n" "}\n\n" "#endif // GET_MC_PSEUDO_LOWERING\n"; return Output.str(); } } // namespace rcc::targetgen