Fix cpu issue with cmp optimization, add HINT and FRINTX (scalar) instructions, fix for NvFlinger sometimes missing free buffers

This commit is contained in:
gdkchan 2018-02-24 11:19:28 -03:00
parent 3936c93448
commit 035efc913e
10 changed files with 96 additions and 24 deletions

View file

@ -51,6 +51,7 @@ namespace ChocolArm64
Set("x10100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluImm)); Set("x10100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluImm));
Set("x1001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluRs)); Set("x1001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluRs));
Set("x00100111x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Extr, typeof(AOpCodeAluRs)); Set("x00100111x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Extr, typeof(AOpCodeAluRs));
Set("11010101000000110010xxxxxxx11111", AInstEmit.Hint, typeof(AOpCodeSystem));
Set("xx001000110xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldar, typeof(AOpCodeMemEx)); Set("xx001000110xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldar, typeof(AOpCodeMemEx));
Set("1x001000011xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxp, typeof(AOpCodeMemEx)); Set("1x001000011xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxp, typeof(AOpCodeMemEx));
Set("xx001000010xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxr, typeof(AOpCodeMemEx)); Set("xx001000010xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxr, typeof(AOpCodeMemEx));
@ -193,6 +194,7 @@ namespace ChocolArm64
Set("000111100x100110010000xxxxxxxxxx", AInstEmit.Frinta_S, typeof(AOpCodeSimd)); Set("000111100x100110010000xxxxxxxxxx", AInstEmit.Frinta_S, typeof(AOpCodeSimd));
Set("000111100x100101010000xxxxxxxxxx", AInstEmit.Frintm_S, typeof(AOpCodeSimd)); Set("000111100x100101010000xxxxxxxxxx", AInstEmit.Frintm_S, typeof(AOpCodeSimd));
Set("000111100x100100110000xxxxxxxxxx", AInstEmit.Frintp_S, typeof(AOpCodeSimd)); Set("000111100x100100110000xxxxxxxxxx", AInstEmit.Frintp_S, typeof(AOpCodeSimd));
Set("000111100x100111010000xxxxxxxxxx", AInstEmit.Frintx_S, typeof(AOpCodeSimd));
Set("000111100x100001110000xxxxxxxxxx", AInstEmit.Fsqrt_S, typeof(AOpCodeSimd)); Set("000111100x100001110000xxxxxxxxxx", AInstEmit.Fsqrt_S, typeof(AOpCodeSimd));
Set("000111100x1xxxxx001110xxxxxxxxxx", AInstEmit.Fsub_S, typeof(AOpCodeSimdReg)); Set("000111100x1xxxxx001110xxxxxxxxxx", AInstEmit.Fsub_S, typeof(AOpCodeSimdReg));
Set("0>0011101<1xxxxx110101xxxxxxxxxx", AInstEmit.Fsub_V, typeof(AOpCodeSimdReg)); Set("0>0011101<1xxxxx110101xxxxxxxxxx", AInstEmit.Fsub_V, typeof(AOpCodeSimdReg));

View file

