From 2bb9b33da1f872dc7e52b92c9f282e3d971d2cdf Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Fri, 5 Aug 2022 14:03:50 -0300
Subject: Implement Arm32 Sha256 and MRS Rd, CPSR instructions (#3544)

* Implement Arm32 Sha256 and MRS Rd, CPSR instructions

* Add tests using Arm64 outputs
---
 ARMeilleure/Instructions/InstEmitSimdHash32.cs | 64 ++++++++++++++++++++++++++
 ARMeilleure/Instructions/InstEmitSystem32.cs   | 25 ++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 ARMeilleure/Instructions/InstEmitSimdHash32.cs

(limited to 'ARMeilleure/Instructions')

diff --git a/ARMeilleure/Instructions/InstEmitSimdHash32.cs b/ARMeilleure/Instructions/InstEmitSimdHash32.cs
new file mode 100644
index 00000000..e19d364d
--- /dev/null
+++ b/ARMeilleure/Instructions/InstEmitSimdHash32.cs
@@ -0,0 +1,64 @@
+using ARMeilleure.Decoders;
+using ARMeilleure.IntermediateRepresentation;
+using ARMeilleure.Translation;
+
+using static ARMeilleure.Instructions.InstEmitHelper;
+
+namespace ARMeilleure.Instructions
+{
+    static partial class InstEmit32
+    {
+#region "Sha256"
+        public static void Sha256h_V(ArmEmitterContext context)
+        {
+            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
+
+            Operand d = GetVecA32(op.Qd);
+            Operand n = GetVecA32(op.Qn);
+            Operand m = GetVecA32(op.Qm);
+
+            Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)), d, n, m);
+
+            context.Copy(GetVecA32(op.Qd), res);
+        }
+
+        public static void Sha256h2_V(ArmEmitterContext context)
+        {
+            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
+
+            Operand d = GetVecA32(op.Qd);
+            Operand n = GetVecA32(op.Qn);
+            Operand m = GetVecA32(op.Qm);
+
+            Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)), d, n, m);
+
+            context.Copy(GetVecA32(op.Qd), res);
+        }
+
+        public static void Sha256su0_V(ArmEmitterContext context)
+        {
+            OpCode32Simd op = (OpCode32Simd)context.CurrOp;
+
+            Operand d = GetVecA32(op.Qd);
+            Operand m = GetVecA32(op.Qm);
+
+            Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), d, m);
+
+            context.Copy(GetVecA32(op.Qd), res);
+        }
+
+        public static void Sha256su1_V(ArmEmitterContext context)
+        {
+            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
+
+            Operand d = GetVecA32(op.Qd);
+            Operand n = GetVecA32(op.Qn);
+            Operand m = GetVecA32(op.Qm);
+
+            Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), d, n, m);
+
+            context.Copy(GetVecA32(op.Qd), res);
+        }
+#endregion
+    }
+}
diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs
index 3e752659..674a4438 100644
--- a/ARMeilleure/Instructions/InstEmitSystem32.cs
+++ b/ARMeilleure/Instructions/InstEmitSystem32.cs
@@ -169,6 +169,31 @@ namespace ARMeilleure.Instructions
             SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32))));
         }
 
+        public static void Mrs(ArmEmitterContext context)
+        {
+            OpCode32Mrs op = (OpCode32Mrs)context.CurrOp;
+
+            if (op.R)
+            {
+                throw new NotImplementedException("SPSR");
+            }
+            else
+            {
+                Operand vSh = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag));
+                Operand cSh = context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag));
+                Operand zSh = context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag));
+                Operand nSh = context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag));
+                Operand qSh = context.ShiftLeft(GetFlag(PState.QFlag), Const((int)PState.QFlag));
+
+                Operand spsr = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh));
+                spsr = context.BitwiseOr(spsr, qSh);
+
+                // TODO: Remaining flags.
+
+                SetIntA32(context, op.Rd, spsr);
+            }
+        }
+
         public static void Msr(ArmEmitterContext context)
         {
             OpCode32MsrReg op = (OpCode32MsrReg)context.CurrOp;
-- 
cgit v1.2.3-70-g09d2