7template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
8struct CompilerBase<Adaptor, Derived, Config>::ScratchReg {
12 AsmReg reg = AsmReg::make_invalid();
15 explicit ScratchReg(
CompilerBase *compiler) : compiler(compiler) {}
17 explicit ScratchReg(
const ScratchReg &) =
delete;
18 ScratchReg(ScratchReg &&) noexcept;
20 ~ScratchReg() noexcept {
reset(); }
22 ScratchReg &operator=(
const ScratchReg &) =
delete;
23 ScratchReg &operator=(ScratchReg &&) noexcept;
25 bool has_reg() const noexcept {
return reg.valid(); }
27 AsmReg cur_reg() const noexcept {
32 AsmReg alloc_specific(AsmReg reg)
noexcept;
34 AsmReg alloc_gp() noexcept {
return alloc(Config::GP_BANK); }
39 AsmReg alloc(RegBank bank)
noexcept;
41 AsmReg release() noexcept {
47 void reset() noexcept;
50 void force_set_reg(AsmReg reg) noexcept { this->reg = reg; }
53template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
54CompilerBase<Adaptor, Derived, Config>::ScratchReg::ScratchReg(
55 ScratchReg &&other)
noexcept {
56 this->compiler = other.compiler;
57 this->reg = other.reg;
58 other.reg = AsmReg::make_invalid();
61template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
62typename CompilerBase<Adaptor, Derived, Config>::ScratchReg &
63 CompilerBase<Adaptor, Derived, Config>::ScratchReg::operator=(
64 ScratchReg &&other)
noexcept {
70 this->compiler = other.compiler;
71 this->reg = other.reg;
72 other.reg = AsmReg::make_invalid();
76template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
77typename CompilerBase<Adaptor, Derived, Config>::AsmReg
78 CompilerBase<Adaptor, Derived, Config>::ScratchReg::alloc_specific(
79 AsmReg reg)
noexcept {
80 assert(compiler->may_change_value_state());
81 assert(!compiler->register_file.is_fixed(reg));
84 if (compiler->register_file.is_used(reg)) {
85 compiler->evict_reg(reg);
88 compiler->register_file.mark_used(reg, INVALID_VAL_LOCAL_IDX, 0);
89 compiler->register_file.mark_clobbered(reg);
90 compiler->register_file.mark_fixed(reg);
95template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
96CompilerBase<Adaptor, Derived, Config>::AsmReg
97 CompilerBase<Adaptor, Derived, Config>::ScratchReg::alloc(
98 RegBank bank)
noexcept {
99 assert(compiler->may_change_value_state());
101 auto ®_file = compiler->register_file;
102 if (!reg.invalid()) {
103 assert(bank == reg_file.reg_bank(reg));
107 reg = compiler->select_reg(bank, 0);
108 reg_file.mark_used(reg, INVALID_VAL_LOCAL_IDX, 0);
109 reg_file.mark_clobbered(reg);
110 reg_file.mark_fixed(reg);
114template <IRAdaptor Adaptor,
typename Derived, CompilerConfig Config>
115void CompilerBase<Adaptor, Derived, Config>::ScratchReg::reset() noexcept {
120 compiler->register_file.unmark_fixed(reg);
121 compiler->register_file.unmark_used(reg);
122 reg = AsmReg::make_invalid();
CompilerBase(Adaptor *adaptor)
Initialize a CompilerBase, should be called by the derived classes.