diff options
Diffstat (limited to 'ARMeilleure')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitFlowHelper.cs | 2 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSimdCmp.cs | 18 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSimdCmp32.cs | 27 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSimdShift32.cs | 2 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSystem32.cs | 54 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/NativeInterface.cs | 26 | ||||
| -rw-r--r-- | ARMeilleure/State/FPCR.cs | 10 | ||||
| -rw-r--r-- | ARMeilleure/State/FPSR.cs | 8 | ||||
| -rw-r--r-- | ARMeilleure/State/FPState.cs | 7 | ||||
| -rw-r--r-- | ARMeilleure/State/PState.cs | 3 | ||||
| -rw-r--r-- | ARMeilleure/Translation/Delegates.cs | 1 |
11 files changed, 94 insertions, 64 deletions
diff --git a/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/ARMeilleure/Instructions/InstEmitFlowHelper.cs index 1ce0cdaa..87549aa3 100644 --- a/ARMeilleure/Instructions/InstEmitFlowHelper.cs +++ b/ARMeilleure/Instructions/InstEmitFlowHelper.cs @@ -242,7 +242,7 @@ namespace ARMeilleure.Instructions private static void EmitNativeCallWithGuestAddress(ArmEmitterContext context, Operand funcAddr, Operand guestAddress, bool isJump) { Operand nativeContextPtr = context.LoadArgument(OperandType.I64, 0); - context.Store(context.Add(nativeContextPtr, Const(NativeContext.GetCallAddressOffset())), guestAddress); + context.Store(context.Add(nativeContextPtr, Const((long)NativeContext.GetCallAddressOffset())), guestAddress); EmitNativeCall(context, nativeContextPtr, funcAddr, isJump); } diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp.cs b/ARMeilleure/Instructions/InstEmitSimdCmp.cs index ff97084b..22cf9f21 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp.cs @@ -538,9 +538,12 @@ namespace ARMeilleure.Instructions context.BranchIfFalse(lblNaN, isOrdered); - Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comissge, n, m); - Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisseq, n, m); - Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisslt, n, m); + Operand nCopy = context.Copy(n); + Operand mCopy = cmpWithZero ? context.VectorZero() : context.Copy(m); + + Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comissge, nCopy, mCopy); + Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisseq, nCopy, mCopy); + Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisslt, nCopy, mCopy); SetFlag(context, PState.VFlag, Const(0)); SetFlag(context, PState.CFlag, cf); @@ -555,9 +558,12 @@ namespace ARMeilleure.Instructions context.BranchIfFalse(lblNaN, isOrdered); - Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comisdge, n, m); - Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisdeq, n, m); - Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisdlt, n, m); + Operand nCopy = context.Copy(n); + Operand mCopy = cmpWithZero ? context.VectorZero() : context.Copy(m); + + Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comisdge, nCopy, mCopy); + Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisdeq, nCopy, mCopy); + Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisdlt, nCopy, mCopy); SetFlag(context, PState.VFlag, Const(0)); SetFlag(context, PState.CFlag, cf); diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index db925053..290cc17e 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -307,7 +307,10 @@ namespace ARMeilleure.Instructions Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisseq, n, m); Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisslt, n, m); - EmitSetFPSCRFlags(context, nf, zf, cf, Const(0)); + SetFpFlag(context, FPState.VFlag, Const(0)); + SetFpFlag(context, FPState.CFlag, cf); + SetFpFlag(context, FPState.ZFlag, zf); + SetFpFlag(context, FPState.NFlag, nf); } else { @@ -321,14 +324,20 @@ namespace ARMeilleure.Instructions Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisdeq, n, m); Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisdlt, n, m); - EmitSetFPSCRFlags(context, nf, zf, cf, Const(0)); + SetFpFlag(context, FPState.VFlag, Const(0)); + SetFpFlag(context, FPState.CFlag, cf); + SetFpFlag(context, FPState.ZFlag, zf); + SetFpFlag(context, FPState.NFlag, nf); } context.Branch(lblEnd); context.MarkLabel(lblNaN); - EmitSetFPSCRFlags(context, Const(3)); + SetFpFlag(context, FPState.VFlag, Const(1)); + SetFpFlag(context, FPState.CFlag, Const(1)); + SetFpFlag(context, FPState.ZFlag, Const(0)); + SetFpFlag(context, FPState.NFlag, Const(0)); context.MarkLabel(lblEnd); } @@ -354,11 +363,11 @@ namespace ARMeilleure.Instructions Operand nzcv = context.Call(info, ne, me, Const(signalNaNs)); - EmitSetFPSCRFlags(context, nzcv); + EmitSetFpscrNzcv(context, nzcv); } } - private static void EmitSetFPSCRFlags(ArmEmitterContext context, Operand nzcv) + private static void EmitSetFpscrNzcv(ArmEmitterContext context, Operand nzcv) { Operand Extract(Operand value, int bit) { @@ -378,14 +387,6 @@ namespace ARMeilleure.Instructions SetFpFlag(context, FPState.NFlag, Extract(nzcv, 3)); } - private static void EmitSetFPSCRFlags(ArmEmitterContext context, Operand n, Operand z, Operand c, Operand v) - { - SetFpFlag(context, FPState.VFlag, v); - SetFpFlag(context, FPState.CFlag, c); - SetFpFlag(context, FPState.ZFlag, z); - SetFpFlag(context, FPState.NFlag, n); - } - private static void EmitSse2OrAvxCmpOpF32(ArmEmitterContext context, CmpCondition cond, bool zero) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; diff --git a/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/ARMeilleure/Instructions/InstEmitSimdShift32.cs index 215fe1e8..f3c002db 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -289,7 +289,7 @@ namespace ARMeilleure.Instructions context.BranchIfFalse(lblNoSat, context.BitwiseOr(gt, lt)); - // TODO: Set QC (to 1) on FPSCR here. + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); context.MarkLabel(lblNoSat); diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs index 14f73c3a..fcd6fc8a 100644 --- a/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -186,14 +186,12 @@ namespace ARMeilleure.Instructions return; } - MethodInfo info; - switch (op.Sreg) { case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpscr)); break; + EmitGetFpscr(context); return; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 @@ -205,22 +203,18 @@ namespace ARMeilleure.Instructions default: throw new NotImplementedException($"Unknown VMRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - - SetIntA32(context, op.Rt, context.Call(info)); } public static void Vmsr(ArmEmitterContext context) { OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; - MethodInfo info; - switch (op.Sreg) { case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr)); break; + EmitSetFpscr(context); return; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 @@ -232,8 +226,6 @@ namespace ARMeilleure.Instructions default: throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - - context.Call(info, GetIntA32(context, op.Rt)); } private static void EmitSetNzcv(ArmEmitterContext context, Operand t) @@ -255,5 +247,47 @@ namespace ARMeilleure.Instructions SetFlag(context, PState.ZFlag, z); SetFlag(context, PState.NFlag, n); } + + private static void EmitGetFpscr(ArmEmitterContext context) + { + OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; + + Operand vSh = context.ShiftLeft(GetFpFlag(FPState.VFlag), Const((int)FPState.VFlag)); + Operand cSh = context.ShiftLeft(GetFpFlag(FPState.CFlag), Const((int)FPState.CFlag)); + Operand zSh = context.ShiftLeft(GetFpFlag(FPState.ZFlag), Const((int)FPState.ZFlag)); + Operand nSh = context.ShiftLeft(GetFpFlag(FPState.NFlag), Const((int)FPState.NFlag)); + + Operand nzcvSh = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh)); + + Operand fpscr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpscr))); + + SetIntA32(context, op.Rt, context.BitwiseOr(nzcvSh, fpscr)); + } + + private static void EmitSetFpscr(ArmEmitterContext context) + { + OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; + + Operand t = GetIntA32(context, op.Rt); + + Operand v = context.ShiftRightUI(t, Const((int)FPState.VFlag)); + v = context.BitwiseAnd(v, Const(1)); + + Operand c = context.ShiftRightUI(t, Const((int)FPState.CFlag)); + c = context.BitwiseAnd(c, Const(1)); + + Operand z = context.ShiftRightUI(t, Const((int)FPState.ZFlag)); + z = context.BitwiseAnd(z, Const(1)); + + Operand n = context.ShiftRightUI(t, Const((int)FPState.NFlag)); + n = context.BitwiseAnd(n, Const(1)); + + SetFpFlag(context, FPState.VFlag, v); + SetFpFlag(context, FPState.CFlag, c); + SetFpFlag(context, FPState.ZFlag, z); + SetFpFlag(context, FPState.NFlag, n); + + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr)), t); + } } } diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index e8f0db84..b4afcc02 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -87,14 +87,8 @@ namespace ARMeilleure.Instructions { var context = GetContext(); - uint result = (uint)(context.Fpsr & FPSR.A32Mask) | (uint)(context.Fpcr & FPCR.A32Mask); - - result |= context.GetFPstateFlag(FPState.NFlag) ? (1u << 31) : 0; - result |= context.GetFPstateFlag(FPState.ZFlag) ? (1u << 30) : 0; - result |= context.GetFPstateFlag(FPState.CFlag) ? (1u << 29) : 0; - result |= context.GetFPstateFlag(FPState.VFlag) ? (1u << 28) : 0; - - return result; + return (uint)(context.Fpsr & FPSR.A32Mask & ~FPSR.Nzcv) | + (uint)(context.Fpcr & FPCR.A32Mask); } public static ulong GetTpidrEl0() @@ -142,17 +136,17 @@ namespace ARMeilleure.Instructions GetContext().Fpsr = (FPSR)value; } - public static void SetFpscr(uint value) + public static void SetFpsrQc() { - var context = GetContext(); + GetContext().Fpsr |= FPSR.Qc; + } - context.SetFPstateFlag(FPState.NFlag, (value & (1u << 31)) != 0); - context.SetFPstateFlag(FPState.ZFlag, (value & (1u << 30)) != 0); - context.SetFPstateFlag(FPState.CFlag, (value & (1u << 29)) != 0); - context.SetFPstateFlag(FPState.VFlag, (value & (1u << 28)) != 0); + public static void SetFpscr(uint fpscr) + { + var context = GetContext(); - context.Fpsr = FPSR.A32Mask & (FPSR)value; - context.Fpcr = FPCR.A32Mask & (FPCR)value; + context.Fpsr = FPSR.A32Mask & (FPSR)fpscr; + context.Fpcr = FPCR.A32Mask & (FPCR)fpscr; } public static void SetTpidrEl0(ulong value) diff --git a/ARMeilleure/State/FPCR.cs b/ARMeilleure/State/FPCR.cs index 913065ea..40d56045 100644 --- a/ARMeilleure/State/FPCR.cs +++ b/ARMeilleure/State/FPCR.cs @@ -5,12 +5,12 @@ namespace ARMeilleure.State [Flags] public enum FPCR : uint { - Ufe = 1 << 11, - Fz = 1 << 24, - Dn = 1 << 25, - Ahp = 1 << 26, + Ufe = 1u << 11, + Fz = 1u << 24, + Dn = 1u << 25, + Ahp = 1u << 26, - A32Mask = 0x07ffff00 + A32Mask = 0x07FF9F00u } public static class FPCRExtensions diff --git a/ARMeilleure/State/FPSR.cs b/ARMeilleure/State/FPSR.cs index 47323b35..800dcd10 100644 --- a/ARMeilleure/State/FPSR.cs +++ b/ARMeilleure/State/FPSR.cs @@ -5,9 +5,11 @@ namespace ARMeilleure.State [Flags] public enum FPSR : uint { - Ufc = 1 << 3, - Qc = 1 << 27, + Ufc = 1u << 3, + Qc = 1u << 27, - A32Mask = 0xf800000f + Nzcv = (1u << 31) | (1u << 30) | (1u << 29) | (1u << 28), + + A32Mask = 0xF800009Fu } } diff --git a/ARMeilleure/State/FPState.cs b/ARMeilleure/State/FPState.cs index 2fe2a567..60c7126c 100644 --- a/ARMeilleure/State/FPState.cs +++ b/ARMeilleure/State/FPState.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.State +namespace ARMeilleure.State { - [Flags] public enum FPState { VFlag = 28, diff --git a/ARMeilleure/State/PState.cs b/ARMeilleure/State/PState.cs index 8dbd84df..e087e702 100644 --- a/ARMeilleure/State/PState.cs +++ b/ARMeilleure/State/PState.cs @@ -1,8 +1,5 @@ -using System; - namespace ARMeilleure.State { - [Flags] public enum PState { TFlag = 5, diff --git a/ARMeilleure/Translation/Delegates.cs b/ARMeilleure/Translation/Delegates.cs index 7c1951ed..88d01818 100644 --- a/ARMeilleure/Translation/Delegates.cs +++ b/ARMeilleure/Translation/Delegates.cs @@ -126,6 +126,7 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr))); + SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall))); |
