diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-02-23 20:52:48 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-02-23 20:52:48 -0300 |
| commit | 9679896b9471afdebf860c016d3fd360b9af7f80 (patch) | |
| tree | 8b122155dbe528db1aa9237be185f0ddf6fefbaf /ChocolArm64/Instructions | |
| parent | 7ed2b4cc39ca286a03589cd3768a419c5ed9941f (diff) | |
Implement fixed-point variant of the UCVTF and SCVTF instructions (#578)
* Add fixed-point variant of the UCVTF instruction
* Change encoding of some fixed-point instructions to not allow invalid encodings
* Fix Fcvtzu_Gp_Fixed encoding
* Add SCVTF (fixed-point GP to Scalar) instruction
* Simplify *Fixed encodings
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) |
