aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-02-23 20:52:48 -0300
committerGitHub <noreply@github.com>2019-02-23 20:52:48 -0300
commit9679896b9471afdebf860c016d3fd360b9af7f80 (patch)
tree8b122155dbe528db1aa9237be185f0ddf6fefbaf /ChocolArm64/Instructions
parent7ed2b4cc39ca286a03589cd3768a419c5ed9941f (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.cs108
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)