backend/arm64/reg_alloc: More flag handling
This commit is contained in:
parent
21601764de
commit
78bc0812b9
2 changed files with 29 additions and 1 deletions
|
@ -11,6 +11,8 @@
|
|||
#include <mcl/assert.hpp>
|
||||
#include <mcl/stdint.hpp>
|
||||
|
||||
#include "dynarmic/backend/arm64/abi.h"
|
||||
|
||||
namespace Dynarmic::Backend::Arm64 {
|
||||
|
||||
using namespace oaknut::util;
|
||||
|
@ -232,7 +234,7 @@ int RegAlloc::RealizeWriteImpl(const IR::Inst* value) {
|
|||
fprs[new_location_index].SetupLocation(value);
|
||||
return new_location_index;
|
||||
} else if constexpr (kind == HostLoc::Kind::Flags) {
|
||||
ASSERT(flags.values.empty());
|
||||
SpillFlags();
|
||||
flags.SetupLocation(value);
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -287,6 +289,31 @@ void RegAlloc::SpillFpr(int index) {
|
|||
spills[new_location_index] = std::exchange(fprs[index], {});
|
||||
}
|
||||
|
||||
void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
|
||||
const auto current_location = ValueLocation(read.value.GetInst());
|
||||
ASSERT(current_location);
|
||||
|
||||
if (current_location->kind == HostLoc::Kind::Flags) {
|
||||
if (!flags.IsOneRemainingUse()) {
|
||||
SpillFlags();
|
||||
}
|
||||
} else if (current_location->kind == HostLoc::Kind::Gpr) {
|
||||
if (!flags.values.empty()) {
|
||||
SpillFlags();
|
||||
}
|
||||
code.MSR(static_cast<oaknut::SystemReg>(0b11'011'0100'0010'000), oaknut::XReg{current_location->index});
|
||||
} else if (current_location->kind == HostLoc::Kind::Spill) {
|
||||
if (!flags.values.empty()) {
|
||||
SpillFlags();
|
||||
}
|
||||
code.LDR(Wscratch0, SP, spill_offset + current_location->index * spill_slot_size);
|
||||
code.MSR(static_cast<oaknut::SystemReg>(0b11'011'0100'0010'000), Xscratch0);
|
||||
} else {
|
||||
ASSERT_FALSE("Invalid current location for flags");
|
||||
}
|
||||
flags.SetupLocation(write);
|
||||
}
|
||||
|
||||
void RegAlloc::SpillFlags() {
|
||||
ASSERT(!flags.locked && !flags.realized);
|
||||
if (flags.values.empty()) {
|
||||
|
|
|
@ -219,6 +219,7 @@ public:
|
|||
|
||||
void DefineAsExisting(IR::Inst* inst, Argument& arg);
|
||||
|
||||
void ReadWriteFlags(Argument& read, IR::Inst* write);
|
||||
void SpillFlags();
|
||||
void SpillAll();
|
||||
|
||||
|
|
Loading…
Reference in a new issue