mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
irjit: Add facility for native reg transfer.
This commit is contained in:
parent
06a1f0b72c
commit
88b6442527
6 changed files with 39 additions and 20 deletions
|
@ -347,7 +347,7 @@ void Arm64IRRegCache::AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Arm64IRRegCache::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) {
|
||||
bool Arm64IRRegCache::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes) {
|
||||
// No special flags, skip the check for a little speed.
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
|||
const int *GetAllocationOrder(MIPSLoc type, MIPSMap flags, int &count, int &base) const override;
|
||||
void AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) override;
|
||||
|
||||
bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) override;
|
||||
bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes) override;
|
||||
void LoadNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void StoreNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void SetNativeRegValue(IRNativeReg nreg, uint32_t imm) override;
|
||||
|
|
|
@ -501,7 +501,7 @@ IRNativeReg IRNativeRegCacheBase::FindBestToSpill(MIPSLoc type, MIPSMap flags, b
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool IRNativeRegCacheBase::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) {
|
||||
bool IRNativeRegCacheBase::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes) {
|
||||
int allocCount = 0, base = 0;
|
||||
const int *allocOrder = GetAllocationOrder(type, flags, allocCount, base);
|
||||
|
||||
|
@ -514,6 +514,11 @@ bool IRNativeRegCacheBase::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IRNativeRegCacheBase::TransferNativeReg(IRNativeReg nreg, IRNativeReg dest, MIPSLoc type, IRReg first, int lanes, MIPSMap flags) {
|
||||
// To be overridden if the backend supports transfers.
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRNativeRegCacheBase::DiscardNativeReg(IRNativeReg nreg) {
|
||||
_assert_msg_(nreg >= 0 && nreg < config_.totalNativeRegs, "DiscardNativeReg on invalid register %d", nreg);
|
||||
if (nr[nreg].mipsReg != IRREG_INVALID) {
|
||||
|
@ -930,11 +935,14 @@ IRNativeReg IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRReg first, int la
|
|||
case MIPSLoc::REG:
|
||||
if (type != MIPSLoc::REG) {
|
||||
nreg = AllocateReg(type, flags);
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags)) {
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags, lanes)) {
|
||||
// If it's not compatible, we'll need to reallocate.
|
||||
// TODO: Could do a transfer and avoid memory flush.
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
if (TransferNativeReg(nreg, -1, type, first, lanes, flags)) {
|
||||
nreg = mr[first].nReg;
|
||||
} else {
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -942,9 +950,13 @@ IRNativeReg IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRReg first, int la
|
|||
case MIPSLoc::VREG:
|
||||
if (type != mr[first].loc) {
|
||||
nreg = AllocateReg(type, flags);
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags)) {
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
} else if (!IsNativeRegCompatible(nreg, type, flags, lanes)) {
|
||||
if (TransferNativeReg(nreg, -1, type, first, lanes, flags)) {
|
||||
nreg = mr[first].nReg;
|
||||
} else {
|
||||
FlushNativeReg(nreg);
|
||||
nreg = AllocateReg(type, flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -981,10 +993,13 @@ void IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg fi
|
|||
_assert_msg_(!mreg.isStatic, "Cannot MapNativeReg a static reg mismatch");
|
||||
if ((flags & MIPSMap::NOINIT) != MIPSMap::NOINIT) {
|
||||
// If we need init, we have to flush mismatches.
|
||||
// TODO: Do a shuffle if interior only?
|
||||
// TODO: We may also be motivated to have multiple read-only "views" or an IRReg.
|
||||
// For example Vec4Scale v0..v3, v0..v3, v3
|
||||
FlushNativeReg(mreg.nReg);
|
||||
if (!TransferNativeReg(mreg.nReg, nreg, type, first, lanes, flags)) {
|
||||
// TODO: We may also be motivated to have multiple read-only "views" or an IRReg.
|
||||
// For example Vec4Scale v0..v3, v0..v3, v3
|
||||
FlushNativeReg(mreg.nReg);
|
||||
}
|
||||
// The mismatch has been "resolved" now.
|
||||
mismatch = false;
|
||||
} else if (oldlanes != 1) {
|
||||
// Even if we don't care about the current contents, we can't discard outside.
|
||||
bool extendsBefore = oldlane > i;
|
||||
|
@ -1017,6 +1032,9 @@ void IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg fi
|
|||
DiscardNativeReg(mreg.nReg);
|
||||
else
|
||||
FlushNativeReg(mreg.nReg);
|
||||
|
||||
// That took care of the mismatch, either by clobber or flush.
|
||||
mismatch = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1027,8 +1045,8 @@ void IRNativeRegCacheBase::MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg fi
|
|||
if ((flags & MIPSMap::NOINIT) != MIPSMap::NOINIT) {
|
||||
// We better not be trying to map to a different nreg if it's in one now.
|
||||
// This might happen on some sort of transfer...
|
||||
// TODO: Make a direct transfer, i.e. FREG -> VREG?
|
||||
FlushNativeReg(mreg.nReg);
|
||||
if (!TransferNativeReg(mreg.nReg, nreg, type, first, lanes, flags))
|
||||
FlushNativeReg(mreg.nReg);
|
||||
} else {
|
||||
DiscardNativeReg(mreg.nReg);
|
||||
}
|
||||
|
|
|
@ -209,13 +209,14 @@ protected:
|
|||
IRNativeReg AllocateReg(MIPSLoc type, MIPSMap flags);
|
||||
IRNativeReg FindFreeReg(MIPSLoc type, MIPSMap flags) const;
|
||||
IRNativeReg FindBestToSpill(MIPSLoc type, MIPSMap flags, bool unusedOnly, bool *clobbered) const;
|
||||
virtual bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags);
|
||||
virtual bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes);
|
||||
virtual void DiscardNativeReg(IRNativeReg nreg);
|
||||
virtual void FlushNativeReg(IRNativeReg nreg);
|
||||
virtual void DiscardReg(IRReg mreg);
|
||||
virtual void FlushReg(IRReg mreg);
|
||||
virtual void AdjustNativeRegAsPtr(IRNativeReg nreg, bool state);
|
||||
virtual void MapNativeReg(MIPSLoc type, IRNativeReg nreg, IRReg first, int lanes, MIPSMap flags);
|
||||
virtual bool TransferNativeReg(IRNativeReg nreg, IRNativeReg dest, MIPSLoc type, IRReg first, int lanes, MIPSMap flags);
|
||||
virtual IRNativeReg MapNativeReg(MIPSLoc type, IRReg first, int lanes, MIPSMap flags);
|
||||
IRNativeReg MapNativeRegAsPointer(IRReg gpr);
|
||||
|
||||
|
|
|
@ -303,11 +303,11 @@ void RiscVRegCache::AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) {
|
|||
}
|
||||
}
|
||||
|
||||
bool RiscVRegCache::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) {
|
||||
bool RiscVRegCache::IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes) {
|
||||
// No special flags except VREG, skip the check for a little speed.
|
||||
if (type != MIPSLoc::VREG)
|
||||
return true;
|
||||
return IRNativeRegCacheBase::IsNativeRegCompatible(nreg, type, flags);
|
||||
return IRNativeRegCacheBase::IsNativeRegCompatible(nreg, type, flags, lanes);
|
||||
}
|
||||
|
||||
void RiscVRegCache::LoadNativeReg(IRNativeReg nreg, IRReg first, int lanes) {
|
||||
|
|
|
@ -76,7 +76,7 @@ protected:
|
|||
const int *GetAllocationOrder(MIPSLoc type, MIPSMap flags, int &count, int &base) const override;
|
||||
void AdjustNativeRegAsPtr(IRNativeReg nreg, bool state) override;
|
||||
|
||||
bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags) override;
|
||||
bool IsNativeRegCompatible(IRNativeReg nreg, MIPSLoc type, MIPSMap flags, int lanes) override;
|
||||
void LoadNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void StoreNativeReg(IRNativeReg nreg, IRReg first, int lanes) override;
|
||||
void SetNativeRegValue(IRNativeReg nreg, uint32_t imm) override;
|
||||
|
|
Loading…
Add table
Reference in a new issue