Просмотр исходного кода

Implement SSHL instruction, fix exception on FMAX/FMIN, and use a better exception message for undefined/unimplemented instructions

gdkchan 8 лет назад
Родитель
Сommit
d77d691381

+ 1 - 0
Ryujinx/Cpu/AOpCodeTable.cs

@@ -208,6 +208,7 @@ namespace ChocolArm64
             Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V,         typeof(AOpCodeSimdShImm));
             Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V,         typeof(AOpCodeSimdShImm));
             Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V,        typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V,        typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V,        typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V,        typeof(AOpCodeSimdReg));
+            Set("0x001110xx1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V,        typeof(AOpCodeSimdReg));
             Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V,       typeof(AOpCodeSimdShImm));
             Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V,       typeof(AOpCodeSimdShImm));
             Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S,        typeof(AOpCodeSimdShImm));
             Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S,        typeof(AOpCodeSimdShImm));
             Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V,        typeof(AOpCodeSimdShImm));
             Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V,        typeof(AOpCodeSimdShImm));

+ 1 - 1
Ryujinx/Cpu/Instruction/AInstEmitException.cs

@@ -27,7 +27,7 @@ namespace ChocolArm64.Instruction
 
 
         public static void Und(AILEmitterCtx Context)
         public static void Und(AILEmitterCtx Context)
         {
         {
-            throw new Exception("und inst! " + Context.CurrOp.Position.ToString("x8"));
+            throw new NotImplementedException($"Undefined instruction at {Context.CurrOp.Position:x16}");
         }
         }
     }
     }
 }
 }

+ 16 - 1
Ryujinx/Cpu/Instruction/AInstEmitScalar.cs

@@ -498,7 +498,22 @@ namespace ChocolArm64.Instruction
             Context.EmitLdvecsf(Op.Rn);
             Context.EmitLdvecsf(Op.Rn);
             Context.EmitLdvecsf(Op.Rm);
             Context.EmitLdvecsf(Op.Rm);
 
 
-            EmitMathOpCall(Context, Name);
+            MethodInfo MthdInfo;
+
+            if (Op.Size == 0)
+            {
+                MthdInfo = typeof(MathF).GetMethod(Name, new Type[] { typeof(float), typeof(float) });
+            }
+            else if (Op.Size == 1)
+            {
+                MthdInfo = typeof(Math).GetMethod(Name, new Type[] { typeof(double), typeof(double) });
+            }
+            else
+            {
+                throw new InvalidOperationException();
+            }
+
+            Context.EmitCall(MthdInfo);
 
 
             Context.EmitStvecsf(Op.Rd);
             Context.EmitStvecsf(Op.Rd);
         }
         }

+ 9 - 2
Ryujinx/Cpu/Instruction/AInstEmitSimd.cs

@@ -375,6 +375,8 @@ namespace ChocolArm64.Instruction
         public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context);
         public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context);
         public static void Smin_V(AILEmitterCtx Context) => EmitVectorSmin(Context);
         public static void Smin_V(AILEmitterCtx Context) => EmitVectorSmin(Context);
 
 
+        public static void Sshl_V(AILEmitterCtx Context) => EmitVectorSshl(Context);
+
         public static void Sshll_V(AILEmitterCtx Context)
         public static void Sshll_V(AILEmitterCtx Context)
         {
         {
             AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
             AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
@@ -737,7 +739,10 @@ namespace ChocolArm64.Instruction
             EmitVectorBinarySx(Context, () => Context.EmitCall(MthdInfo));
             EmitVectorBinarySx(Context, () => Context.EmitCall(MthdInfo));
         }
         }
 
 
-        private static void EmitVectorUshl(AILEmitterCtx Context)
+        private static void EmitVectorSshl(AILEmitterCtx Context) => EmitVectorShl(Context, true);
+        private static void EmitVectorUshl(AILEmitterCtx Context) => EmitVectorShl(Context, false);
+
+        private static void EmitVectorShl(AILEmitterCtx Context, bool Signed)
         {
         {
             //This instruction shifts the value on vector A by the number of bits
             //This instruction shifts the value on vector A by the number of bits
             //specified on the signed, lower 8 bits of vector B. If the shift value
             //specified on the signed, lower 8 bits of vector B. If the shift value
@@ -772,7 +777,9 @@ namespace ChocolArm64.Instruction
                 Context.Emit(OpCodes.Bge_S, LblShl);
                 Context.Emit(OpCodes.Bge_S, LblShl);
                 Context.Emit(OpCodes.Neg);
                 Context.Emit(OpCodes.Neg);
 
 
-                EmitShift(OpCodes.Shr_Un);
+                EmitShift(Signed
+                    ? OpCodes.Shr
+                    : OpCodes.Shr_Un);
 
 
                 Context.MarkLabel(LblShl);
                 Context.MarkLabel(LblShl);
 
 

+ 0 - 2
Ryujinx/Loaders/Executable.cs

@@ -7,7 +7,6 @@ namespace Ryujinx.Loaders
 {
 {
     class Executable
     class Executable
     {
     {
-        private IExecutable    NsoData;
         private AMemory Memory;
         private AMemory Memory;
 
 
         private ElfDyn[] Dynamic;
         private ElfDyn[] Dynamic;
@@ -17,7 +16,6 @@ namespace Ryujinx.Loaders
 
 
         public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
         public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
         {
         {
-            this.NsoData   = Exe;
             this.Memory    = Memory;
             this.Memory    = Memory;
             this.ImageBase = ImageBase;
             this.ImageBase = ImageBase;
             this.ImageEnd  = ImageBase;
             this.ImageEnd  = ImageBase;