@ -6,7 +6,7 @@ using System.Reflection.Emit;
namespace ChocolArm64 namespace ChocolArm64
{ {
class ATranslator public class ATranslator
{ {
public AThread Thread { get; private set; } public AThread Thread { get; private set; }
@ -41,7 +41,7 @@ namespace ChocolArm64
while (Position != 0 && KeepRunning); while (Position != 0 && KeepRunning);
} }
public bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub) internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)
{ {
if (OpCode.Emitter != AInstEmit.Bl) if (OpCode.Emitter != AInstEmit.Bl)
{ {
@ -53,7 +53,7 @@ namespace ChocolArm64
return TryGetCachedSub(((AOpCodeBImmAl)OpCode).Imm, out Sub); return TryGetCachedSub(((AOpCodeBImmAl)OpCode).Imm, out Sub);
} }
public bool TryGetCachedSub(long Position, out ATranslatedSub Sub) internal bool TryGetCachedSub(long Position, out ATranslatedSub Sub)
{ {
return CachedSubs.TryGetValue(Position, out Sub); return CachedSubs.TryGetValue(Position, out Sub);
} }

View file

@ -10,8 +10,6 @@ namespace ChocolArm64.Decoder
public int Opc { get; private set; } public int Opc { get; private set; }
public int Size { get; protected set; } public int Size { get; protected set; }
public int SizeF => Size & 1;
public AOpCodeSimd(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) public AOpCodeSimd(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{ {
Rd = (OpCode >> 0) & 0x1f; Rd = (OpCode >> 0) & 0x1f;

View file

@ -265,6 +265,32 @@ namespace ChocolArm64.Instruction
}); });
} }
public static void Frintx_S(AILEmitterCtx Context)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpcr));
if (Op.Size == 0)
{
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.RoundF));
}
else if (Op.Size == 1)
{
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Round));
}
else
{
throw new InvalidOperationException();
}
EmitScalarSetF(Context, Op.Rd, Op.Size);
}
public static void Fsqrt_S(AILEmitterCtx Context) public static void Fsqrt_S(AILEmitterCtx Context)
{ {
EmitScalarUnaryOpF(Context, () => EmitScalarUnaryOpF(Context, () =>

View file

@ -9,6 +9,11 @@ namespace ChocolArm64.Instruction
{ {
static partial class AInstEmit static partial class AInstEmit
{ {
public static void Hint(AILEmitterCtx Context)
{
//Execute as no-op.
}
public static void Mrs(AILEmitterCtx Context) public static void Mrs(AILEmitterCtx Context)
{ {
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;

View file

@ -189,6 +189,32 @@ namespace ChocolArm64.Instruction
(Value >> 6) & 1 + (Value >> 7); (Value >> 6) & 1 + (Value >> 7);
} }
public static float RoundF(float Value, int Fpcr)
{
switch ((ARoundMode)((Fpcr >> 22) & 3))
{
case ARoundMode.ToNearest: return MathF.Round (Value);
case ARoundMode.TowardsPlusInfinity: return MathF.Ceiling (Value);
case ARoundMode.TowardsMinusInfinity: return MathF.Floor (Value);
case ARoundMode.TowardsZero: return MathF.Truncate(Value);
}
throw new InvalidOperationException();
}
public static double Round(double Value, int Fpcr)
{
switch ((ARoundMode)((Fpcr >> 22) & 3))
{
case ARoundMode.ToNearest: return Math.Round (Value);
case ARoundMode.TowardsPlusInfinity: return Math.Ceiling (Value);
case ARoundMode.TowardsMinusInfinity: return Math.Floor (Value);
case ARoundMode.TowardsZero: return Math.Truncate(Value);
}
throw new InvalidOperationException();
}
public static AVec Tbl1_V64(AVec Vector, AVec Tb0) public static AVec Tbl1_V64(AVec Vector, AVec Tb0)
{ {
return Tbl(Vector, 8, Tb0); return Tbl(Vector, 8, Tb0);

View file

@ -0,0 +1,10 @@
namespace ChocolArm64.State
{
public enum ARoundMode
{
ToNearest = 0,
TowardsPlusInfinity = 1,
TowardsMinusInfinity = 2,
TowardsZero = 3
}
}

View file

@ -18,8 +18,8 @@ namespace ChocolArm64.Translation
private AILBlock ILBlock; private AILBlock ILBlock;
private AOpCode LastCmpOp; private AOpCode OptOpLastCompare;
private AOpCode LastFlagOp; private AOpCode OptOpLastFlagSet;
private int BlkIndex; private int BlkIndex;
private int OpcIndex; private int OpcIndex;
@ -75,6 +75,9 @@ namespace ChocolArm64.Translation
BlkIndex++; BlkIndex++;
OpcIndex = -1; OpcIndex = -1;
OptOpLastFlagSet = null;
OptOpLastCompare = null;
ILBlock = Emitter.GetILBlock(BlkIndex); ILBlock = Emitter.GetILBlock(BlkIndex);
} }
@ -120,7 +123,7 @@ namespace ChocolArm64.Translation
public void TryOptMarkCondWithoutCmp() public void TryOptMarkCondWithoutCmp()
{ {
LastCmpOp = CurrOp; OptOpLastCompare = CurrOp;
AInstEmitAluHelper.EmitDataLoadOpers(this); AInstEmitAluHelper.EmitDataLoadOpers(this);
@ -148,12 +151,13 @@ namespace ChocolArm64.Translation
int IntCond = (int)Cond; int IntCond = (int)Cond;
if (LastCmpOp != null && LastFlagOp == LastCmpOp && BranchOps.ContainsKey(Cond)) if (OptOpLastCompare != null &&
OptOpLastCompare == OptOpLastFlagSet && BranchOps.ContainsKey(Cond))
{ {
Ldloc(Tmp3Index, AIoType.Int, LastCmpOp.RegisterSize); Ldloc(Tmp3Index, AIoType.Int, OptOpLastCompare.RegisterSize);
Ldloc(Tmp4Index, AIoType.Int, LastCmpOp.RegisterSize); Ldloc(Tmp4Index, AIoType.Int, OptOpLastCompare.RegisterSize);
if (LastCmpOp.Emitter == AInstEmit.Adds) if (OptOpLastCompare.Emitter == AInstEmit.Adds)
{ {
Emit(OpCodes.Neg); Emit(OpCodes.Neg);
} }
@ -356,7 +360,7 @@ namespace ChocolArm64.Translation
public void EmitLdflg(int Index) => Ldloc(Index, AIoType.Flag); public void EmitLdflg(int Index) => Ldloc(Index, AIoType.Flag);
public void EmitStflg(int Index) public void EmitStflg(int Index)
{ {
LastFlagOp = CurrOp; OptOpLastFlagSet = CurrOp;
Stloc(Index, AIoType.Flag); Stloc(Index, AIoType.Flag);
} }

View file

@ -1,5 +1,3 @@
using ChocolArm64.Memory;
namespace Ryujinx.Core.OsHle namespace Ryujinx.Core.OsHle
{ {
static class MemoryRegions static class MemoryRegions

View file

@ -291,7 +291,10 @@ namespace Ryujinx.Core.OsHle.Objects.Android
BufferQueue[Slot].State = BufferState.Free; BufferQueue[Slot].State = BufferState.Free;
lock (WaitBufferFree)
{
WaitBufferFree.Set(); WaitBufferFree.Set();
}
}); });
} }
@ -316,6 +319,8 @@ namespace Ryujinx.Core.OsHle.Objects.Android
int Slot; int Slot;
do do
{
lock (WaitBufferFree)
{ {
if ((Slot = GetFreeSlot(Width, Height)) != -1) if ((Slot = GetFreeSlot(Width, Height)) != -1)
{ {
@ -324,8 +329,6 @@ namespace Ryujinx.Core.OsHle.Objects.Android
Logging.Debug("Waiting for a free BufferQueue slot..."); Logging.Debug("Waiting for a free BufferQueue slot...");
lock (WaitBufferFree)
{
if (!KeepRunning) if (!KeepRunning)
{ {
break; break;