aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitAlu.cs11
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSystem.cs84
-rw-r--r--Ryujinx/Cpu/Memory/AMemory.cs19
-rw-r--r--Ryujinx/Cpu/State/ACoreType.cs8
-rw-r--r--Ryujinx/Cpu/State/ARegisters.cs98
-rw-r--r--Ryujinx/Cpu/Translation/AILEmitterCtx.cs38
-rw-r--r--Ryujinx/OsHle/Objects/AudIAudioRenderer.cs2
-rw-r--r--Ryujinx/OsHle/Process.cs4
-rw-r--r--Ryujinx/OsHle/Svc/SvcSystem.cs4
9 files changed, 130 insertions, 138 deletions
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
index c09b1863..f963f6f7 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
@@ -175,17 +175,6 @@ namespace ChocolArm64.Instruction
Context.EmitStintzr(Op.Rd);
}
- private static void EmitRev(AILEmitterCtx Context, string Name)
- {
- AOpCodeAlu Op = (AOpCodeAlu)Context.CurrOp;
-
- Context.EmitLdintzr(Op.Rn);
-
- ASoftFallback.EmitCall(Context, Name);
-
- Context.EmitStintzr(Op.Rd);
- }
-
public static void Rorv(AILEmitterCtx Context)
{
EmitDataLoadRn(Context);
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSystem.cs b/Ryujinx/Cpu/Instruction/AInstEmitSystem.cs
index 23a0b6b2..9a6333cd 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSystem.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSystem.cs
@@ -1,6 +1,8 @@
using ChocolArm64.Decoder;
using ChocolArm64.State;
using ChocolArm64.Translation;
+using System;
+using System.Reflection;
using System.Reflection.Emit;
namespace ChocolArm64.Instruction
@@ -13,13 +15,30 @@ namespace ChocolArm64.Instruction
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx);
- Context.EmitLdc_I4(Op.Op0);
- Context.EmitLdc_I4(Op.Op1);
- Context.EmitLdc_I4(Op.CRn);
- Context.EmitLdc_I4(Op.CRm);
- Context.EmitLdc_I4(Op.Op2);
+ string PropName;
- Context.EmitCall(typeof(ARegisters), nameof(ARegisters.GetSystemReg));
+ switch (GetPackedId(Op))
+ {
+ case 0b11_011_0000_0000_001: PropName = nameof(ARegisters.CtrEl0); break;
+ case 0b11_011_0000_0000_111: PropName = nameof(ARegisters.DczidEl0); break;
+ case 0b11_011_0100_0100_000: PropName = nameof(ARegisters.Fpcr); break;
+ case 0b11_011_0100_0100_001: PropName = nameof(ARegisters.Fpsr); break;
+ case 0b11_011_1101_0000_010: PropName = nameof(ARegisters.TpidrEl0); break;
+ case 0b11_011_1101_0000_011: PropName = nameof(ARegisters.Tpidr); break;
+ case 0b11_011_1110_0000_001: PropName = nameof(ARegisters.CntpctEl0); break;
+
+ default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}");
+ }
+
+ Context.EmitCallPropGet(typeof(ARegisters), PropName);
+
+ PropertyInfo PropInfo = typeof(ARegisters).GetProperty(PropName);
+
+ if (PropInfo.PropertyType != typeof(long) &&
+ PropInfo.PropertyType != typeof(ulong))
+ {
+ Context.Emit(OpCodes.Conv_U8);
+ }
Context.EmitStintzr(Op.Rt);
}
@@ -29,15 +48,28 @@ namespace ChocolArm64.Instruction
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx);
-
- Context.EmitLdc_I4(Op.Op0);
- Context.EmitLdc_I4(Op.Op1);
- Context.EmitLdc_I4(Op.CRn);
- Context.EmitLdc_I4(Op.CRm);
- Context.EmitLdc_I4(Op.Op2);
Context.EmitLdintzr(Op.Rt);
- Context.EmitCall(typeof(ARegisters), nameof(ARegisters.SetSystemReg));
+ string PropName;
+
+ switch (GetPackedId(Op))
+ {
+ case 0b11_011_0100_0100_000: PropName = nameof(ARegisters.Fpcr); break;
+ case 0b11_011_0100_0100_001: PropName = nameof(ARegisters.Fpsr); break;
+ case 0b11_011_1101_0000_010: PropName = nameof(ARegisters.TpidrEl0); break;
+
+ default: throw new NotImplementedException($"Unknown MSR at {Op.Position:x16}");
+ }
+
+ PropertyInfo PropInfo = typeof(ARegisters).GetProperty(PropName);
+
+ if (PropInfo.PropertyType != typeof(long) &&
+ PropInfo.PropertyType != typeof(ulong))
+ {
+ Context.Emit(OpCodes.Conv_U4);
+ }
+
+ Context.EmitCallPropSet(typeof(ARegisters), PropName);
}
public static void Nop(AILEmitterCtx Context)
@@ -52,19 +84,12 @@ namespace ChocolArm64.Instruction
//We treat it as no-op here since we don't have any cache being emulated anyway.
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
- int Id;
-
- Id = Op.Op2 << 0;
- Id |= Op.CRm << 3;
- Id |= Op.CRn << 7;
- Id |= Op.Op1 << 11;
-
- switch (Id)
+ switch (GetPackedId(Op))
{
- case 0b011_0111_0100_001:
+ case 0b11_011_0111_0100_001:
{
//DC ZVA
- for (int Offs = 0; Offs < 64; Offs += 8)
+ for (int Offs = 0; Offs < (4 << ARegisters.DczSizeLog2); Offs += 8)
{
Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
Context.EmitLdint(Op.Rt);
@@ -80,5 +105,18 @@ namespace ChocolArm64.Instruction
}
}
}
+
+ private static int GetPackedId(AOpCodeSystem Op)
+ {
+ int Id;
+
+ Id = Op.Op2 << 0;
+ Id |= Op.CRm << 3;
+ Id |= Op.CRn << 7;
+ Id |= Op.Op1 << 11;
+ Id |= Op.Op0 << 14;
+
+ return Id;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx/Cpu/Memory/AMemory.cs b/Ryujinx/Cpu/Memory/AMemory.cs
index 4e9bd53f..af1c75bf 100644
--- a/Ryujinx/Cpu/Memory/AMemory.cs
+++ b/Ryujinx/Cpu/Memory/AMemory.cs
@@ -6,6 +6,8 @@ namespace ChocolArm64.Memory
{
public unsafe class AMemory
{
+ private const long ErgMask = (4 << ARegisters.ErgSizeLog2) - 1;
+
public AMemoryMgr Manager { get; private set; }
private struct ExMonitor
@@ -52,6 +54,11 @@ namespace ChocolArm64.Memory
{
lock (Monitors)
{
+ if (Monitors.TryGetValue(ThreadId, out ExMonitor Monitor))
+ {
+ ExAddrs.Remove(Monitor.Position);
+ }
+
Monitors.Remove(ThreadId);
}
}
@@ -60,14 +67,16 @@ namespace ChocolArm64.Memory
{
lock (Monitors)
{
- bool ExState = !ExAddrs.Contains(Position);
+ Position &= ~ErgMask;
- if (ExState)
+ if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor))
{
- ExAddrs.Add(Position);
+ ExAddrs.Remove(Monitor.Position);
}
- ExMonitor Monitor = new ExMonitor(Position, ExState);
+ bool ExState = ExAddrs.Add(Position);
+
+ Monitor = new ExMonitor(Position, ExState);
if (!Monitors.TryAdd(Registers.ThreadId, Monitor))
{
@@ -80,6 +89,8 @@ namespace ChocolArm64.Memory
{
lock (Monitors)
{
+ Position &= ~ErgMask;
+
if (!Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor))
{
return false;
diff --git a/Ryujinx/Cpu/State/ACoreType.cs b/Ryujinx/Cpu/State/ACoreType.cs
deleted file mode 100644
index 3fed78cf..00000000
--- a/Ryujinx/Cpu/State/ACoreType.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace ChocolArm64.State
-{
- public enum ACoreType
- {
- CortexA53,
- CortexA57
- }
-} \ No newline at end of file
diff --git a/Ryujinx/Cpu/State/ARegisters.cs b/Ryujinx/Cpu/State/ARegisters.cs
index 3a424a7f..76b8f9b3 100644
--- a/Ryujinx/Cpu/State/ARegisters.cs
+++ b/Ryujinx/Cpu/State/ARegisters.cs
@@ -7,6 +7,12 @@ namespace ChocolArm64.State
internal const int LRIndex = 30;
internal const int ZRIndex = 31;
+ internal const int ErgSizeLog2 = 4;
+ internal const int DczSizeLog2 = 4;
+
+ private const long TicksPerS = 19_200_000;
+ private const long TicksPerMS = TicksPerS / 1_000;
+
public ulong X0, X1, X2, X3, X4, X5, X6, X7,
X8, X9, X10, X11, X12, X13, X14, X15,
X16, X17, X18, X19, X20, X21, X22, X23,
@@ -22,97 +28,23 @@ namespace ChocolArm64.State
public bool Zero;
public bool Negative;
- public int ProcessId;
- public int ThreadId;
- public long TlsAddrEl0;
- public long TlsAddr;
+ public int ProcessId;
+ public int ThreadId;
- private int FPCR;
- private int FPSR;
+ public long TpidrEl0 { get; set; }
+ public long Tpidr { get; set; }
- public ACoreType CoreType;
+ public int Fpcr { get; set; }
+ public int Fpsr { get; set; }
- private const ulong A53DczidEl0 = 4;
- private const ulong A53CtrEl0 = 0x84448004;
- private const ulong A57CtrEl0 = 0x8444c004;
+ public uint CtrEl0 => 0x8444c004;
+ public uint DczidEl0 => 0x00000004;
- private const ulong TicksPerS = 19_200_000;
- private const ulong TicksPerMS = TicksPerS / 1_000;
+ public long CntpctEl0 => Environment.TickCount * TicksPerMS;
public event EventHandler<SvcEventArgs> SvcCall;
public event EventHandler<EventArgs> Undefined;
- public ulong GetSystemReg(int Op0, int Op1, int CRn, int CRm, int Op2)
- {
- switch (PackRegId(Op0, Op1, CRn, CRm, Op2))
- {
- case 0b11_011_0000_0000_001: return GetCtrEl0();
- case 0b11_011_0000_0000_111: return GetDczidEl0();
- case 0b11_011_0100_0100_000: return (ulong)PackFPCR();
- case 0b11_011_0100_0100_001: return (ulong)PackFPSR();
- case 0b11_011_1101_0000_010: return (ulong)TlsAddrEl0;
- case 0b11_011_1101_0000_011: return (ulong)TlsAddr;
- case 0b11_011_1110_0000_001: return (ulong)Environment.TickCount * TicksPerMS;
-
- default: throw new ArgumentException();
- }
- }
-
- public void SetSystemReg(int Op0, int Op1, int CRn, int CRm, int Op2, ulong Value)
- {
- switch (PackRegId(Op0, Op1, CRn, CRm, Op2))
- {
- case 0b11_011_0100_0100_000: UnpackFPCR((int)Value); break;
- case 0b11_011_0100_0100_001: UnpackFPSR((int)Value); break;
- case 0b11_011_1101_0000_010: TlsAddrEl0 = (long)Value; break;
-
- default: throw new ArgumentException();
- }
- }
-
- private int PackRegId(int Op0, int Op1, int CRn, int CRm, int Op2)
- {
- int Id;
-
- Id = Op2 << 0;
- Id |= CRm << 3;
- Id |= CRn << 7;
- Id |= Op1 << 11;
- Id |= Op0 << 14;
-
- return Id;
- }
-
- public ulong GetCtrEl0()
- {
- return CoreType == ACoreType.CortexA53 ? A53CtrEl0 : A57CtrEl0;
- }
-
- public ulong GetDczidEl0()
- {
- return A53DczidEl0;
- }
-
- public int PackFPCR()
- {
- return FPCR; //TODO
- }
-
- public int PackFPSR()
- {
- return FPSR; //TODO
- }
-
- public void UnpackFPCR(int Value)
- {
- FPCR = Value;
- }
-
- public void UnpackFPSR(int Value)
- {
- FPSR = Value;
- }
-
public void OnSvcCall(int Imm)
{
SvcCall?.Invoke(this, new SvcEventArgs(Imm));
diff --git a/Ryujinx/Cpu/Translation/AILEmitterCtx.cs b/Ryujinx/Cpu/Translation/AILEmitterCtx.cs
index 88841db7..bf56db21 100644
--- a/Ryujinx/Cpu/Translation/AILEmitterCtx.cs
+++ b/Ryujinx/Cpu/Translation/AILEmitterCtx.cs
@@ -467,11 +467,41 @@ namespace ChocolArm64.Translation
throw new ArgumentOutOfRangeException(nameof(Size));
}
- public void EmitCall(Type MthdType, string MthdName)
+ public void EmitCallPropGet(Type ObjType, string PropName)
{
- if (MthdType == null)
+ if (ObjType == null)
{
- throw new ArgumentNullException(nameof(MthdType));
+ throw new ArgumentNullException(nameof(ObjType));
+ }
+
+ if (PropName == null)
+ {
+ throw new ArgumentNullException(nameof(PropName));
+ }
+
+ EmitCall(ObjType.GetMethod($"get_{PropName}"));
+ }
+
+ public void EmitCallPropSet(Type ObjType, string PropName)
+ {
+ if (ObjType == null)
+ {
+ throw new ArgumentNullException(nameof(ObjType));
+ }
+
+ if (PropName == null)
+ {
+ throw new ArgumentNullException(nameof(PropName));
+ }
+
+ EmitCall(ObjType.GetMethod($"set_{PropName}"));
+ }
+
+ public void EmitCall(Type ObjType, string MthdName)
+ {
+ if (ObjType == null)
+ {
+ throw new ArgumentNullException(nameof(ObjType));
}
if (MthdName == null)
@@ -479,7 +509,7 @@ namespace ChocolArm64.Translation
throw new ArgumentNullException(nameof(MthdName));
}
- EmitCall(MthdType.GetMethod(MthdName));
+ EmitCall(ObjType.GetMethod(MthdName));
}
public void EmitCall(MethodInfo MthdInfo)
diff --git a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs b/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
index b451d07b..84ac4e04 100644
--- a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
+++ b/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
@@ -19,7 +19,7 @@ namespace Ryujinx.OsHle.Objects
{
Context.Memory.WriteInt32(Position + Offset, 5);
}
-
+
return 0;
}
diff --git a/Ryujinx/OsHle/Process.cs b/Ryujinx/OsHle/Process.cs
index 1cfae929..3f72527e 100644
--- a/Ryujinx/OsHle/Process.cs
+++ b/Ryujinx/OsHle/Process.cs
@@ -138,7 +138,7 @@ namespace Ryujinx.OsHle
Thread.Registers.SvcCall += SvcHandler.SvcCall;
Thread.Registers.ProcessId = ProcessId;
Thread.Registers.ThreadId = Ns.Os.IdGen.GenerateId();
- Thread.Registers.TlsAddr = TlsPageAddr + TlsSlot * TlsSize;
+ Thread.Registers.Tpidr = TlsPageAddr + TlsSlot * TlsSize;
Thread.Registers.X0 = (ulong)ArgsPtr;
Thread.Registers.X1 = (ulong)Handle;
Thread.Registers.X31 = (ulong)StackTop;
@@ -165,7 +165,7 @@ namespace Ryujinx.OsHle
{
if (sender is AThread Thread)
{
- TlsSlots.TryRemove(GetTlsSlot(Thread.Registers.TlsAddr), out _);
+ TlsSlots.TryRemove(GetTlsSlot(Thread.Registers.Tpidr), out _);
Ns.Os.IdGen.DeleteId(Thread.ThreadId);
}
diff --git a/Ryujinx/OsHle/Svc/SvcSystem.cs b/Ryujinx/OsHle/Svc/SvcSystem.cs
index 6f614d16..75d04830 100644
--- a/Ryujinx/OsHle/Svc/SvcSystem.cs
+++ b/Ryujinx/OsHle/Svc/SvcSystem.cs
@@ -39,7 +39,7 @@ namespace Ryujinx.OsHle.Svc
private static void SvcGetSystemTick(Switch Ns, ARegisters Registers, AMemory Memory)
{
- Registers.X0 = (ulong)Registers.GetSystemReg(3, 3, 14, 0, 1);
+ Registers.X0 = (ulong)Registers.CntpctEl0;
}
private static void SvcConnectToNamedPort(Switch Ns, ARegisters Registers, AMemory Memory)
@@ -70,7 +70,7 @@ namespace Ryujinx.OsHle.Svc
private static void SendSyncRequest(Switch Ns, ARegisters Registers, AMemory Memory, bool IsUser)
{
- long CmdPtr = Registers.TlsAddr;
+ long CmdPtr = Registers.Tpidr;
long Size = 0x100;
int Handle = 0;