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("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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue