Archived
1
0
Fork 0
forked from Mirror/Ryujinx

Add Fcvtas_S/V & Fcvtau_S/V. (#1018)

This commit is contained in:
LDj3SNuD 2020-03-24 22:53:49 +01:00 committed by GitHub
parent d0960e75aa
commit 1de16f7653
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 25 deletions

View file

@ -298,7 +298,11 @@ namespace ARMeilleure.Decoders
SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", InstName.Fcsel_S, InstEmit.Fcsel_S, typeof(OpCodeSimdFcond)); SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", InstName.Fcsel_S, InstEmit.Fcsel_S, typeof(OpCodeSimdFcond));
SetA64("00011110xx10001xx10000xxxxxxxxxx", InstName.Fcvt_S, InstEmit.Fcvt_S, typeof(OpCodeSimd)); SetA64("00011110xx10001xx10000xxxxxxxxxx", InstName.Fcvt_S, InstEmit.Fcvt_S, typeof(OpCodeSimd));
SetA64("x00111100x100100000000xxxxxxxxxx", InstName.Fcvtas_Gp, InstEmit.Fcvtas_Gp, typeof(OpCodeSimdCvt)); SetA64("x00111100x100100000000xxxxxxxxxx", InstName.Fcvtas_Gp, InstEmit.Fcvtas_Gp, typeof(OpCodeSimdCvt));
SetA64("010111100x100001110010xxxxxxxxxx", InstName.Fcvtas_S, InstEmit.Fcvtas_S, typeof(OpCodeSimd));
SetA64("0>0011100<100001110010xxxxxxxxxx", InstName.Fcvtas_V, InstEmit.Fcvtas_V, typeof(OpCodeSimd));
SetA64("x00111100x100101000000xxxxxxxxxx", InstName.Fcvtau_Gp, InstEmit.Fcvtau_Gp, typeof(OpCodeSimdCvt)); SetA64("x00111100x100101000000xxxxxxxxxx", InstName.Fcvtau_Gp, InstEmit.Fcvtau_Gp, typeof(OpCodeSimdCvt));
SetA64("011111100x100001110010xxxxxxxxxx", InstName.Fcvtau_S, InstEmit.Fcvtau_S, typeof(OpCodeSimd));
SetA64("0>1011100<100001110010xxxxxxxxxx", InstName.Fcvtau_V, InstEmit.Fcvtau_V, typeof(OpCodeSimd));
SetA64("0x0011100x100001011110xxxxxxxxxx", InstName.Fcvtl_V, InstEmit.Fcvtl_V, typeof(OpCodeSimd)); SetA64("0x0011100x100001011110xxxxxxxxxx", InstName.Fcvtl_V, InstEmit.Fcvtl_V, typeof(OpCodeSimd));
SetA64("x00111100x110000000000xxxxxxxxxx", InstName.Fcvtms_Gp, InstEmit.Fcvtms_Gp, typeof(OpCodeSimdCvt)); SetA64("x00111100x110000000000xxxxxxxxxx", InstName.Fcvtms_Gp, InstEmit.Fcvtms_Gp, typeof(OpCodeSimdCvt));
SetA64("x00111100x110001000000xxxxxxxxxx", InstName.Fcvtmu_Gp, InstEmit.Fcvtmu_Gp, typeof(OpCodeSimdCvt)); SetA64("x00111100x110001000000xxxxxxxxxx", InstName.Fcvtmu_Gp, InstEmit.Fcvtmu_Gp, typeof(OpCodeSimdCvt));

View file

