Merge branch 'master' into pptc_and_pool_enhancements
This commit is contained in:
@@ -519,19 +519,50 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Operand src1 = operation.GetSource(0);
|
||||
Operand src2 = operation.GetSource(1);
|
||||
|
||||
ValidateBinOp(dest, src1, src2);
|
||||
|
||||
if (dest.Type.IsInteger())
|
||||
{
|
||||
context.Assembler.Add(dest, src2, dest.Type);
|
||||
// If Destination and Source 1 Operands are the same, perform a standard add as there are no benefits to using LEA.
|
||||
if (dest.Kind == src1.Kind && dest.Value == src1.Value)
|
||||
{
|
||||
ValidateBinOp(dest, src1, src2);
|
||||
|
||||
context.Assembler.Add(dest, src2, dest.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsureSameType(dest, src1, src2);
|
||||
|
||||
int offset;
|
||||
Operand index;
|
||||
|
||||
if (src2.Kind == OperandKind.Constant)
|
||||
{
|
||||
offset = src2.AsInt32();
|
||||
index = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 0;
|
||||
index = src2;
|
||||
}
|
||||
|
||||
MemoryOperand memOp = MemoryOp(dest.Type, src1, index, Multiplier.x1, offset);
|
||||
|
||||
context.Assembler.Lea(dest, memOp, dest.Type);
|
||||
}
|
||||
}
|
||||
else if (dest.Type == OperandType.FP32)
|
||||
else
|
||||
{
|
||||
context.Assembler.Addss(dest, src1, src2);
|
||||
}
|
||||
else /* if (dest.Type == OperandType.FP64) */
|
||||
{
|
||||
context.Assembler.Addsd(dest, src1, src2);
|
||||
ValidateBinOp(dest, src1, src2);
|
||||
|
||||
if (dest.Type == OperandType.FP32)
|
||||
{
|
||||
context.Assembler.Addss(dest, src1, src2);
|
||||
}
|
||||
else /* if (dest.Type == OperandType.FP64) */
|
||||
{
|
||||
context.Assembler.Addsd(dest, src1, src2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1273,6 +1273,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
switch (operation.Instruction)
|
||||
{
|
||||
case Instruction.Add:
|
||||
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger();
|
||||
case Instruction.Multiply:
|
||||
case Instruction.Subtract:
|
||||
return !HardwareCapabilities.SupportsVexEncoding || operation.Destination.Type.IsInteger();
|
||||
|
@@ -33,5 +33,10 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
return !HighCq && Interlocked.Increment(ref _callCount) == MinCallsForRejit;
|
||||
}
|
||||
|
||||
public void ResetCallCount()
|
||||
{
|
||||
Interlocked.Exchange(ref _callCount, 0);
|
||||
}
|
||||
}
|
||||
}
|
@@ -397,33 +397,10 @@ namespace ARMeilleure.Translation
|
||||
|
||||
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
||||
{
|
||||
static bool OverlapsWith(ulong funcAddress, ulong funcSize, ulong address, ulong size)
|
||||
{
|
||||
return funcAddress < address + size && address < funcAddress + funcSize;
|
||||
}
|
||||
// If rejit is running, stop it as it may be trying to rejit a function on the invalidated region.
|
||||
ClearRejitQueue(allowRequeue: true);
|
||||
|
||||
// Make a copy of all overlapping functions, as we can't otherwise
|
||||
// remove elements from the collection we are iterating.
|
||||
// Doing that before clearing the rejit queue is fine, even
|
||||
// if a function is translated after this, it would only replace
|
||||
// a existing function, as rejit is only triggered on functions
|
||||
// that were already executed before.
|
||||
var toDelete = _funcs.Where(x => OverlapsWith(x.Key, x.Value.GuestSize, address, size)).ToArray();
|
||||
|
||||
if (toDelete.Length != 0)
|
||||
{
|
||||
// If rejit is running, stop it as it may be trying to rejit the functions we are
|
||||
// supposed to remove.
|
||||
ClearRejitQueue();
|
||||
}
|
||||
|
||||
foreach (var kv in toDelete)
|
||||
{
|
||||
if (_funcs.TryRemove(kv.Key, out TranslatedFunction func))
|
||||
{
|
||||
EnqueueForDeletion(kv.Key, func);
|
||||
}
|
||||
}
|
||||
// TODO: Completely remove functions overlapping the specified range from the cache.
|
||||
}
|
||||
|
||||
private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func)
|
||||
@@ -434,7 +411,7 @@ namespace ARMeilleure.Translation
|
||||
private void ClearJitCache()
|
||||
{
|
||||
// Ensure no attempt will be made to compile new functions due to rejit.
|
||||
ClearRejitQueue();
|
||||
ClearRejitQueue(allowRequeue: false);
|
||||
|
||||
foreach (var kv in _funcs)
|
||||
{
|
||||
@@ -449,10 +426,25 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearRejitQueue()
|
||||
private void ClearRejitQueue(bool allowRequeue)
|
||||
{
|
||||
_backgroundTranslatorLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_backgroundStack.Clear();
|
||||
|
||||
if (allowRequeue)
|
||||
{
|
||||
while (_backgroundStack.TryPop(out var request))
|
||||
{
|
||||
if (_funcs.TryGetValue(request.Address, out var func))
|
||||
{
|
||||
func.ResetCallCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundStack.Clear();
|
||||
}
|
||||
|
||||
_backgroundTranslatorLock.ReleaseWriterLock();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user