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 noexcept {
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 noexcept {
35 if (std::holds_alternative<AsmReg>(base)) {
36 return std::get<AsmReg>(base).valid();
41 AsmReg index_reg() const noexcept {
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 noexcept {
return scale != 0; }
57 std::variant<std::monostate, ValuePartRef, ScratchReg, Expr> state;
59 GenericValuePart() =
default;
61 GenericValuePart(GenericValuePart &) =
delete;
63 GenericValuePart(GenericValuePart &&other)
noexcept {
64 state = std::move(other.state);
65 other.state = std::monostate{};
68 GenericValuePart &operator=(
const GenericValuePart &)
noexcept =
delete;
70 GenericValuePart &operator=(GenericValuePart &&other)
noexcept {
74 state = std::move(other.state);
75 other.state = std::monostate{};
80 GenericValuePart(
ScratchReg &®) noexcept : state{std::move(reg)} {
81 assert(std::get<ScratchReg>(state).has_reg());
85 GenericValuePart(ValuePartRef &&ref) noexcept : state{std::move(ref)} {}
87 GenericValuePart(Expr expr) noexcept : state{std::move(expr)} {}
89 [[nodiscard]]
bool is_expr() const noexcept {
90 return std::holds_alternative<Expr>(state);
93 [[nodiscard]]
bool is_imm() const noexcept {
94 auto *ptr = std::get_if<ValuePartRef>(&state);
95 return ptr && ptr->is_const();
98 u32 imm_size() const noexcept {
103 [[nodiscard]] u64 imm64() const noexcept {
104 assert(imm_size() <= 8);
105 return val_ref().const_data()[0];
108 [[nodiscard]]
const ValuePartRef &
val_ref() const noexcept {
109 return std::get<ValuePartRef>(state);
112 [[nodiscard]] ValuePartRef &
val_ref() noexcept {
113 return std::get<ValuePartRef>(state);
116 void reset() noexcept { 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) noexcept
Get a using reference to a value.