6#include "CompilerConfig.hpp"
8#include "tpde/Assembler.hpp"
13 #error ARG is used as a temporary preprocessor macro
16#define ARG(x) std::declval<x>()
20class AssignmentPartRef;
25concept IsTrue = (B ==
true);
28concept ValueParts =
requires(T a) {
30 { a.count() } -> std::convertible_to<u32>;
33 { a.size_bytes(ARG(u32)) } -> std::convertible_to<u32>;
36 { a.reg_bank(ARG(u32)) } -> std::convertible_to<RegBank>;
40concept ValRefSpecialStruct =
requires(T a) {
42 { a.mode } -> std::same_as<uint8_t &>;
43 requires std::is_standard_layout_v<T>;
44 requires offsetof(T, mode) == 0;
47template <
typename T,
typename Config>
48concept Compiler = CompilerConfig<Config> &&
requires(T a) {
50 { T::NUM_FIXED_ASSIGNMENTS } -> SameBaseAs<u32[Config::NUM_BANKS]>;
53 { a.start_func(ARG(u32)) };
56 a.prologue_assign_arg(
57 ARG(CCAssigner *), ARG(u32), ARG(
typename T::IRValueRef))
62 { a.finish_func(ARG(u32)) };
65 { a.spill_reg(ARG(
typename Config::AsmReg), ARG(u32), ARG(u32)) };
68 { a.load_from_stack(ARG(
typename Config::AsmReg), ARG(u32), ARG(u32)) };
72 a.mov(ARG(
typename Config::AsmReg), ARG(
typename Config::AsmReg), ARG(u32))
77 a.gval_expr_as_reg(ARG(
typename T::GenericValuePart &))
78 } -> std::same_as<typename Config::AsmReg>;
81 a.select_fixed_assignment_reg(ARG(AssignmentPartRef),
82 ARG(
typename T::IRValueRef))
83 } -> std::same_as<typename Config::AsmReg>;
88 { a.cur_func_may_emit_calls() } -> std::convertible_to<bool>;
92 { a.cur_personality_func() } -> std::same_as<SymRef>;
97 { a.cur_cc_assigner() } -> std::convertible_to<CCAssigner *>;
100 a.try_force_fixed_assignment(ARG(
typename T::IRValueRef))
101 } -> std::convertible_to<bool>;
103 { a.val_parts(ARG(
typename T::IRValueRef)) } -> ValueParts;
108 requires ValRefSpecialStruct<typename T::ValRefSpecial>;
113 a.val_ref_special(ARG(
typename T::IRValueRef))
114 } -> std::same_as<std::optional<typename T::ValRefSpecial>>;
119 a.val_part_ref_special(ARG(
typename T::ValRefSpecial &), ARG(u32))
120 } -> std::same_as<typename T::ValuePart>;
126 { a.define_func_idx(ARG(
typename T::IRFuncRef), ARG(u32)) };
130 requires IsTrue<Config::DEFAULT_VAR_REF_HANDLING> ||
requires {
134 { a.setup_var_ref_assignments() };
140 a.load_address_of_var_reference(ARG(
typename Config::AsmReg),
141 ARG(AssignmentPartRef))
146 a.compile_inst(ARG(
typename T::IRInstRef), ARG(
typename T::InstRange))
147 } -> std::convertible_to<bool>;