diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-01-10 19:16:59 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-10 19:16:59 -0300 |
| commit | 5e0f8e873857ce3ca3f532aff0936beb28e412c8 (patch) | |
| tree | 576e5110c076b7d1f4d94e608ee21493f5b48879 /ARMeilleure/Translation/ArmEmitterContext.cs | |
| parent | d16288a2a87f0979df30ba69d4fe10660177b6ac (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.cs | 49 |
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) |
