blob: 5afa911a1477ffcae0428c0ef8a99f8bd7f00224 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
|