diff options
author | Ac_K <Acoustik666@gmail.com> | 2023-06-28 17:36:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-28 17:36:30 +0200 |
commit | 9288ffd26d0b0b831f62cfc0281c71662d251884 (patch) | |
tree | 190677d6b4344cd7315ffd0616c5bf7b6055734f /src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs | |
parent | 2cdc82cb910d03e13d36b6a31148b5b87e35fde9 (diff) |
Cpu: Implement VCVT (between floating-point and fixed-point) instruction (#5343)1.1.932
* 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>
Diffstat (limited to 'src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs')
-rw-r--r-- | src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs | 29 |
1 files changed, 29 insertions, 0 deletions
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; |