aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-02-17 18:59:37 -0300
committergdkchan <gab.dark.100@gmail.com>2018-02-17 18:59:37 -0300
commit595e7ee588da7ad528479dc0013565d3a1fdd138 (patch)
treec7241367ca3e327d10280b4524aa8ba2dfeb35d7
parentebddc40550f9107c7b52f8709a12ef070244f8f0 (diff)
Add FCVTAS and FCVTAU instructions
-rw-r--r--Ryujinx/Cpu/AOpCodeTable.cs2
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs25
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs35
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs30
4 files changed, 68 insertions, 24 deletions
diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index c9678fb5..cfed011e 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -151,6 +151,8 @@ namespace ChocolArm64
Set("00011110xx1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S, typeof(AOpCodeSimdFcond));
Set("00011110xx10001xx10000xxxxxxxxxx", AInstEmit.Fcvt_S, typeof(AOpCodeSimd));
+ Set("x0011110xx100100000000xxxxxxxxxx", AInstEmit.Fcvtas_Gp, typeof(AOpCodeSimdCvt));
+ Set("x0011110xx100101000000xxxxxxxxxx", AInstEmit.Fcvtau_Gp, typeof(AOpCodeSimdCvt));
Set("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp, typeof(AOpCodeSimdCvt));
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt));
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt));
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
index 854ba85d..245862a6 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs
@@ -222,30 +222,7 @@ namespace ChocolArm64.Instruction
EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
- Context.EmitLdc_I4((int)MidpointRounding.AwayFromZero);
-
- MethodInfo MthdInfo;
-
- Type[] Types = new Type[] { null, typeof(MidpointRounding) };
-
- Types[0] = Op.Size == 0
- ? typeof(float)
- : typeof(double);
-
- if (Op.Size == 0)
- {
- MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), Types);
- }
- else if (Op.Size == 1)
- {
- MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
- }
- else
- {
- throw new InvalidOperationException();
- }
-
- Context.EmitCall(MthdInfo);
+ EmitRoundMathCall(Context, MidpointRounding.AwayFromZero);
EmitScalarSetF(Context, Op.Rd, Op.Size);
}
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
index b7a47411..68f23914 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdCvt.cs
@@ -21,6 +21,16 @@ namespace ChocolArm64.Instruction
EmitScalarSetF(Context, Op.Rd, Op.Opc);
}
+ public static void Fcvtas_Gp(AILEmitterCtx Context)
+ {
+ Fcvta__Gp(Context, Signed: true);
+ }
+
+ public static void Fcvtau_Gp(AILEmitterCtx Context)
+ {
+ Fcvta__Gp(Context, Signed: false);
+ }
+
public static void Fcvtms_Gp(AILEmitterCtx Context)
{
EmitFcvt_s_Gp(Context, nameof(Math.Floor));
@@ -155,6 +165,31 @@ namespace ChocolArm64.Instruction
}
}
+ private static void Fcvta__Gp(AILEmitterCtx Context, bool Signed)
+ {
+ AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;
+
+ EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
+
+ EmitRoundMathCall(Context, MidpointRounding.AwayFromZero);
+
+ if (Signed)
+ {
+ EmitScalarFcvts(Context, Op.Size, 0);
+ }
+ else
+ {
+ EmitScalarFcvtu(Context, Op.Size, 0);
+ }
+
+ if (Context.CurrOp.RegisterSize == ARegisterSize.Int32)
+ {
+ Context.Emit(OpCodes.Conv_U8);
+ }
+
+ Context.EmitStintzr(Op.Rd);
+ }
+
private static void EmitFcvt_s_Gp(AILEmitterCtx Context, string Name)
{
AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
index 0149fd2e..fe529023 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs
@@ -76,6 +76,36 @@ namespace ChocolArm64.Instruction
Context.EmitCall(MthdInfo);
}
+ public static void EmitRoundMathCall(AILEmitterCtx Context, MidpointRounding RoundMode)
+ {
+ IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
+
+ Context.EmitLdc_I4((int)RoundMode);
+
+ MethodInfo MthdInfo;
+
+ Type[] Types = new Type[] { null, typeof(MidpointRounding) };
+
+ Types[0] = Op.Size == 0
+ ? typeof(float)
+ : typeof(double);
+
+ if (Op.Size == 0)
+ {
+ MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), Types);
+ }
+ else if (Op.Size == 1)
+ {
+ MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
+
+ Context.EmitCall(MthdInfo);
+ }
+
public static void EmitScalarUnaryOpSx(AILEmitterCtx Context, Action Emit)
{
EmitScalarOp(Context, Emit, OperFlags.Rn, true);