From 5e0f8e873857ce3ca3f532aff0936beb28e412c8 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 10 Jan 2023 19:16:59 -0300 Subject: 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 --- ARMeilleure/Translation/ArmEmitterContext.cs | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'ARMeilleure/Translation/ArmEmitterContext.cs') 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) -- cgit v1.2.3