From e36e97c64d7b973fbbc3ac92e9f115d74a4d9e2d Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:18:51 +0200 Subject: CPU: This PR fixes Fpscr, among other things. (#1433) * CPU: This PR fixes Fpscr, among other things. * Add Fpscr.Qc = 1 if sat. for Vqrshrn & Vqrshrun. * Fix Vcmp & Vcmpe opcode table. * Revert "Fix Vcmp & Vcmpe opcode table." This reverts commit c117d9410d693185ff5f8ee8e457ffbfb2027dd5. * Address PR feedbacks. --- ARMeilleure/Instructions/InstEmitSystem32.cs | 54 ++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'ARMeilleure/Instructions/InstEmitSystem32.cs') 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); + } } } -- cgit v1.2.3