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)) };
 
   55  { a.gen_func_prolog_and_args(ARG(CCAssigner *)) };
 
   59  { a.finish_func(ARG(u32)) };
 
   62  { a.spill_reg(ARG(
typename Config::AsmReg), ARG(u32), ARG(u32)) };
 
   65  { a.load_from_stack(ARG(
typename Config::AsmReg), ARG(u32), ARG(u32)) };
 
   69    a.mov(ARG(
typename Config::AsmReg), ARG(
typename Config::AsmReg), ARG(u32))
 
   74    a.gval_expr_as_reg(ARG(
typename T::GenericValuePart &))
 
   75  } -> std::same_as<typename Config::AsmReg>;
 
   78    a.select_fixed_assignment_reg(ARG(AssignmentPartRef),
 
   79                                  ARG(
typename T::IRValueRef))
 
   80  } -> std::same_as<typename Config::AsmReg>;
 
   85  { a.cur_func_may_emit_calls() } -> std::convertible_to<bool>;
 
   89  { a.cur_personality_func() } -> std::same_as<SymRef>;
 
   94  { a.cur_cc_assigner() } -> std::convertible_to<CCAssigner *>;
 
   97    a.try_force_fixed_assignment(ARG(
typename T::IRValueRef))
 
   98  } -> std::convertible_to<bool>;
 
  100  { a.val_parts(ARG(
typename T::IRValueRef)) } -> ValueParts;
 
  105  requires ValRefSpecialStruct<typename T::ValRefSpecial>;
 
  110    a.val_ref_special(ARG(
typename T::IRValueRef))
 
  111  } -> std::same_as<std::optional<typename T::ValRefSpecial>>;
 
  116    a.val_part_ref_special(ARG(
typename T::ValRefSpecial &), ARG(u32))
 
  117  } -> std::same_as<typename T::ValuePart>;
 
  123  { a.define_func_idx(ARG(
typename T::IRFuncRef), ARG(u32)) };
 
  127  requires IsTrue<Config::DEFAULT_VAR_REF_HANDLING> || 
requires {
 
  131    { a.setup_var_ref_assignments() };
 
  137      a.load_address_of_var_reference(ARG(
typename Config::AsmReg),
 
  138                                      ARG(AssignmentPartRef))
 
  143    a.compile_inst(ARG(
typename T::IRInstRef), ARG(
typename T::InstRange))
 
  144  } -> std::convertible_to<bool>;