mirror of
https://git.suyu.dev/suyu/dynarmic
synced 2024-11-21 14:29:03 -07:00
backend/rv64: Implement AssertNoMoreUses and some minor tweaks
This commit is contained in:
parent
b7cca7c53d
commit
cc2a6fd6fb
3 changed files with 43 additions and 30 deletions
|
@ -40,6 +40,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
|||
|
||||
template<>
|
||||
void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
|
||||
[[maybe_unused]] auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(ctx.reg_alloc.IsValueLive(inst));
|
||||
}
|
||||
|
||||
|
@ -93,6 +94,9 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoMoreUses();
|
||||
|
||||
// TODO: Add Cycles
|
||||
|
||||
// TODO: Emit Terminal
|
||||
|
|
|
@ -102,6 +102,13 @@ bool RegAlloc::IsValueLive(IR::Inst* inst) const {
|
|||
return !!ValueLocation(inst);
|
||||
}
|
||||
|
||||
void RegAlloc::AssertNoMoreUses() const {
|
||||
const auto is_empty = [](const auto& i) { return i.values.empty() && !i.locked && !i.realized && !i.accumulated_uses && !i.expected_uses; };
|
||||
ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty));
|
||||
ASSERT(std::all_of(fprs.begin(), fprs.end(), is_empty));
|
||||
ASSERT(std::all_of(spills.begin(), spills.end(), is_empty));
|
||||
}
|
||||
|
||||
template<HostLoc::Kind kind>
|
||||
u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
||||
// TODO
|
||||
|
@ -141,26 +148,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
ASSERT(!ValueInfo(*current_location).realized);
|
||||
ASSERT(!ValueInfo(*current_location).locked);
|
||||
|
||||
if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||
SpillFpr(new_location_index);
|
||||
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
|
||||
break;
|
||||
case HostLoc::Kind::Fpr:
|
||||
ASSERT_FALSE("Logic error");
|
||||
break;
|
||||
case HostLoc::Kind::Spill:
|
||||
as.FLD(biscuit::FPR{new_location_index}, spill_offset + new_location_index * spill_slot_size, biscuit::sp);
|
||||
break;
|
||||
}
|
||||
|
||||
fprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
||||
fprs[new_location_index].realized = true;
|
||||
return new_location_index;
|
||||
} else if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
SpillGpr(new_location_index);
|
||||
|
||||
|
@ -180,6 +168,25 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
|
|||
gprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
||||
gprs[new_location_index].realized = true;
|
||||
return new_location_index;
|
||||
} else if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||
SpillFpr(new_location_index);
|
||||
|
||||
switch (current_location->kind) {
|
||||
case HostLoc::Kind::Gpr:
|
||||
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
|
||||
break;
|
||||
case HostLoc::Kind::Fpr:
|
||||
ASSERT_FALSE("Logic error");
|
||||
break;
|
||||
case HostLoc::Kind::Spill:
|
||||
as.FLD(biscuit::FPR{new_location_index}, spill_offset + new_location_index * spill_slot_size, biscuit::sp);
|
||||
break;
|
||||
}
|
||||
|
||||
fprs[new_location_index] = std::exchange(ValueInfo(*current_location), {});
|
||||
fprs[new_location_index].realized = true;
|
||||
return new_location_index;
|
||||
} else {
|
||||
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
||||
}
|
||||
|
@ -194,19 +201,19 @@ u32 RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
|||
info.values.emplace_back(value);
|
||||
info.locked = true;
|
||||
info.realized = true;
|
||||
info.expected_uses += value->UseCount();
|
||||
info.expected_uses = value->UseCount();
|
||||
};
|
||||
|
||||
if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||
SpillFpr(new_location_index);
|
||||
setup_location(fprs[new_location_index]);
|
||||
return new_location_index;
|
||||
} else if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
if constexpr (required_kind == HostLoc::Kind::Gpr) {
|
||||
const u32 new_location_index = AllocateRegister(gprs, gpr_order);
|
||||
SpillGpr(new_location_index);
|
||||
setup_location(gprs[new_location_index]);
|
||||
return new_location_index;
|
||||
} else if constexpr (required_kind == HostLoc::Kind::Fpr) {
|
||||
const u32 new_location_index = AllocateRegister(fprs, fpr_order);
|
||||
SpillFpr(new_location_index);
|
||||
setup_location(fprs[new_location_index]);
|
||||
return new_location_index;
|
||||
} else {
|
||||
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
|
||||
}
|
||||
|
@ -305,13 +312,13 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
|
|||
return info.Contains(value);
|
||||
};
|
||||
|
||||
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value)) {
|
||||
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
|
||||
return *iter;
|
||||
}
|
||||
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value)) {
|
||||
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != gprs.end()) {
|
||||
return *iter;
|
||||
}
|
||||
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value)) {
|
||||
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != gprs.end()) {
|
||||
return *iter;
|
||||
}
|
||||
ASSERT_FALSE("RegAlloc::ValueInfo: Value not found");
|
||||
|
|
|
@ -124,6 +124,8 @@ public:
|
|||
(rs.Realize(), ...);
|
||||
}
|
||||
|
||||
void AssertNoMoreUses() const;
|
||||
|
||||
private:
|
||||
template<typename>
|
||||
friend struct RAReg;
|
||||
|
|
Loading…
Reference in a new issue