aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-02-12 00:37:20 -0300
committergdkchan <gab.dark.100@gmail.com>2018-02-12 00:37:20 -0300
commit7d11a146c097a0bcf8b78e3aeab73a96fa8bc19c (patch)
tree7436a101f388696dbd72336b546d2c5b9d2df8cc
parent9e8d99f30deb4872fb5507c6d1d7fdaf6d1ea638 (diff)
Generate CIL for SCVTF (vector), add undefined encodings for some instructions
-rw-r--r--Ryujinx/Cpu/AOpCodeTable.cs71
-rw-r--r--Ryujinx/Cpu/Decoder/AOpCodeAluImm.cs2
-rw-r--r--Ryujinx/Cpu/Decoder/AOpCodeAluRs.cs14
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitException.cs14
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSimd.cs275
-rw-r--r--Ryujinx/Cpu/Instruction/ASoftFallback.cs193
-rw-r--r--Ryujinx/Cpu/State/ARegisters.cs14
7 files changed, 319 insertions, 264 deletions
diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index b61326a4..dcc0f6aa 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -11,11 +11,11 @@ namespace ChocolArm64
#region "OpCode Table"
//Integer
Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs));
- Set("x0010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
- Set("x0001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
+ Set("x00100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
+ Set("x0001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx));
- Set("x0110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm));
- Set("x0101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs));
+ Set("x01100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm));
+ Set("x0101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs));
Set("x0101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRx));
Set("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adr, typeof(AOpCodeAdr));
Set("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adrp, typeof(AOpCodeAdr));
@@ -102,11 +102,11 @@ namespace ChocolArm64
Set("xx111000001xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeMemReg));
Set("1x001000001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxp, typeof(AOpCodeMemEx));
Set("xx001000000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxr, typeof(AOpCodeMemEx));
- Set("x1010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm));
- Set("x1001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs));
+ Set("x10100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm));
+ Set("x1001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs));
Set("x1001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRx));
- Set("x1110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm));
- Set("x1101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs));
+ Set("x11100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm));
+ Set("x1101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs));
Set("x1101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRx));
Set("11010100000xxxxxxxxxxxxxxxx00001", AInstEmit.Svc, typeof(AOpCodeException));
Set("1101010100001xxxxxxxxxxxxxxxxxxx", AInstEmit.Sys, typeof(AOpCodeSystem));
@@ -119,24 +119,25 @@ namespace ChocolArm64
Set("10011011110xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umulh, typeof(AOpCodeMul));
//Vector
- Set("0x001110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V, typeof(AOpCodeSimdReg));
+ Set("0>001110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V, typeof(AOpCodeSimdReg));
Set("01011110xx110001101110xxxxxxxxxx", AInstEmit.Addp_S, typeof(AOpCodeSimd));
- Set("0x001110xx1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg));
- Set("0x001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
+ Set("0>001110<<1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg));
+ Set("000011100x110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
+ Set("01001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg));
Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg));
Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm));
Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
- Set("0x101110xx1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
- Set("0x001110xx100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
- Set("0x001110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
- Set("0x101110xx100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
- Set("0x001110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
- Set("0x001110xx100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
- Set("0x101110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
- Set("0x101110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
- Set("0x101110xx100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
- Set("0x001110xx100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
+ Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
+ Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
+ Set("0>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
+ Set("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
+ Set("0>001110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
+ Set("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
+ Set("0>101110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
+ Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
+ Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
+ Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
@@ -199,26 +200,28 @@ namespace ChocolArm64
Set("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm));
Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg));
Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit));
- Set("0x001110xx1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg));
+ Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg));
Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0xx0111100000xxx111001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
- Set("0x001110xx1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V, typeof(AOpCodeSimdReg));
+ Set("0x001110<<1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V, typeof(AOpCodeSimdReg));
Set("0x10111100000xxx0xx001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
Set("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
Set("0x10111100000xxx110x01xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
- Set("0x101110xx100000101110xxxxxxxxxx", AInstEmit.Neg_V, typeof(AOpCodeSimdReg));
+ Set("0>101110<<100000101110xxxxxxxxxx", AInstEmit.Neg_V, typeof(AOpCodeSimdReg));
Set("0x10111000100000010110xxxxxxxxxx", AInstEmit.Not_V, typeof(AOpCodeSimd));
Set("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg));
Set("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm));
Set("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg));
+ Set("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
+ Set("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
Set("0x0011100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_V, typeof(AOpCodeSimd));
Set("010111110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_S, typeof(AOpCodeSimdShImm));
Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V, typeof(AOpCodeSimdShImm));
Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg));
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
- Set("0x001110xx1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
+ Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
@@ -231,9 +234,7 @@ namespace ChocolArm64
Set("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm));
Set("xx111100x01xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemReg));
Set("01111110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_S, typeof(AOpCodeSimdReg));
- Set("0x101110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg));
- Set("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
- Set("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
+ Set("0>101110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg));
Set("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl));
Set("001011100x110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd));
Set("01101110<<110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd));
@@ -241,7 +242,7 @@ namespace ChocolArm64
Set("x0011110xx100011000000xxxxxxxxxx", AInstEmit.Ucvtf_Gp, typeof(AOpCodeSimdCvt));
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimdReg));
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
- Set("0x101110xx1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
+ Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
Set("0x1011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm));
Set("0x1011110>>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
@@ -311,9 +312,13 @@ namespace ChocolArm64
{
InsertTop(XMask, Value, Inst);
}
- else if ((ZCount & OCount) != 0)
+ else if (ZCount != 0 && OCount != 0)
{
- for (int OCtr = 0; (uint)OCtr < (1 << OCount) - 1; OCtr++)
+ //When both the > and the <, then a value is blacklisted,
+ //with > indicating 0, and < indicating 1. So, for example, ><<
+ //blacklists the pattern 011, but 000, 001, 010, 100, 101,
+ //110 and 111 are valid.
+ for (int OCtr = 0; (uint)OCtr < (1 << OCount); OCtr++)
{
int OVal = Value;
@@ -322,7 +327,9 @@ namespace ChocolArm64
OVal |= ((OCtr >> O) & 1) << OPos[O];
}
- InsertWithCtr(1, 1 << ZCount, ZCount, ZPos, XMask, OVal, Inst);
+ int ZStart = OCtr == (1 << OCount) ? 1 : 0;
+
+ InsertWithCtr(ZStart, 1 << ZCount, ZCount, ZPos, XMask, OVal, Inst);
}
}
else if (ZCount != 0)
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeAluImm.cs b/Ryujinx/Cpu/Decoder/AOpCodeAluImm.cs
index 6b0adbc2..e913475a 100644
--- a/Ryujinx/Cpu/Decoder/AOpCodeAluImm.cs
+++ b/Ryujinx/Cpu/Decoder/AOpCodeAluImm.cs
@@ -15,8 +15,6 @@ namespace ChocolArm64.Decoder
int Shift = (OpCode >> 22) & 3;
- //Assert Shift < 2
-
Imm <<= Shift * 12;
}
else if (DataOp == ADataOp.Logical)
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeAluRs.cs b/Ryujinx/Cpu/Decoder/AOpCodeAluRs.cs
index 8439df6f..9c215be3 100644
--- a/Ryujinx/Cpu/Decoder/AOpCodeAluRs.cs
+++ b/Ryujinx/Cpu/Decoder/AOpCodeAluRs.cs
@@ -11,11 +11,19 @@ namespace ChocolArm64.Decoder
public AOpCodeAluRs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{
- Shift = (OpCode >> 10) & 0x3f;
+ int Shift = (OpCode >> 10) & 0x3f;
+
+ if (Shift >= GetBitsCount())
+ {
+ Emitter = AInstEmit.Und;
+
+ return;
+ }
+
+ this.Shift = Shift;
+
Rm = (OpCode >> 16) & 0x1f;
ShiftType = (AShiftType)((OpCode >> 22) & 0x3);
-
- //Assert ShiftType != 3
}
}
} \ No newline at end of file
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitException.cs b/Ryujinx/Cpu/Instruction/AInstEmitException.cs
index f05d962f..085bb9aa 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitException.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitException.cs
@@ -1,12 +1,14 @@
using ChocolArm64.Decoder;
using ChocolArm64.State;
using ChocolArm64.Translation;
-using System;
+using System.Reflection;
namespace ChocolArm64.Instruction
{
static partial class AInstEmit
{
+ private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
+
public static void Brk(AILEmitterCtx Context)
{
EmitExceptionCall(Context, nameof(ARegisters.OnBreak));
@@ -27,7 +29,9 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Op.Id);
- Context.EmitCall(typeof(ARegisters), MthdName);
+ MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding);
+
+ Context.EmitCall(MthdInfo);
if (Context.CurrBlock.Next != null)
{
@@ -46,7 +50,11 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I8(Op.Position);
Context.EmitLdc_I4(Op.RawOpCode);
- Context.EmitCall(typeof(ARegisters), nameof(ARegisters.OnUndefined));
+ string MthdName = nameof(ARegisters.OnUndefined);
+
+ MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding);
+
+ Context.EmitCall(MthdInfo);
if (Context.CurrBlock.Next != null)
{
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
index 75c308c3..3ff65ea4 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
@@ -104,8 +104,8 @@ namespace ChocolArm64.Instruction
public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add);
- public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvtS(Context);
- public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtU(Context);
+ public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvts(Context);
+ public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtu(Context);
public static void Fmla_V(AILEmitterCtx Context)
{
@@ -264,19 +264,7 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
- public static void Scvtf_V(AILEmitterCtx Context)
- {
- AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Scvtf_V64),
- nameof(ASoftFallback.Scvtf_V128));
-
- Context.EmitStvec(Op.Rd);
- }
+ public static void Scvtf_V(AILEmitterCtx Context) => EmitVectorScvtf(Context);
public static void Shl_V(AILEmitterCtx Context)
{
@@ -346,7 +334,7 @@ namespace ChocolArm64.Instruction
nameof(ASoftFallback.Tbl4_V128)); break;
default: throw new InvalidOperationException();
- }
+ }
Context.EmitStvec(Op.Rd);
}
@@ -434,33 +422,12 @@ namespace ChocolArm64.Instruction
public static void Ushr_V(AILEmitterCtx Context)
{
- AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
- Context.EmitLdc_I4(Op.Size);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Ushr64),
- nameof(ASoftFallback.Ushr128));
-
- Context.EmitStvec(Op.Rd);
+ EmitVectorShr(Context, ShrFlags.None);
}
public static void Usra_V(AILEmitterCtx Context)
{
- AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rd);
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
- Context.EmitLdc_I4(Op.Size);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Usra64),
- nameof(ASoftFallback.Usra128));
-
- Context.EmitStvec(Op.Rd);
+ EmitVectorShr(Context, ShrFlags.Accumulate);
}
public static void Uzp1_V(AILEmitterCtx Context)
@@ -651,11 +618,11 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(0);
Context.EmitLdc_I4(Op.Size);
- EmitVectorExtractZx(Context, Op.Rn, 0);
+ EmitVectorExtractZx(Context, Op.Rn, 0, Op.Size);
for (int Index = 1; Index < (Bytes >> Op.Size); Index++)
{
- EmitVectorExtractZx(Context, Op.Rn, Index);
+ EmitVectorExtractZx(Context, Op.Rn, Op.Size, Index);
Context.Emit(OpCodes.Add);
}
@@ -730,7 +697,7 @@ namespace ChocolArm64.Instruction
int MaxShift = 8 << Op.Size;
- EmitVectorBinaryZx(Context, () =>
+ Action Emit = () =>
{
AILLabel LblShl = new AILLabel();
AILLabel LblZero = new AILLabel();
@@ -771,80 +738,147 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I8(0);
Context.MarkLabel(LblEnd);
- });
+ };
+
+ if (Signed)
+ {
+ EmitVectorBinarySx(Context, Emit);
+ }
+ else
+ {
+ EmitVectorBinaryZx(Context, Emit);
+ }
}
- private static void EmitVectorFcvtS(AILEmitterCtx Context)
+ private enum ShrFlags
{
- EmitVectorCvtOp(Context, CvtDir.Fcvt, true);
+ None = 0,
+ Signed = 1 << 0,
+ Rounding = 1 << 1,
+ Accumulate = 1 << 2
+ }
+
+ private static void EmitVectorShr(AILEmitterCtx Context, ShrFlags Flags)
+ {
+ AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
+
+ int Shift = (8 << (Op.Size + 1)) - Op.Imm;
+
+ if (Flags.HasFlag(ShrFlags.Accumulate))
+ {
+ Action Emit = () =>
+ {
+ Context.EmitLdc_I4(Shift);
+
+ Context.Emit(OpCodes.Shr_Un);
+ Context.Emit(OpCodes.Add);
+ };
+
+ EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false);
+ }
+ else
+ {
+ EmitVectorUnaryZx(Context, () =>
+ {
+ Context.EmitLdc_I4(Shift);
+
+ Context.Emit(OpCodes.Shr_Un);
+ });
+ }
}
- private static void EmitVectorFcvtU(AILEmitterCtx Context)
+ private static void EmitVectorFcvts(AILEmitterCtx Context)
{
- EmitVectorCvtOp(Context, CvtDir.Fcvt, false);
+ EmitVectorFcvtOp(Context, Signed: true);
}
- private static void EmitVectorCvtfS(AILEmitterCtx Context)
+ private static void EmitVectorFcvtu(AILEmitterCtx Context)
{
- EmitVectorCvtOp(Context, CvtDir.Cvtf, true);
+ EmitVectorFcvtOp(Context, Signed: false);
}
- private static void EmitVectorCvtfU(AILEmitterCtx Context)
+ private static void EmitVectorScvtf(AILEmitterCtx Context)
{
- EmitVectorCvtOp(Context, CvtDir.Cvtf, false);
+ EmitVectorCvtfOp(Context, Signed: true);
}
- private enum CvtDir
+ private static void EmitVectorUcvtf(AILEmitterCtx Context)
{
- Fcvt,
- Cvtf
+ EmitVectorCvtfOp(Context, Signed: false);
}
- private static void EmitVectorCvtOp(AILEmitterCtx Context, CvtDir Dir, bool Signed)
+ private static void EmitVectorFcvtOp(AILEmitterCtx Context, bool Signed)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int SizeF = Op.Size & 1;
int SizeI = SizeF + 2;
- int FBits = 0;
+ int FBits = GetFBits(Context);
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ for (int Index = 0; Index < (Bytes >> SizeI); Index++)
+ {
+ EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+
+ Context.EmitLdc_I4(FBits);
+
+ if (SizeF == 0)
+ {
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.SatSingleToInt32)
+ : nameof(ASoftFallback.SatSingleToUInt32));
+ }
+ else if (SizeF == 1)
+ {
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.SatDoubleToInt64)
+ : nameof(ASoftFallback.SatDoubleToUInt64));
+ }
- if (Op is AOpCodeSimdShImm OpImm)
+ EmitVectorInsert(Context, Op.Rd, Index, SizeI);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
{
- FBits = (8 << (Op.Size + 1)) - OpImm.Imm;
+ EmitVectorZeroUpper(Context, Op.Rd);
}
+ }
+
+ private static void EmitVectorCvtfOp(AILEmitterCtx Context, bool Signed)
+ {
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+ int SizeF = Op.Size & 1;
+ int SizeI = SizeF + 2;
+
+ int FBits = GetFBits(Context);
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
for (int Index = 0; Index < (Bytes >> SizeI); Index++)
{
- EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+ EmitVectorExtract(Context, Op.Rn, Index, SizeI, Signed);
Context.EmitLdc_I4(FBits);
- if (Dir == CvtDir.Fcvt)
+ if (SizeF == 0)
{
- //Float to Integer.
- if (SizeF == 0)
- {
- ASoftFallback.EmitCall(Context, Signed
- ? nameof(ASoftFallback.SatSingleToInt32)
- : nameof(ASoftFallback.SatSingleToUInt32));
- }
- else if (SizeF == 1)
- {
- ASoftFallback.EmitCall(Context, Signed
- ? nameof(ASoftFallback.SatDoubleToInt64)
- : nameof(ASoftFallback.SatDoubleToUInt64));
- }
+ Context.Emit(OpCodes.Conv_I4);
+
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.Int32ToSingle)
+ : nameof(ASoftFallback.UInt32ToSingle));
}
- else if (Dir == CvtDir.Cvtf)
+ else if (SizeF == 1)
{
- //Integer to Float.
- //TODO.
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.Int64ToDouble)
+ : nameof(ASoftFallback.UInt64ToDouble));
}
- EmitVectorInsert(Context, Op.Rd, Index, SizeI);
+ EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
}
if (Op.RegisterSize == ARegisterSize.SIMD64)
@@ -853,6 +887,16 @@ namespace ChocolArm64.Instruction
}
}
+ private static int GetFBits(AILEmitterCtx Context)
+ {
+ if (Context.CurrOp is AOpCodeSimdShImm Op)
+ {
+ return (8 << (Op.Size + 1)) - Op.Imm;
+ }
+
+ return 0;
+ }
+
private static void EmitVectorBinaryFOp(AILEmitterCtx Context, OpCode ILOp)
{
EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp));
@@ -899,36 +943,43 @@ namespace ChocolArm64.Instruction
private static void EmitVectorUnarySx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorOp(Context, Emit, 1, true);
+ EmitVectorOp(Context, Emit, OperFlags.Rn, true);
}
private static void EmitVectorBinarySx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorOp(Context, Emit, 2, true);
+ EmitVectorOp(Context, Emit, OperFlags.RnRm, true);
}
private static void EmitVectorUnaryZx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorOp(Context, Emit, 1, false);
+ EmitVectorOp(Context, Emit, OperFlags.Rn, false);
}
private static void EmitVectorBinaryZx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorOp(Context, Emit, 2, false);
+ EmitVectorOp(Context, Emit, OperFlags.RnRm, false);
}
private static void EmitVectorTernaryZx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorOp(Context, Emit, 3, false);
+ EmitVectorOp(Context, Emit, OperFlags.RdRnRm, false);
}
- private static void EmitVectorOp(AILEmitterCtx Context, Action Emit, int Opers, bool Signed)
+ [Flags]
+ private enum OperFlags
{
- if (Opers < 1 || Opers > 3)
- {
- throw new ArgumentOutOfRangeException(nameof(Opers));
- }
+ Rd = 1 << 0,
+ Rn = 1 << 1,
+ Rm = 1 << 2,
+
+ RnRm = Rn | Rm,
+ RdRn = Rd | Rn,
+ RdRnRm = Rd | Rn | Rm
+ }
+ private static void EmitVectorOp(AILEmitterCtx Context, Action Emit, OperFlags Opers, bool Signed)
+ {
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
@@ -939,19 +990,19 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size);
- if (Opers == 3)
+ if (Opers.HasFlag(OperFlags.Rd))
{
- EmitVectorExtract(Context, Op.Rd, Index, Signed);
+ EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
}
- if (Opers >= 1)
+ if (Opers.HasFlag(OperFlags.Rn))
{
- EmitVectorExtract(Context, Op.Rn, Index, Signed);
+ EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
}
- if (Opers >= 2)
+ if (Opers.HasFlag(OperFlags.Rm))
{
- EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Signed);
+ EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
}
Emit();
@@ -999,7 +1050,7 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size);
- EmitVectorExtract(Context, Op.Rn, Index, Signed);
+ EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
Context.EmitLdc_I8(Imm);
@@ -1026,11 +1077,11 @@ namespace ChocolArm64.Instruction
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
{
- EmitVectorExtractSx(Context, Op.Rn, Index);
+ EmitVectorExtractSx(Context, Op.Rn, Index, Op.Size);
if (Op is AOpCodeSimdReg BinOp)
{
- EmitVectorExtractSx(Context, BinOp.Rm, Index);
+ EmitVectorExtractSx(Context, BinOp.Rm, Index, Op.Size);
}
else
{
@@ -1078,29 +1129,39 @@ namespace ChocolArm64.Instruction
}
}
- private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index)
+ private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index, int Size)
{
- EmitVectorExtract(Context, Reg, Index, true);
+ EmitVectorExtract(Context, Reg, Index, Size, true);
}
- private static void EmitVectorExtractZx(AILEmitterCtx Context, int Reg, int Index)
+ private static void EmitVectorExtractZx(AILEmitterCtx Context, int Reg, int Index, int Size)
{
- EmitVectorExtract(Context, Reg, Index, false);
+ EmitVectorExtract(Context, Reg, Index, Size, false);
}
- private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed)
+ private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, int Size, bool Signed)
{
IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
Context.EmitLdvec(Reg);
Context.EmitLdc_I4(Index);
- Context.EmitLdc_I4(Op.Size);
+ Context.EmitLdc_I4(Size);
ASoftFallback.EmitCall(Context, Signed
? nameof(ASoftFallback.ExtractSVec)
: nameof(ASoftFallback.ExtractVec));
}
+ private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
+ {
+ EmitVectorInsert(Context, Rd, 0, 3, 0);
+ }
+
+ private static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
+ {
+ EmitVectorInsert(Context, Rd, 1, 3, 0);
+ }
+
private static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
{
Context.EmitLdvec(Reg);
@@ -1122,16 +1183,6 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Reg);
}
- private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
- {
- EmitVectorInsert(Context, Rd, 0, 3, 0);
- }
-
- private static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
- {
- EmitVectorInsert(Context, Rd, 1, 3, 0);
- }
-
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size)
{
Context.EmitLdvec(Reg);
diff --git a/Ryujinx/Cpu/Instruction/ASoftFallback.cs b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
index a7508d7f..8fe31a22 100644
--- a/Ryujinx/Cpu/Instruction/ASoftFallback.cs
+++ b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
@@ -97,70 +97,142 @@ namespace ChocolArm64.Instruction
throw new ArgumentException(nameof(Size));
}
- public static int SatDoubleToInt32(double Value, int FBits = 0)
+ public static int SatSingleToInt32(float Value, int FBits)
{
- if (FBits != 0) Value *= Math.Pow(2, FBits);
+ if (FBits != 0) Value *= MathF.Pow(2, FBits);
return Value > int.MaxValue ? int.MaxValue :
Value < int.MinValue ? int.MinValue : (int)Value;
}
- public static long SatDoubleToInt64(double Value, int FBits = 0)
+ public static long SatSingleToInt64(float Value, int FBits)
{
- if (FBits != 0) Value *= Math.Pow(2, FBits);
+ if (FBits != 0) Value *= MathF.Pow(2, FBits);
return Value > long.MaxValue ? long.MaxValue :
Value < long.MinValue ? long.MinValue : (long)Value;
}
- public static uint SatDoubleToUInt32(double Value, int FBits = 0)
+ public static uint SatSingleToUInt32(float Value, int FBits)
{
- if (FBits != 0) Value *= Math.Pow(2, FBits);
+ if (FBits != 0) Value *= MathF.Pow(2, FBits);
return Value > uint.MaxValue ? uint.MaxValue :
Value < uint.MinValue ? uint.MinValue : (uint)Value;
}
- public static ulong SatDoubleToUInt64(double Value, int FBits = 0)
+ public static ulong SatSingleToUInt64(float Value, int FBits)
{
- if (FBits != 0) Value *= Math.Pow(2, FBits);
+ if (FBits != 0) Value *= MathF.Pow(2, FBits);
return Value > ulong.MaxValue ? ulong.MaxValue :
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
}
- public static int SatSingleToInt32(float Value, int FBits = 0)
+ public static int SatDoubleToInt32(double Value, int FBits)
{
- if (FBits != 0) Value *= MathF.Pow(2, FBits);
+ if (FBits != 0) Value *= Math.Pow(2, FBits);
return Value > int.MaxValue ? int.MaxValue :
Value < int.MinValue ? int.MinValue : (int)Value;
}
- public static long SatSingleToInt64(float Value, int FBits = 0)
+ public static long SatDoubleToInt64(double Value, int FBits)
{
- if (FBits != 0) Value *= MathF.Pow(2, FBits);
+ if (FBits != 0) Value *= Math.Pow(2, FBits);
return Value > long.MaxValue ? long.MaxValue :
Value < long.MinValue ? long.MinValue : (long)Value;
}
- public static uint SatSingleToUInt32(float Value, int FBits = 0)
+ public static uint SatDoubleToUInt32(double Value, int FBits)
{
- if (FBits != 0) Value *= MathF.Pow(2, FBits);
+ if (FBits != 0) Value *= Math.Pow(2, FBits);
return Value > uint.MaxValue ? uint.MaxValue :
Value < uint.MinValue ? uint.MinValue : (uint)Value;
}
- public static ulong SatSingleToUInt64(float Value, int FBits = 0)
+ public static ulong SatDoubleToUInt64(double Value, int FBits)
{
- if (FBits != 0) Value *= MathF.Pow(2, FBits);
+ if (FBits != 0) Value *= Math.Pow(2, FBits);
return Value > ulong.MaxValue ? ulong.MaxValue :
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
}
+ public static float Int32ToSingle(int Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float Int64ToSingle(long Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float UInt32ToSingle(uint Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float UInt64ToSingle(ulong Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float Int32ToDouble(int Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float Int64ToDouble(long Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float UInt32ToDouble(uint Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
+ public static float UInt64ToDouble(ulong Value, int FBits)
+ {
+ float ValueF = Value;
+
+ if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
+
+ return ValueF;
+ }
+
public static ulong SMulHi128(ulong LHS, ulong RHS)
{
long LLo = (uint)(LHS >> 0);
@@ -556,44 +628,6 @@ namespace ChocolArm64.Instruction
return Res;
}
- public static AVec Scvtf_V64(AVec Vector, int Size)
- {
- return Scvtf_V(Vector, Size, 2);
- }
-
- public static AVec Scvtf_V128(AVec Vector, int Size)
- {
- return Scvtf_V(Vector, Size, 4);
- }
-
- private static AVec Scvtf_V(AVec Vector, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- int Value = (int)ExtractSVec(Vector, Index, Size + 2);
-
- Res = AVec.InsertSingle(Res, Index, Value);
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- long Value = ExtractSVec(Vector, Index, Size + 2);
-
- Res = AVec.InsertDouble(Res, Index, Value);
- }
- }
-
- return Res;
- }
-
public static AVec Sshll(AVec Vector, int Shift, int Size)
{
return Sshll_(Vector, Shift, Size, false);
@@ -785,57 +819,6 @@ namespace ChocolArm64.Instruction
return Res;
}
- public static AVec Ushr64(AVec Vector, int Shift, int Size)
- {
- return Ushr(Vector, Shift, Size, 8);
- }
-
- public static AVec Ushr128(AVec Vector, int Shift, int Size)
- {
- return Ushr(Vector, Shift, Size, 16);
- }
-
- private static AVec Ushr(AVec Vector, int Shift, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- for (int Index = 0; Index < Elems; Index++)
- {
- ulong Value = ExtractVec(Vector, Index, Size);
-
- Res = InsertVec(Res, Index, Size, Value >> Shift);
- }
-
- return Res;
- }
-
- public static AVec Usra64(AVec Res, AVec Vector, int Shift, int Size)
- {
- return Usra(Res, Vector, Shift, Size, 8);
- }
-
- public static AVec Usra128(AVec Res, AVec Vector, int Shift, int Size)
- {
- return Usra(Res, Vector, Shift, Size, 16);
- }
-
- private static AVec Usra(AVec Res, AVec Vector, int Shift, int Size, int Bytes)
- {
- int Elems = Bytes >> Size;
-
- for (int Index = 0; Index < Elems; Index++)
- {
- ulong Value = ExtractVec(Vector, Index, Size);
- ulong Addend = ExtractVec(Res, Index, Size);
-
- Res = InsertVec(Res, Index, Size, Addend + (Value >> Shift));
- }
-
- return Res;
- }
-
public static AVec Uzp1_V64(AVec LHS, AVec RHS, int Size)
{
return Uzp(LHS, RHS, Size, 0, 8);
diff --git a/Ryujinx/Cpu/State/ARegisters.cs b/Ryujinx/Cpu/State/ARegisters.cs
index 07656724..bb93699d 100644
--- a/Ryujinx/Cpu/State/ARegisters.cs
+++ b/Ryujinx/Cpu/State/ARegisters.cs
@@ -10,9 +10,6 @@ namespace ChocolArm64.State
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,
@@ -40,23 +37,26 @@ namespace ChocolArm64.State
public uint CtrEl0 => 0x8444c004;
public uint DczidEl0 => 0x00000004;
+ private const long TicksPerS = 19_200_000;
+ private const long TicksPerMS = TicksPerS / 1_000;
+
public long CntpctEl0 => Environment.TickCount * TicksPerMS;
public event EventHandler<AInstExceptEventArgs> Break;
public event EventHandler<AInstExceptEventArgs> SvcCall;
- public event EventHandler<AInstUndEventArgs> Undefined;
+ public event EventHandler<AInstUndEventArgs> Undefined;
- public void OnBreak(int Imm)
+ internal void OnBreak(int Imm)
{
Break?.Invoke(this, new AInstExceptEventArgs(Imm));
}
- public void OnSvcCall(int Imm)
+ internal void OnSvcCall(int Imm)
{
SvcCall?.Invoke(this, new AInstExceptEventArgs(Imm));
}
- public void OnUndefined(long Position, int RawOpCode)
+ internal void OnUndefined(long Position, int RawOpCode)
{
Undefined?.Invoke(this, new AInstUndEventArgs(Position, RawOpCode));
}