diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2020-08-08 17:18:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-08 17:18:51 +0200 |
| commit | e36e97c64d7b973fbbc3ac92e9f115d74a4d9e2d (patch) | |
| tree | 80bdb45273e6bbc0d862276bdb6f6551b0a2541d /ARMeilleure/Instructions/InstEmitSystem32.cs | |
| parent | 8d59ad88b4d59ef6ad26b9a747dc871fd1f1007a (diff) | |
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.
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSystem32.cs')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSystem32.cs | 54 |
1 files changed, 44 insertions, 10 deletions
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); + } } } |
