mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-06 01:29:44 +00:00
Implement caller saved registers
Hopefully this fixes linux tests runs. The heuristics may need to be retuned.
This commit is contained in:
parent
4c8753f484
commit
c971abb9ec
1 changed files with 33 additions and 9 deletions
|
@ -206,12 +206,6 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
int intLocalFreeRegisters = intFreeRegisters & ~blkInfo.IntFixedRegisters;
|
||||
int vecLocalFreeRegisters = vecFreeRegisters & ~blkInfo.VecFixedRegisters;
|
||||
|
||||
if (blkInfo.HasCall)
|
||||
{
|
||||
intLocalFreeRegisters &= ~regMasks.IntCallerSavedRegisters;
|
||||
vecLocalFreeRegisters &= ~regMasks.VecCallerSavedRegisters;
|
||||
}
|
||||
|
||||
int intActiveRegisters = 0;
|
||||
int vecActiveRegisters = 0;
|
||||
|
||||
|
@ -245,9 +239,39 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
}
|
||||
// If operation is call, spill caller saved registers.
|
||||
else if (node.Instruction == Instruction.Call)
|
||||
{
|
||||
int intCallerSavedRegisters = regMasks.IntCallerSavedRegisters & intActiveRegisters;
|
||||
int vecCallerSavedRegisters = regMasks.VecCallerSavedRegisters & vecActiveRegisters;
|
||||
|
||||
// If the operation is folded to a fill, no need ot inspect sources; since sources of fills are
|
||||
// constant operands which does not require registers.
|
||||
while (intCallerSavedRegisters != 0)
|
||||
{
|
||||
int reg = BitOperations.TrailingZeroCount(intCallerSavedRegisters);
|
||||
|
||||
SpillRegister(ref GetLocalInfo(intActive[reg]), node);
|
||||
|
||||
intActive[reg] = default;
|
||||
intActiveRegisters &= ~(1 << reg);
|
||||
intCurrActiveRegisters |= 1 << reg;
|
||||
intCallerSavedRegisters &= ~(1 << reg);
|
||||
}
|
||||
|
||||
while (vecCallerSavedRegisters != 0)
|
||||
{
|
||||
int reg = BitOperations.TrailingZeroCount(vecCallerSavedRegisters);
|
||||
|
||||
SpillRegister(ref GetLocalInfo(vecActive[reg]), node);
|
||||
|
||||
vecActive[reg] = default;
|
||||
vecActiveRegisters &= ~(1 << reg);
|
||||
vecCurrActiveRegisters |= 1 << reg;
|
||||
vecCallerSavedRegisters &= ~(1 << reg);
|
||||
}
|
||||
}
|
||||
|
||||
// If the operation is folded to a fill, no need to inspect sources; since sources of fills are
|
||||
// constant operands which do not require registers.
|
||||
if (!folded)
|
||||
{
|
||||
foreach (ref Operand source in node.SourcesUnsafe)
|
||||
|
@ -314,7 +338,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
if (info.UsesAllocated == info.Uses)
|
||||
{
|
||||
// If the local is not a block local, we have to spill it; otherwise this would cause
|
||||
// issues when the local is used a in a loop.
|
||||
// issues when the local is used in a loop.
|
||||
if (!info.IsBlockLocal)
|
||||
{
|
||||
SpillRegister(ref info, node);
|
||||
|
|
Loading…
Reference in a new issue