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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef RCC_CODEGEN_TARGETDESCRIPTION_H
#define RCC_CODEGEN_TARGETDESCRIPTION_H
#include "rcc/CodeGen/InstructionDescriptor.h"
#include "rcc/CodeGen/TargetMIRTextInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
#include "rcc/Support/Error.h"
#include <cstdint>
#include <optional>
#include <span>
#include <utility>
#include <vector>
namespace rcc {
class MachineBasicBlock;
class MachineCFIInfo;
class MachineFrameInfo;
class MachineInstr;
class MachineMemOperand;
class MachineRegisterInfo;
struct VirtualRegisterInfo;
enum class BooleanContent : std::uint8_t {
Undefined,
ZeroOrOne,
ZeroOrNegativeOne,
};
struct TargetBooleanContentInfo final {
BooleanContent ScalarInteger = BooleanContent::Undefined;
BooleanContent ScalarFloatingPoint = BooleanContent::Undefined;
BooleanContent Vector = BooleanContent::Undefined;
};
enum class StackGrowthDirection : std::uint8_t {
Down,
Up,
};
struct TargetStackInfo final {
PhysicalRegister StackPointerRegisterToSaveRestore;
StackGrowthDirection GrowthDirection = StackGrowthDirection::Down;
};
class TargetDescription final {
public:
TargetDescription(const TargetDescription &) = delete;
TargetDescription &operator=(const TargetDescription &) = delete;
TargetDescription(TargetDescription &&) noexcept = default;
TargetDescription &operator=(TargetDescription &&) noexcept = default;
~TargetDescription() = default;
[[nodiscard]] static Expected<TargetDescription> create(InstructionSet Instructions,
TargetRegisterInfo Registers,
TargetMIRTextInfoDesc MIRText = {},
TargetBooleanContentInfo BooleanInfo = {},
TargetStackInfo StackInfo = {});
[[nodiscard]] const InstructionSet &instructions() const noexcept {
return Instructions;
}
[[nodiscard]] const TargetRegisterInfo ®isters() const noexcept {
return Registers;
}
[[nodiscard]] const TargetMIRTextInfo &mirText() const noexcept {
return MIRText;
}
[[nodiscard]] BooleanContent getBooleanContents(bool IsVector,
bool IsFloatingPoint) const noexcept {
if (IsVector)
return BooleanInfo.Vector;
return IsFloatingPoint ? BooleanInfo.ScalarFloatingPoint : BooleanInfo.ScalarInteger;
}
[[nodiscard]] PhysicalRegister stackPointerRegisterToSaveRestore() const noexcept {
return StackInfo.StackPointerRegisterToSaveRestore;
}
[[nodiscard]] StackGrowthDirection stackGrowthDirection() const noexcept {
return StackInfo.GrowthDirection;
}
[[nodiscard]] const InstructionDescriptor *
instructionDescriptor(Opcode InstructionOpcode) const noexcept {
return Instructions.descriptor(InstructionOpcode);
}
[[nodiscard]] Expected<void> validateExplicitOperands(Opcode InstructionOpcode,
std::span<const MachineOperand> Operands,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> validateOperandTies(Opcode InstructionOpcode,
std::span<const MachineOperand> ExplicitOperands,
std::span<const MachineOperandTie> Ties,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void>
validateImplicitOperands(Opcode InstructionOpcode,
std::span<const MachineOperand *const> ImplicitOperands,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void>
validateEarlyClobber(std::span<const MachineOperand> ExplicitOperands,
std::span<const MachineOperand *const> ImplicitOperands,
std::span<const MachineOperandTie> Ties) const;
[[nodiscard]] Expected<void>
validateMemOperands(Opcode InstructionOpcode,
std::span<const MachineMemOperand *const> MemOperands) const;
[[nodiscard]] Expected<void> validateInstruction(const MachineInstr &Instruction,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> validateTieCompatibility(const MachineOperand &Def,
const MachineOperand &Use,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> validateCFIInfo(const MachineCFIInfo &Info) const;
[[nodiscard]] Expected<void> validateFrameInfo(const MachineFrameInfo &Info) const;
[[nodiscard]] Expected<void> validateRegisterInfo(const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> validateBlockLiveIns(const MachineBasicBlock &Block) const;
[[nodiscard]] Expected<std::vector<MachineOperand>>
createDefaultImplicitOperands(const InstructionDescriptor &Descriptor) const {
return Instructions.createDefaultImplicitOperands(Descriptor);
}
private:
TargetDescription(InstructionSet Instructions, TargetRegisterInfo Registers,
TargetMIRTextInfo MIRText, TargetBooleanContentInfo BooleanInfo,
TargetStackInfo StackInfo)
: Instructions(std::move(Instructions)), Registers(std::move(Registers)),
MIRText(std::move(MIRText)), BooleanInfo(BooleanInfo), StackInfo(StackInfo) {}
[[nodiscard]] Expected<void> validateTargetOperand(const OperandDescriptor *Descriptor,
const MachineOperand &Operand,
const MachineRegisterInfo &RegInfo) const;
[[nodiscard]] Expected<void> validateVirtualRegister(Register Reg,
const VirtualRegisterInfo &Info) const;
[[nodiscard]] std::optional<RegisterClassID>
effectiveRegisterClass(const MachineOperand &Operand, const MachineRegisterInfo &RegInfo) const;
InstructionSet Instructions;
TargetRegisterInfo Registers;
TargetMIRTextInfo MIRText;
TargetBooleanContentInfo BooleanInfo;
TargetStackInfo StackInfo;
};
} // namespace rcc
#endif // RCC_CODEGEN_TARGETDESCRIPTION_H
|