forked from Mirror/Ryujinx
Add FCVTAS and FCVTAU instructions
This commit is contained in:
parent
ebddc40550
commit
595e7ee588
4 changed files with 68 additions and 24 deletions
|
@ -151,6 +151,8 @@ namespace ChocolArm64
|
||||||
Set("00011110xx1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S, typeof(AOpCodeSimdReg));
|
Set("00011110xx1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S, typeof(AOpCodeSimdReg));
|
||||||
Set("00011110xx1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S, typeof(AOpCodeSimdFcond));
|
Set("00011110xx1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S, typeof(AOpCodeSimdFcond));
|
||||||
Set("00011110xx10001xx10000xxxxxxxxxx", AInstEmit.Fcvt_S, typeof(AOpCodeSimd));
|
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("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp, typeof(AOpCodeSimdCvt));
|
||||||
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt));
|
||||||
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt));
|
||||||
|
|
|
@ -222,30 +222,7 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
|
EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);
|
||||||
|
|
||||||
Context.EmitLdc_I4((int)MidpointRounding.AwayFromZero);
|
EmitRoundMathCall(Context, 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);
|
|
||||||
|
|
||||||
EmitScalarSetF(Context, Op.Rd, Op.Size);
|
EmitScalarSetF(Context, Op.Rd, Op.Size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,16 @@ namespace ChocolArm64.Instruction
|
||||||
EmitScalarSetF(Context, Op.Rd, Op.Opc);
|
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)
|
public static void Fcvtms_Gp(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitFcvt_s_Gp(Context, nameof(Math.Floor));
|
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)
|
private static void EmitFcvt_s_Gp(AILEmitterCtx Context, string Name)
|
||||||
{
|
{
|
||||||
AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;
|
AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;
|
||||||
|
|
|
@ -76,6 +76,36 @@ namespace ChocolArm64.Instruction
|
||||||
Context.EmitCall(MthdInfo);
|
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)
|
public static void EmitScalarUnaryOpSx(AILEmitterCtx Context, Action Emit)
|
||||||
{
|
{
|
||||||
EmitScalarOp(Context, Emit, OperFlags.Rn, true);
|
EmitScalarOp(Context, Emit, OperFlags.Rn, true);
|
||||||
|
|
Loading…
Reference in a new issue