aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/ArmEmitterContext.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-01-10 19:16:59 -0300
committerGitHub <noreply@github.com>2023-01-10 19:16:59 -0300
commit5e0f8e873857ce3ca3f532aff0936beb28e412c8 (patch)
tree576e5110c076b7d1f4d94e608ee21493f5b48879 /ARMeilleure/Translation/ArmEmitterContext.cs
parentd16288a2a87f0979df30ba69d4fe10660177b6ac (diff)
Implement JIT Arm64 backend (#4114)
* Implement JIT Arm64 backend * PPTC version bump * Address some feedback from Arm64 JIT PR * Address even more PR feedback * Remove unused IsPageAligned function * Sync Qc flag before calls * Fix comment and remove unused enum * Address riperiperi PR feedback * Delete Breakpoint IR instruction that was only implemented for Arm64
Diffstat (limited to 'ARMeilleure/Translation/ArmEmitterContext.cs')
-rw-r--r--ARMeilleure/Translation/ArmEmitterContext.cs49
1 files changed, 49 insertions, 0 deletions
diff --git a/ARMeilleure/Translation/ArmEmitterContext.cs b/ARMeilleure/Translation/ArmEmitterContext.cs
index 48254de4..238f8508 100644
--- a/ARMeilleure/Translation/ArmEmitterContext.cs
+++ b/ARMeilleure/Translation/ArmEmitterContext.cs
@@ -39,6 +39,8 @@ namespace ARMeilleure.Translation
}
}
+ private bool _pendingQcFlagSync;
+
public OpCode CurrOp { get; set; }
public IMemoryManager Memory { get; }
@@ -81,6 +83,8 @@ namespace ARMeilleure.Translation
public override Operand Call(MethodInfo info, params Operand[] callArgs)
{
+ SyncQcFlag();
+
if (!HasPtc)
{
return base.Call(info, callArgs);
@@ -139,6 +143,51 @@ namespace ARMeilleure.Translation
_optOpLastFlagSet = null;
}
+ public void SetPendingQcFlagSync()
+ {
+ _pendingQcFlagSync = true;
+ }
+
+ public void SyncQcFlag()
+ {
+ if (_pendingQcFlagSync)
+ {
+ if (Optimizations.UseAdvSimd)
+ {
+ Operand fpsr = AddIntrinsicInt(Intrinsic.Arm64MrsFpsr);
+
+ uint qcFlagMask = (uint)FPSR.Qc;
+
+ Operand qcClearLabel = Label();
+
+ BranchIfFalse(qcClearLabel, BitwiseAnd(fpsr, Const(qcFlagMask)));
+
+ AddIntrinsicNoRet(Intrinsic.Arm64MsrFpsr, Const(0));
+ InstEmitHelper.SetFpFlag(this, FPState.QcFlag, Const(1));
+
+ MarkLabel(qcClearLabel);
+ }
+
+ _pendingQcFlagSync = false;
+ }
+ }
+
+ public void ClearQcFlag()
+ {
+ if (Optimizations.UseAdvSimd)
+ {
+ AddIntrinsicNoRet(Intrinsic.Arm64MsrFpsr, Const(0));
+ }
+ }
+
+ public void ClearQcFlagIfModified()
+ {
+ if (_pendingQcFlagSync && Optimizations.UseAdvSimd)
+ {
+ AddIntrinsicNoRet(Intrinsic.Arm64MsrFpsr, Const(0));
+ }
+ }
+
public Operand TryGetComparisonResult(Condition condition)
{
if (_optOpLastCompare == null || _optOpLastCompare != _optOpLastFlagSet)