From 9288ffd26d0b0b831f62cfc0281c71662d251884 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Wed, 28 Jun 2023 17:36:30 +0200 Subject: 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> --- src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/ARMeilleure/Instructions') diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index dcdcc65d..b0385591 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -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; -- cgit v1.2.3