aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-02-24 11:19:28 -0300
committergdkchan <gab.dark.100@gmail.com>2018-02-24 11:19:28 -0300
commit035efc913e7f2a68315d4206cef46672005b8442 (patch)
treeeeb130850da914eb18e50ab5106db801b2eb4b14
parent3936c934482a587635bc5a1e47962551aeb53aeb (diff)
Fix cpu issue with cmp optimization, add HINT and FRINTX (scalar) instructions, fix for NvFlinger sometimes missing free buffers
-rw-r--r--ChocolArm64/AOpCodeTable.cs2
-rw-r--r--ChocolArm64/ATranslator.cs6
-rw-r--r--ChocolArm64/Decoder/AOpCodeSimd.cs2
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs26
-rw-r--r--ChocolArm64/Instruction/AInstEmitSystem.cs5
-rw-r--r--ChocolArm64/Instruction/ASoftFallback.cs26
-rw-r--r--ChocolArm64/State/ARoundMode.cs10
-rw-r--r--ChocolArm64/Translation/AILEmitterCtx.cs22
-rw-r--r--Ryujinx.Core/OsHle/MemoryRegions.cs2
-rw-r--r--Ryujinx.Core/OsHle/Objects/Android/NvFlinger.cs17
10 files changed, 95 insertions, 23 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index b8fe278d..71a944cf 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -51,6 +51,7 @@ namespace ChocolArm64
Set("x10100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluImm));
Set("x1001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor, typeof(AOpCodeAluRs));
Set("x00100111x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Extr, typeof(AOpCodeAluRs));
+ Set("11010101000000110010xxxxxxx11111", AInstEmit.Hint, typeof(AOpCodeSystem));
Set("xx001000110xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldar, typeof(AOpCodeMemEx));
Set("1x001000011xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxp, typeof(AOpCodeMemEx));
Set("xx001000010xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxr, typeof(AOpCodeMemEx));
@@ -193,6 +194,7 @@ namespace ChocolArm64
Set("000111100x100110010000xxxxxxxxxx", AInstEmit.Frinta_S, typeof(AOpCodeSimd));
Set("000111100x100101010000xxxxxxxxxx", AInstEmit.Frintm_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("000111100x1xxxxx001110xxxxxxxxxx", AInstEmit.Fsub_S, typeof(AOpCodeSimdReg));
Set("0>0011101<1xxxxx110101xxxxxxxxxx", AInstEmit.Fsub_V, typeof(AOpCodeSimdReg));
diff --git a/ChocolArm64/ATranslator.cs b/ChocolArm64/ATranslator.cs
index 96bbc89e..04cef44f 100644
--- a/ChocolArm64/ATranslator.cs
+++ b/ChocolArm64/ATranslator.cs
@@ -6,7 +6,7 @@ using System.Reflection.Emit;
namespace ChocolArm64
{
- class ATranslator
+ public class ATranslator
{
public AThread Thread { get; private set; }
@@ -41,7 +41,7 @@ namespace ChocolArm64
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)
{
@@ -53,7 +53,7 @@ namespace ChocolArm64
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);
}
diff --git a/ChocolArm64/Decoder/AOpCodeSimd.cs b/ChocolArm64/Decoder/AOpCodeSimd.cs
index 5f940b22..41708517 100644
--- a/ChocolArm64/Decoder/AOpCodeSimd.cs
+++ b/ChocolArm64/Decoder/AOpCodeSimd.cs
@@ -10,8 +10,6 @@ namespace ChocolArm64.Decoder
public int Opc { get; private set; }
public int Size { get; protected set; }
- public int SizeF => Size & 1;
-
public AOpCodeSimd(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{
Rd = (OpCode >> 0) & 0x1f;
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 6665f219..e1fd56e0 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -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)
{
EmitScalarUnaryOpF(Context, () =>
diff --git a/ChocolArm64/Instruction/AInstEmitSystem.cs b/ChocolArm64/Instruction/AInstEmitSystem.cs
index 6754be7a..f9d18602 100644
--- a/ChocolArm64/Instruction/AInstEmitSystem.cs
+++ b/ChocolArm64/Instruction/AInstEmitSystem.cs
@@ -9,6 +9,11 @@ namespace ChocolArm64.Instruction
{
static partial class AInstEmit
{
+ public static void Hint(AILEmitterCtx Context)
+ {
+ //Execute as no-op.
+ }
+
public static void Mrs(AILEmitterCtx Context)
{
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs
index a57966ba..5127182d 100644
--- a/ChocolArm64/Instruction/ASoftFallback.cs
+++ b/ChocolArm64/Instruction/ASoftFallback.cs
@@ -189,6 +189,32 @@ namespace ChocolArm64.Instruction
(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)
{
return Tbl(Vector, 8, Tb0);
diff --git a/ChocolArm64/State/ARoundMode.cs b/ChocolArm64/State/ARoundMode.cs
new file mode 100644
index 00000000..9896f307
--- /dev/null
+++ b/ChocolArm64/State/ARoundMode.cs
@@ -0,0 +1,10 @@
+namespace ChocolArm64.State
+{
+ public enum ARoundMode
+ {
+ ToNearest = 0,
+ TowardsPlusInfinity = 1,
+ TowardsMinusInfinity = 2,
+ TowardsZero = 3
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/Translation/AILEmitterCtx.cs b/ChocolArm64/Translation/AILEmitterCtx.cs
index cf644540..9199eddc 100644
--- a/ChocolArm64/Translation/AILEmitterCtx.cs
+++ b/ChocolArm64/Translation/AILEmitterCtx.cs
@@ -18,8 +18,8 @@ namespace ChocolArm64.Translation
private AILBlock ILBlock;
- private AOpCode LastCmpOp;
- private AOpCode LastFlagOp;
+ private AOpCode OptOpLastCompare;
+ private AOpCode OptOpLastFlagSet;
private int BlkIndex;
private int OpcIndex;
@@ -75,6 +75,9 @@ namespace ChocolArm64.Translation
BlkIndex++;
OpcIndex = -1;
+ OptOpLastFlagSet = null;
+ OptOpLastCompare = null;
+
ILBlock = Emitter.GetILBlock(BlkIndex);
}
@@ -120,7 +123,7 @@ namespace ChocolArm64.Translation
public void TryOptMarkCondWithoutCmp()
{
- LastCmpOp = CurrOp;
+ OptOpLastCompare = CurrOp;
AInstEmitAluHelper.EmitDataLoadOpers(this);
@@ -146,14 +149,15 @@ namespace ChocolArm64.Translation
{
OpCode ILOp;
- 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(Tmp4Index, AIoType.Int, LastCmpOp.RegisterSize);
+ Ldloc(Tmp3Index, AIoType.Int, OptOpLastCompare.RegisterSize);
+ Ldloc(Tmp4Index, AIoType.Int, OptOpLastCompare.RegisterSize);
- if (LastCmpOp.Emitter == AInstEmit.Adds)
+ if (OptOpLastCompare.Emitter == AInstEmit.Adds)
{
Emit(OpCodes.Neg);
}
@@ -356,7 +360,7 @@ namespace ChocolArm64.Translation
public void EmitLdflg(int Index) => Ldloc(Index, AIoType.Flag);
public void EmitStflg(int Index)
{
- LastFlagOp = CurrOp;
+ OptOpLastFlagSet = CurrOp;
Stloc(Index, AIoType.Flag);
}
diff --git a/Ryujinx.Core/OsHle/MemoryRegions.cs b/Ryujinx.Core/OsHle/MemoryRegions.cs
index e8ededc8..86d266f6 100644
--- a/Ryujinx.Core/OsHle/MemoryRegions.cs
+++ b/Ryujinx.Core/OsHle/MemoryRegions.cs
@@ -1,5 +1,3 @@
-using ChocolArm64.Memory;
-
namespace Ryujinx.Core.OsHle
{
static class MemoryRegions
diff --git a/Ryujinx.Core/OsHle/Objects/Android/NvFlinger.cs b/Ryujinx.Core/OsHle/Objects/Android/NvFlinger.cs
index 54588383..11069cb2 100644
--- a/Ryujinx.Core/OsHle/Objects/Android/NvFlinger.cs
+++ b/Ryujinx.Core/OsHle/Objects/Android/NvFlinger.cs
@@ -291,7 +291,10 @@ namespace Ryujinx.Core.OsHle.Objects.Android
BufferQueue[Slot].State = BufferState.Free;
- WaitBufferFree.Set();
+ lock (WaitBufferFree)
+ {
+ WaitBufferFree.Set();
+ }
});
}
@@ -317,15 +320,15 @@ namespace Ryujinx.Core.OsHle.Objects.Android
do
{
- if ((Slot = GetFreeSlot(Width, Height)) != -1)
+ lock (WaitBufferFree)
{
- break;
- }
+ if ((Slot = GetFreeSlot(Width, Height)) != -1)
+ {
+ break;
+ }
- Logging.Debug("Waiting for a free BufferQueue slot...");
+ Logging.Debug("Waiting for a free BufferQueue slot...");
- lock (WaitBufferFree)
- {
if (!KeepRunning)
{
break;