@ -98,11 +98,31 @@ namespace ARMeilleure.Instructions
EmitFcvt_s_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1)); EmitFcvt_s_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
} }
public static void Fcvtas_S(ArmEmitterContext context)
{
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: true);
}
public static void Fcvtas_V(ArmEmitterContext context)
{
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: false);
}
public static void Fcvtau_Gp(ArmEmitterContext context) public static void Fcvtau_Gp(ArmEmitterContext context)
{ {
EmitFcvt_u_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1)); EmitFcvt_u_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
} }
public static void Fcvtau_S(ArmEmitterContext context)
{
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: true);
}
public static void Fcvtau_V(ArmEmitterContext context)
{
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: false);
}
public static void Fcvtl_V(ArmEmitterContext context) public static void Fcvtl_V(ArmEmitterContext context)
{ {
OpCodeSimd op = (OpCodeSimd)context.CurrOp; OpCodeSimd op = (OpCodeSimd)context.CurrOp;
@ -255,7 +275,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvtn(context, signed: true, scalar: true); EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.ToEven, op1), signed: true, scalar: true);
} }
} }
@ -267,7 +287,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvtn(context, signed: true, scalar: false); EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.ToEven, op1), signed: true, scalar: false);
} }
} }
@ -279,7 +299,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvtn(context, signed: false, scalar: true); EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.ToEven, op1), signed: false, scalar: true);
} }
} }
@ -291,7 +311,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvtn(context, signed: false, scalar: false); EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.ToEven, op1), signed: false, scalar: false);
} }
} }
@ -585,7 +605,7 @@ namespace ARMeilleure.Instructions
} }
} }
private static void EmitFcvtn(ArmEmitterContext context, bool signed, bool scalar) private static void EmitFcvt(ArmEmitterContext context, Func1I emit, bool signed, bool scalar)
{ {
OpCodeSimd op = (OpCodeSimd)context.CurrOp; OpCodeSimd op = (OpCodeSimd)context.CurrOp;
@ -604,7 +624,7 @@ namespace ARMeilleure.Instructions
{ {
Operand ne = context.VectorExtract(type, n, index); Operand ne = context.VectorExtract(type, n, index);
Operand e = EmitRoundMathCall(context, MidpointRounding.ToEven, ne); Operand e = emit(ne);
if (sizeF == 0) if (sizeF == 0)
{ {

View file

@ -180,7 +180,11 @@ namespace ARMeilleure.Instructions
Fcsel_S, Fcsel_S,
Fcvt_S, Fcvt_S,
Fcvtas_Gp, Fcvtas_Gp,
Fcvtas_S,
Fcvtas_V,
Fcvtau_Gp, Fcvtau_Gp,
Fcvtau_S,
Fcvtau_V,
Fcvtl_V, Fcvtl_V,
Fcvtms_Gp, Fcvtms_Gp,
Fcvtmu_Gp, Fcvtmu_Gp,

View file

@ -829,10 +829,12 @@ namespace Ryujinx.Tests.Cpu
}; };
} }
private static uint[] _F_Cvt_NZ_SU_S_S_() private static uint[] _F_Cvt_ANZ_SU_S_S_()
{ {
return new uint[] return new uint[]
{ {
0x5E21C820u, // FCVTAS S0, S1
0x7E21C820u, // FCVTAU S0, S1
0x5E21A820u, // FCVTNS S0, S1 0x5E21A820u, // FCVTNS S0, S1
0x7E21A820u, // FCVTNU S0, S1 0x7E21A820u, // FCVTNU S0, S1
0x5EA1B820u, // FCVTZS S0, S1 0x5EA1B820u, // FCVTZS S0, S1
@ -840,10 +842,12 @@ namespace Ryujinx.Tests.Cpu
}; };
} }
private static uint[] _F_Cvt_NZ_SU_S_D_() private static uint[] _F_Cvt_ANZ_SU_S_D_()
{ {
return new uint[] return new uint[]
{ {
0x5E61C820u, // FCVTAS D0, D1
0x7E61C820u, // FCVTAU D0, D1
0x5E61A820u, // FCVTNS D0, D1 0x5E61A820u, // FCVTNS D0, D1
0x7E61A820u, // FCVTNU D0, D1 0x7E61A820u, // FCVTNU D0, D1
0x5EE1B820u, // FCVTZS D0, D1 0x5EE1B820u, // FCVTZS D0, D1
@ -851,10 +855,12 @@ namespace Ryujinx.Tests.Cpu
}; };
} }
private static uint[] _F_Cvt_NZ_SU_V_2S_4S_() private static uint[] _F_Cvt_ANZ_SU_V_2S_4S_()
{ {
return new uint[] return new uint[]
{ {
0x0E21C800u, // FCVTAS V0.2S, V0.2S
0x2E21C800u, // FCVTAU V0.2S, V0.2S
0x0E21A800u, // FCVTNS V0.2S, V0.2S 0x0E21A800u, // FCVTNS V0.2S, V0.2S
0x2E21A800u, // FCVTNU V0.2S, V0.2S 0x2E21A800u, // FCVTNU V0.2S, V0.2S
0x0EA1B800u, // FCVTZS V0.2S, V0.2S 0x0EA1B800u, // FCVTZS V0.2S, V0.2S
@ -862,10 +868,12 @@ namespace Ryujinx.Tests.Cpu
}; };
} }
private static uint[] _F_Cvt_NZ_SU_V_2D_() private static uint[] _F_Cvt_ANZ_SU_V_2D_()
{ {
return new uint[] return new uint[]
{ {
0x4E61C800u, // FCVTAS V0.2D, V0.2D
0x6E61C800u, // FCVTAU V0.2D, V0.2D
0x4E61A800u, // FCVTNS V0.2D, V0.2D 0x4E61A800u, // FCVTNS V0.2D, V0.2D
0x6E61A800u, // FCVTNU V0.2D, V0.2D 0x6E61A800u, // FCVTNU V0.2D, V0.2D
0x4EE1B800u, // FCVTZS V0.2D, V0.2D 0x4EE1B800u, // FCVTZS V0.2D, V0.2D
@ -1981,8 +1989,8 @@ namespace Ryujinx.Tests.Cpu
} }
[Test, Pairwise] [Explicit] [Test, Pairwise] [Explicit]
public void F_Cvt_NZ_SU_S_S([ValueSource("_F_Cvt_NZ_SU_S_S_")] uint opcodes, public void F_Cvt_ANZ_SU_S_S([ValueSource("_F_Cvt_ANZ_SU_S_S_")] uint opcodes,
[ValueSource("_1S_F_W_")] ulong a) [ValueSource("_1S_F_W_")] ulong a)
{ {
ulong z = TestContext.CurrentContext.Random.NextULong(); ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z); V128 v0 = MakeVectorE0E1(z, z);
@ -1994,8 +2002,8 @@ namespace Ryujinx.Tests.Cpu
} }
[Test, Pairwise] [Explicit] [Test, Pairwise] [Explicit]
public void F_Cvt_NZ_SU_S_D([ValueSource("_F_Cvt_NZ_SU_S_D_")] uint opcodes, public void F_Cvt_ANZ_SU_S_D([ValueSource("_F_Cvt_ANZ_SU_S_D_")] uint opcodes,
[ValueSource("_1D_F_X_")] ulong a) [ValueSource("_1D_F_X_")] ulong a)
{ {
ulong z = TestContext.CurrentContext.Random.NextULong(); ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE1(z); V128 v0 = MakeVectorE1(z);
@ -2007,12 +2015,12 @@ namespace Ryujinx.Tests.Cpu
} }
[Test, Pairwise] [Explicit] [Test, Pairwise] [Explicit]
public void F_Cvt_NZ_SU_V_2S_4S([ValueSource("_F_Cvt_NZ_SU_V_2S_4S_")] uint opcodes, public void F_Cvt_ANZ_SU_V_2S_4S([ValueSource("_F_Cvt_ANZ_SU_V_2S_4S_")] uint opcodes,
[Values(0u)] uint rd, [Values(0u)] uint rd,
[Values(1u, 0u)] uint rn, [Values(1u, 0u)] uint rn,
[ValueSource("_2S_F_W_")] ulong z, [ValueSource("_2S_F_W_")] ulong z,
[ValueSource("_2S_F_W_")] ulong a, [ValueSource("_2S_F_W_")] ulong a,
[Values(0b0u, 0b1u)] uint q) // <2S, 4S> [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
{ {
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= ((q & 1) << 30); opcodes |= ((q & 1) << 30);
@ -2026,11 +2034,11 @@ namespace Ryujinx.Tests.Cpu
} }
[Test, Pairwise] [Explicit] [Test, Pairwise] [Explicit]
public void F_Cvt_NZ_SU_V_2D([ValueSource("_F_Cvt_NZ_SU_V_2D_")] uint opcodes, public void F_Cvt_ANZ_SU_V_2D([ValueSource("_F_Cvt_ANZ_SU_V_2D_")] uint opcodes,
[Values(0u)] uint rd, [Values(0u)] uint rd,
[Values(1u, 0u)] uint rn, [Values(1u, 0u)] uint rn,
[ValueSource("_1D_F_X_")] ulong z, [ValueSource("_1D_F_X_")] ulong z,
[ValueSource("_1D_F_X_")] ulong a) [ValueSource("_1D_F_X_")] ulong a)
{ {
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0); opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);