Improve access to system registers by using properties, also use exclusive region granularity on exclusive load/stores, and ensure that acquires without releases won't hold the address forever, remove unused ALU rev method

This commit is contained in:
gdkchan 2018-02-06 12:15:08 -03:00
parent 6ae5587b5e
commit 2347c44bbf
9 changed files with 130 additions and 138 deletions

View file

@ -1,8 +0,0 @@
namespace ChocolArm64.State
{
public enum ACoreType
{
CortexA53,
CortexA57
}
}

View file

@ -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));