gdkchan před 8 roky
rodič
revize
5a0396efaf

+ 1 - 1
Ryujinx/Cpu/ATranslator.cs

@@ -38,7 +38,7 @@ namespace ChocolArm64
                     Position = TranslateSubroutine(Position).Execute(Thread.Registers, Thread.Memory);
                 }
             }
-            while (Position != 0 && KeepRunning);
+            while (Position != 0 && KeepRunning); 
         }
 
         public bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)

+ 13 - 1
Ryujinx/Cpu/Instruction/AInstEmitAlu.cs

@@ -60,6 +60,8 @@ namespace ChocolArm64.Instruction
 
             Context.Emit(OpCodes.And);
 
+            EmitZeroCVFlags(Context);
+
             Context.EmitZNFlagCheck();
 
             EmitDataStoreS(Context);
@@ -79,6 +81,8 @@ namespace ChocolArm64.Instruction
 
             if (SetFlags)
             {
+                EmitZeroCVFlags(Context);
+
                 Context.EmitZNFlagCheck();
             }
 
@@ -334,6 +338,14 @@ namespace ChocolArm64.Instruction
             {
                 Context.Emit(OpCodes.Conv_I4);
             }
-        }        
+        }
+
+        private static void EmitZeroCVFlags(AILEmitterCtx Context)
+        {
+            Context.EmitLdc_I4(0);
+            Context.EmitLdc_I4(0);
+            Context.EmitStflg((int)APState.VBit);
+            Context.EmitStflg((int)APState.CBit);
+        }
     }
 }

+ 49 - 20
Ryujinx/Cpu/Instruction/AInstEmitSimdMemory.cs

@@ -1,6 +1,7 @@
 using ChocolArm64.Decoder;
 using ChocolArm64.State;
 using ChocolArm64.Translation;
+using System;
 using System.Reflection.Emit;
 
 using static ChocolArm64.Instruction.AInstEmitMemoryHelper;
@@ -85,45 +86,73 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdMemSs Op = (AOpCodeSimdMemSs)Context.CurrOp;
 
-            //TODO: Replicate mode.
-
             int Offset = 0;
 
-            for (int SElem = 0; SElem < Op.SElems; SElem++)
+            void EmitMemAddress()
             {
-                int Rt = (Op.Rt + SElem) & 0x1f;
+                Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
+                Context.EmitLdint(Op.Rn);
+                Context.EmitLdc_I8(Offset);
 
-                if (IsLoad)
+                Context.Emit(OpCodes.Add);
+            }
+
+            if (Op.Replicate)
+            {
+                //Only loads uses the replicate mode.
+                if (!IsLoad)
                 {
-                    Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
-                    Context.EmitLdint(Op.Rn);
-                    Context.EmitLdc_I8(Offset);
+                    throw new InvalidOperationException();
+                }
 
-                    Context.Emit(OpCodes.Add);
+                int Bytes = Context.CurrOp.GetBitsCount() >> 3;
 
-                    EmitReadZxCall(Context, Op.Size);
+                for (int SElem = 0; SElem < Op.SElems; SElem++)
+                {
+                    int Rt = (Op.Rt + SElem) & 0x1f;
 
-                    EmitVectorInsert(Context, Rt, Op.Index, Op.Size);
+                    for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
+                    {
+                        EmitMemAddress();
+
+                        EmitReadZxCall(Context, Op.Size);
+
+                        EmitVectorInsert(Context, Rt, Index, Op.Size);
+                    }
 
                     if (Op.RegisterSize == ARegisterSize.SIMD64)
                     {
                         EmitVectorZeroUpper(Context, Rt);
                     }
+
+                    Offset += 1 << Op.Size;
                 }
-                else
+            }
+            else
+            {
+                for (int SElem = 0; SElem < Op.SElems; SElem++)
                 {
-                    Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
-                    Context.EmitLdint(Op.Rn);
-                    Context.EmitLdc_I8(Offset);
+                    int Rt = (Op.Rt + SElem) & 0x1f;
 
-                    Context.Emit(OpCodes.Add);
+                    if (IsLoad)
+                    {
+                        EmitMemAddress();
 
-                    EmitVectorExtractZx(Context, Rt, Op.Index, Op.Size);
+                        EmitReadZxCall(Context, Op.Size);
 
-                    EmitWriteCall(Context, Op.Size);
-                }
+                        EmitVectorInsert(Context, Rt, Op.Index, Op.Size);
+                    }
+                    else
+                    {
+                        EmitMemAddress();
 
-                Offset += 1 << Op.Size;
+                        EmitVectorExtractZx(Context, Rt, Op.Index, Op.Size);
+
+                        EmitWriteCall(Context, Op.Size);
+                    }
+
+                    Offset += 1 << Op.Size;
+                }
             }
 
             if (Op.WBack)

+ 1 - 0
Ryujinx/Ui/Program.cs

@@ -2,6 +2,7 @@
 using Gal.OpenGL;
 using System;
 using System.IO;
+using ChocolArm64;
 
 namespace Ryujinx
 {