Implement speculative translation on the CPU (#515)
* Implement speculative translation on the cpu, and change the way how branches to unknown or untranslated addresses works * Port t0opt changes and other cleanups * Change namespace from translation related classes to ChocolArm64.Translation, other minor tweaks * Fix typo * Translate higher quality code for indirect jumps aswell, and on some cases that were missed when lower quality (tier 0) code was available * Remove debug print * Remove direct argument passing optimization, and enable tail calls for BR instructions * Call delegates directly with Callvirt rather than calling Execute, do not emit calls for tier 0 code * Remove unused property * Rename argument on ArmSubroutine delegate
This commit is contained in:
parent
f5b4f6ccc4
commit
a694420d11
21 changed files with 656 additions and 376 deletions
|
@ -26,74 +26,32 @@ namespace ChocolArm64.Translation
|
|||
_subName = subName;
|
||||
}
|
||||
|
||||
public TranslatedSub GetSubroutine()
|
||||
public TranslatedSub GetSubroutine(TranslationTier tier)
|
||||
{
|
||||
LocalAlloc = new LocalAlloc(_ilBlocks, _ilBlocks[0]);
|
||||
|
||||
List<Register> subArgs = new List<Register>();
|
||||
|
||||
void SetArgs(long inputs, RegisterType baseType)
|
||||
{
|
||||
for (int bit = 0; bit < 64; bit++)
|
||||
{
|
||||
long mask = 1L << bit;
|
||||
|
||||
if ((inputs & mask) != 0)
|
||||
{
|
||||
subArgs.Add(GetRegFromBit(bit, baseType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetArgs(LocalAlloc.GetIntInputs(_ilBlocks[0]), RegisterType.Int);
|
||||
SetArgs(LocalAlloc.GetVecInputs(_ilBlocks[0]), RegisterType.Vector);
|
||||
|
||||
DynamicMethod method = new DynamicMethod(_subName, typeof(long), GetArgumentTypes(subArgs));
|
||||
DynamicMethod method = new DynamicMethod(_subName, typeof(long), TranslatedSub.FixedArgTypes);
|
||||
|
||||
Generator = method.GetILGenerator();
|
||||
|
||||
TranslatedSub subroutine = new TranslatedSub(method, subArgs);
|
||||
|
||||
int argsStart = TranslatedSub.FixedArgTypes.Length;
|
||||
TranslatedSub subroutine = new TranslatedSub(method, tier);
|
||||
|
||||
_locals = new Dictionary<Register, int>();
|
||||
|
||||
_localsCount = 0;
|
||||
|
||||
for (int index = 0; index < subroutine.SubArgs.Count; index++)
|
||||
{
|
||||
Register reg = subroutine.SubArgs[index];
|
||||
|
||||
Generator.EmitLdarg(index + argsStart);
|
||||
Generator.EmitStloc(GetLocalIndex(reg));
|
||||
}
|
||||
new ILOpCodeLoadState(_ilBlocks[0]).Emit(this);
|
||||
|
||||
foreach (ILBlock ilBlock in _ilBlocks)
|
||||
{
|
||||
ilBlock.Emit(this);
|
||||
}
|
||||
|
||||
subroutine.PrepareMethod();
|
||||
|
||||
return subroutine;
|
||||
}
|
||||
|
||||
private Type[] GetArgumentTypes(IList<Register> Params)
|
||||
{
|
||||
Type[] fixedArgs = TranslatedSub.FixedArgTypes;
|
||||
|
||||
Type[] output = new Type[Params.Count + fixedArgs.Length];
|
||||
|
||||
fixedArgs.CopyTo(output, 0);
|
||||
|
||||
int typeIdx = fixedArgs.Length;
|
||||
|
||||
for (int index = 0; index < Params.Count; index++)
|
||||
{
|
||||
output[typeIdx++] = GetFieldType(Params[index].Type);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public int GetLocalIndex(Register reg)
|
||||
{
|
||||
if (!_locals.TryGetValue(reg, out int index))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue