mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-10-01 12:30:00 +02:00
e21ebbf666
* Add optimizations related to caller/callee saved registers, thread synchronization and disable tier 0 * Refactoring * Add a config entry to enable or disable the reg load/store opt. * Remove unnecessary register state stores for calls when the callee is know * Rename IoType to VarType * Enable tier 0 while fixing some perf issues related to tier 0 * Small tweak -- Compile before adding to the cache, to avoid lags * Add required config entry
60 lines
No EOL
2 KiB
C#
60 lines
No EOL
2 KiB
C#
using ChocolArm64.State;
|
|
using System.Reflection.Emit;
|
|
|
|
namespace ChocolArm64.Translation
|
|
{
|
|
struct ILOpCodeStoreState : IILEmit
|
|
{
|
|
private ILBlock _block;
|
|
|
|
private TranslatedSub _callSub;
|
|
|
|
public ILOpCodeStoreState(ILBlock block, TranslatedSub callSub = null)
|
|
{
|
|
_block = block;
|
|
_callSub = callSub;
|
|
}
|
|
|
|
public void Emit(ILMethodBuilder context)
|
|
{
|
|
long intOutputs = context.RegUsage.GetIntOutputs(_block);
|
|
long vecOutputs = context.RegUsage.GetVecOutputs(_block);
|
|
|
|
if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete)
|
|
{
|
|
intOutputs = RegisterUsage.ClearCallerSavedIntRegs(intOutputs, context.IsAarch64);
|
|
vecOutputs = RegisterUsage.ClearCallerSavedVecRegs(vecOutputs, context.IsAarch64);
|
|
}
|
|
|
|
if (_callSub != null)
|
|
{
|
|
//Those register are assigned on the callee function, without
|
|
//reading it's value first. We don't need to write them because
|
|
//they are not going to be read on the callee.
|
|
intOutputs &= ~_callSub.IntNiRegsMask;
|
|
vecOutputs &= ~_callSub.VecNiRegsMask;
|
|
}
|
|
|
|
StoreLocals(context, intOutputs, RegisterType.Int);
|
|
StoreLocals(context, vecOutputs, RegisterType.Vector);
|
|
}
|
|
|
|
private void StoreLocals(ILMethodBuilder context, long outputs, RegisterType baseType)
|
|
{
|
|
for (int bit = 0; bit < 64; bit++)
|
|
{
|
|
long mask = 1L << bit;
|
|
|
|
if ((outputs & mask) != 0)
|
|
{
|
|
Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
|
|
|
|
context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
|
|
context.Generator.EmitLdloc(context.GetLocalIndex(reg));
|
|
|
|
context.Generator.Emit(OpCodes.Stfld, reg.GetField());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |