diff options
Diffstat (limited to 'ChocolArm64/Instructions')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitSimdCvt.cs | 108 |
1 files changed, 72 insertions, 36 deletions
diff --git a/ChocolArm64/Instructions/InstEmitSimdCvt.cs b/ChocolArm64/Instructions/InstEmitSimdCvt.cs index 2eac3194..11105d89 100644 --- a/ChocolArm64/Instructions/InstEmitSimdCvt.cs +++ b/ChocolArm64/Instructions/InstEmitSimdCvt.cs @@ -244,7 +244,7 @@ namespace ChocolArm64.Instructions public static void Fcvtzs_Gp_Fixed(ILEmitterCtx context) { - EmitFcvtzs_Gp_Fix(context); + EmitFcvtzs_Gp_Fixed(context); } public static void Fcvtzs_S(ILEmitterCtx context) @@ -264,7 +264,7 @@ namespace ChocolArm64.Instructions public static void Fcvtzu_Gp_Fixed(ILEmitterCtx context) { - EmitFcvtzu_Gp_Fix(context); + EmitFcvtzu_Gp_Fixed(context); } public static void Fcvtzu_S(ILEmitterCtx context) @@ -293,6 +293,24 @@ namespace ChocolArm64.Instructions EmitScalarSetF(context, op.Rd, op.Size); } + public static void Scvtf_Gp_Fixed(ILEmitterCtx context) + { + OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; + + context.EmitLdintzr(op.Rn); + + if (context.CurrOp.RegisterSize == RegisterSize.Int32) + { + context.Emit(OpCodes.Conv_I4); + } + + EmitFloatCast(context, op.Size); + + EmitI2fFBitsMul(context, op.Size, op.FBits); + + EmitScalarSetF(context, op.Rd, op.Size); + } + public static void Scvtf_S(ILEmitterCtx context) { OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; @@ -349,48 +367,42 @@ namespace ChocolArm64.Instructions EmitScalarSetF(context, op.Rd, op.Size); } - public static void Ucvtf_S(ILEmitterCtx context) + public static void Ucvtf_Gp_Fixed(ILEmitterCtx context) { - OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; + OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; - EmitVectorExtractZx(context, op.Rn, 0, op.Size + 2); + context.EmitLdintzr(op.Rn); + + if (context.CurrOp.RegisterSize == RegisterSize.Int32) + { + context.Emit(OpCodes.Conv_U4); + } context.Emit(OpCodes.Conv_R_Un); EmitFloatCast(context, op.Size); + EmitI2fFBitsMul(context, op.Size, op.FBits); + EmitScalarSetF(context, op.Rd, op.Size); } - public static void Ucvtf_V(ILEmitterCtx context) + public static void Ucvtf_S(ILEmitterCtx context) { - EmitVectorCvtf(context, signed: false); - } + OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; - private static int GetFBits(ILEmitterCtx context) - { - if (context.CurrOp is OpCodeSimdShImm64 op) - { - return GetImmShr(op); - } + EmitVectorExtractZx(context, op.Rn, 0, op.Size + 2); - return 0; + context.Emit(OpCodes.Conv_R_Un); + + EmitFloatCast(context, op.Size); + + EmitScalarSetF(context, op.Rd, op.Size); } - private static void EmitFloatCast(ILEmitterCtx context, int size) + public static void Ucvtf_V(ILEmitterCtx context) { - if (size == 0) - { - context.Emit(OpCodes.Conv_R4); - } - else if (size == 1) - { - context.Emit(OpCodes.Conv_R8); - } - else - { - throw new ArgumentOutOfRangeException(nameof(size)); - } + EmitVectorCvtf(context, signed: false); } private static void EmitFcvtn(ILEmitterCtx context, bool signed, bool scalar) @@ -476,17 +488,17 @@ namespace ChocolArm64.Instructions context.EmitStintzr(op.Rd); } - private static void EmitFcvtzs_Gp_Fix(ILEmitterCtx context) + private static void EmitFcvtzs_Gp_Fixed(ILEmitterCtx context) { - EmitFcvtz__Gp_Fix(context, true); + EmitFcvtz__Gp_Fixed(context, true); } - private static void EmitFcvtzu_Gp_Fix(ILEmitterCtx context) + private static void EmitFcvtzu_Gp_Fixed(ILEmitterCtx context) { - EmitFcvtz__Gp_Fix(context, false); + EmitFcvtz__Gp_Fixed(context, false); } - private static void EmitFcvtz__Gp_Fix(ILEmitterCtx context, bool signed) + private static void EmitFcvtz__Gp_Fixed(ILEmitterCtx context, bool signed) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; @@ -530,9 +542,7 @@ namespace ChocolArm64.Instructions context.Emit(OpCodes.Conv_R_Un); } - context.Emit(sizeF == 0 - ? OpCodes.Conv_R4 - : OpCodes.Conv_R8); + EmitFloatCast(context, sizeF); EmitI2fFBitsMul(context, sizeF, fBits); @@ -644,6 +654,32 @@ namespace ChocolArm64.Instructions } } + private static int GetFBits(ILEmitterCtx context) + { + if (context.CurrOp is OpCodeSimdShImm64 op) + { + return GetImmShr(op); + } + + return 0; + } + + private static void EmitFloatCast(ILEmitterCtx context, int size) + { + if (size == 0) + { + context.Emit(OpCodes.Conv_R4); + } + else if (size == 1) + { + context.Emit(OpCodes.Conv_R8); + } + else + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + } + private static void EmitScalarFcvts(ILEmitterCtx context, int size, int fBits) { if (size < 0 || size > 1) |
