11template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
12struct CompilerBase<Adaptor, Derived, Config>::GenericValuePart {
14 std::variant<AsmReg, ScratchReg> base;
15 std::variant<AsmReg, ScratchReg> index;
19 explicit Expr() : base{AsmReg::make_invalid()}, scale{0}, disp{0} {}
21 explicit Expr(AsmReg base, i64 disp = 0)
22 : base(base), scale(0), disp(disp) {}
24 explicit Expr(ScratchReg &&base, i64 disp = 0)
25 : base(std::move(base)), scale(0), disp(disp) {}
27 AsmReg base_reg()
const {
28 if (std::holds_alternative<AsmReg>(base)) {
29 return std::get<AsmReg>(base);
31 return std::get<ScratchReg>(base).cur_reg();
34 [[nodiscard]]
bool has_base()
const {
35 if (std::holds_alternative<AsmReg>(base)) {
36 return std::get<AsmReg>(base).valid();
41 AsmReg index_reg()
const {
42 assert(scale != 0 &&
"index_reg() called on invalid index");
43 assert((scale != 1 || has_base()) &&
44 "Expr with unscaled index must have base");
45 if (std::holds_alternative<AsmReg>(index)) {
46 return std::get<AsmReg>(index);
48 return std::get<ScratchReg>(index).cur_reg();
51 [[nodiscard]]
bool has_index()
const {
return scale != 0; }
57 std::variant<std::monostate, ValuePartRef, ScratchReg, Expr> state;
59 GenericValuePart() =
default;
61 GenericValuePart(GenericValuePart &) =
delete;
63 GenericValuePart(GenericValuePart &&other) {
64 state = std::move(other.state);
65 other.state = std::monostate{};
68 GenericValuePart &operator=(
const GenericValuePart &) =
delete;
70 GenericValuePart &operator=(GenericValuePart &&other) {
74 state = std::move(other.state);
75 other.state = std::monostate{};
80 GenericValuePart(
ScratchReg &®) : state{std::move(reg)} {
81 assert(std::get<ScratchReg>(state).has_reg());
85 GenericValuePart(ValuePartRef &&ref) : state{std::move(ref)} {}
87 GenericValuePart(Expr expr) : state{std::move(expr)} {}
89 [[nodiscard]]
bool is_expr()
const {
90 return std::holds_alternative<Expr>(state);
93 [[nodiscard]]
bool is_imm()
const {
94 auto *ptr = std::get_if<ValuePartRef>(&state);
95 return ptr && ptr->is_const();
98 u32 imm_size()
const {
103 [[nodiscard]] u64 imm64()
const {
104 assert(imm_size() <= 8);
105 return val_ref().const_data()[0];
108 [[nodiscard]]
const ValuePartRef &
val_ref()
const {
109 return std::get<ValuePartRef>(state);
112 [[nodiscard]] ValuePartRef &
val_ref() {
113 return std::get<ValuePartRef>(state);
116 void reset() { state = std::monostate{}; }
Owned unspillable and unevictable temporary register with RAII semantics.
The base class for the compiler.
void reset()
Reset any leftover data from the previous compilation such that it will not affect the next compilati...
ValueRef val_ref(IRValueRef value)
Get a using reference to a value.