aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/State
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/State')
-rw-r--r--ARMeilleure/State/ExecutionContext.cs19
-rw-r--r--ARMeilleure/State/FPCR.cs19
-rw-r--r--ARMeilleure/State/FPSCR.cs15
-rw-r--r--ARMeilleure/State/FPSR.cs11
-rw-r--r--ARMeilleure/State/FPState.cs23
-rw-r--r--ARMeilleure/State/NativeContext.cs28
6 files changed, 97 insertions, 18 deletions
diff --git a/ARMeilleure/State/ExecutionContext.cs b/ARMeilleure/State/ExecutionContext.cs
index c73ca197..5d18e6ed 100644
--- a/ARMeilleure/State/ExecutionContext.cs
+++ b/ARMeilleure/State/ExecutionContext.cs
@@ -36,10 +36,25 @@ namespace ARMeilleure.State
set => _nativeContext.SetPstate(value);
}
- public FPCR Fpcr { get; set; }
- public FPSR Fpsr { get; set; }
+ public FPSR Fpsr
+ {
+ get => (FPSR)_nativeContext.GetFPState((uint)FPSR.Mask);
+ set => _nativeContext.SetFPState((uint)value, (uint)FPSR.Mask);
+ }
+
+ public FPCR Fpcr
+ {
+ get => (FPCR)_nativeContext.GetFPState((uint)FPCR.Mask);
+ set => _nativeContext.SetFPState((uint)value, (uint)FPCR.Mask);
+ }
public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;
+ public FPSCR Fpscr
+ {
+ get => (FPSCR)_nativeContext.GetFPState((uint)FPSCR.Mask);
+ set => _nativeContext.SetFPState((uint)value, (uint)FPSCR.Mask);
+ }
+
public bool IsAarch32 { get; set; }
internal ExecutionMode ExecutionMode
diff --git a/ARMeilleure/State/FPCR.cs b/ARMeilleure/State/FPCR.cs
index 40d56045..6f707de7 100644
--- a/ARMeilleure/State/FPCR.cs
+++ b/ARMeilleure/State/FPCR.cs
@@ -5,21 +5,18 @@ namespace ARMeilleure.State
[Flags]
public enum FPCR : uint
{
+ Ioe = 1u << 8,
+ Dze = 1u << 9,
+ Ofe = 1u << 10,
Ufe = 1u << 11,
+ Ixe = 1u << 12,
+ Ide = 1u << 15,
+ RMode0 = 1u << 22,
+ RMode1 = 1u << 23,
Fz = 1u << 24,
Dn = 1u << 25,
Ahp = 1u << 26,
- A32Mask = 0x07FF9F00u
- }
-
- public static class FPCRExtensions
- {
- private const int RModeShift = 22;
-
- public static FPRoundingMode GetRoundingMode(this FPCR fpcr)
- {
- return (FPRoundingMode)(((int)fpcr >> RModeShift) & 3);
- }
+ Mask = Ahp | Dn | Fz | RMode1 | RMode0 | Ide | Ixe | Ufe | Ofe | Dze | Ioe // 0x07C09F00u
}
}
diff --git a/ARMeilleure/State/FPSCR.cs b/ARMeilleure/State/FPSCR.cs
new file mode 100644
index 00000000..d6d2fc26
--- /dev/null
+++ b/ARMeilleure/State/FPSCR.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace ARMeilleure.State
+{
+ [Flags]
+ public enum FPSCR : uint
+ {
+ V = 1u << 28,
+ C = 1u << 29,
+ Z = 1u << 30,
+ N = 1u << 31,
+
+ Mask = N | Z | C | V | FPSR.Mask | FPCR.Mask // 0xFFC09F9Fu
+ }
+}
diff --git a/ARMeilleure/State/FPSR.cs b/ARMeilleure/State/FPSR.cs
index 800dcd10..5e66d5ce 100644
--- a/ARMeilleure/State/FPSR.cs
+++ b/ARMeilleure/State/FPSR.cs
@@ -5,11 +5,14 @@ namespace ARMeilleure.State
[Flags]
public enum FPSR : uint
{
+ Ioc = 1u << 0,
+ Dzc = 1u << 1,
+ Ofc = 1u << 2,
Ufc = 1u << 3,
- Qc = 1u << 27,
+ Ixc = 1u << 4,
+ Idc = 1u << 7,
+ Qc = 1u << 27,
- Nzcv = (1u << 31) | (1u << 30) | (1u << 29) | (1u << 28),
-
- A32Mask = 0xF800009Fu
+ Mask = Qc | Idc | Ixc | Ufc | Ofc | Dzc | Ioc // 0x0800009Fu
}
}
diff --git a/ARMeilleure/State/FPState.cs b/ARMeilleure/State/FPState.cs
index 60c7126c..fa6ab9d4 100644
--- a/ARMeilleure/State/FPState.cs
+++ b/ARMeilleure/State/FPState.cs
@@ -2,9 +2,30 @@
{
public enum FPState
{
+ // FPSR Flags.
+ IocFlag = 0,
+ DzcFlag = 1,
+ OfcFlag = 2,
+ UfcFlag = 3,
+ IxcFlag = 4,
+ IdcFlag = 7,
+ QcFlag = 27,
VFlag = 28,
CFlag = 29,
ZFlag = 30,
- NFlag = 31
+ NFlag = 31,
+
+ // FPCR Flags.
+ IoeFlag = 8,
+ DzeFlag = 9,
+ OfeFlag = 10,
+ UfeFlag = 11,
+ IxeFlag = 12,
+ IdeFlag = 15,
+ RMode0Flag = 22,
+ RMode1Flag = 23,
+ FzFlag = 24,
+ DnFlag = 25,
+ AhpFlag = 26
}
}
diff --git a/ARMeilleure/State/NativeContext.cs b/ARMeilleure/State/NativeContext.cs
index 11ab5ca3..89e875d1 100644
--- a/ARMeilleure/State/NativeContext.cs
+++ b/ARMeilleure/State/NativeContext.cs
@@ -140,6 +140,34 @@ namespace ARMeilleure.State
GetStorage().FpFlags[(int)flag] = value ? 1u : 0u;
}
+ public unsafe uint GetFPState(uint mask = uint.MaxValue)
+ {
+ uint value = 0;
+ for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++)
+ {
+ uint bit = 1u << flag;
+
+ if ((mask & bit) == bit)
+ {
+ value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
+ }
+ }
+ return value;
+ }
+
+ public unsafe void SetFPState(uint value, uint mask = uint.MaxValue)
+ {
+ for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++)
+ {
+ uint bit = 1u << flag;
+
+ if ((mask & bit) == bit)
+ {
+ GetStorage().FpFlags[flag] = (value & bit) == bit ? 1u : 0u;
+ }
+ }
+ }
+
public int GetCounter() => GetStorage().Counter;
public void SetCounter(int value) => GetStorage().Counter = value;