Cpu: Implement VCVT (between floating-point and fixed-point) instruction (#5343)

* cpu: Implement VCVT (between floating-point and fixed-point) instruction

Rebase, fix and superseed of https://github.com/Ryujinx/Ryujinx/pull/2915

(Since I only have little CPU knowledge, I hope I have done everything good)

* Update Ptc.cs

* Fix wrong cast

* Rename tests

* Addresses feedback

Co-Authored-By: gdkchan <5624669+gdkchan@users.noreply.github.com>

* Remove extra empty line

---------

Co-authored-by: gdkchan <5624669+gdkchan@users.noreply.github.com>
This commit is contained in:
Ac_K
2023-06-28 17:36:30 +02:00
committed by GitHub
parent 2cdc82cb91
commit 9288ffd26d
5 changed files with 309 additions and 176 deletions

View File

@ -114,6 +114,35 @@ namespace ARMeilleure.Instructions
}
}
public static void Vcvt_V_Fixed(ArmEmitterContext context)
{
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
var toFixed = op.Opc == 1;
int fracBits = op.Fbits;
var unsigned = op.U;
if (toFixed) // F32 to S32 or U32 (fixed)
{
EmitVectorUnaryOpF32(context, (op1) =>
{
var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
return context.Call(info, scaledValue);
});
}
else // S32 or U32 (fixed) to F32
{
EmitVectorUnaryOpI32(context, (op1) =>
{
var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
}, !unsigned);
}
}
public static void Vcvt_FD(ArmEmitterContext context)
{
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;