aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-04-30 01:39:58 +0200
committergdkchan <gab.dark.100@gmail.com>2018-04-29 20:39:58 -0300
commit7cda630aba8b99b65379c0ef0e92483491e4fbb3 (patch)
tree916bd69e1d296c8ff034df238eab3ca6de7d7ac6 /ChocolArm64
parent071754aaeb1c9113c5818421b7cca1f3c717052a (diff)
Add Sqxtn_S, Sqxtn_V, Uqxtn_S, Uqxtn_V instructions and Tests (6). (#110)
* Update ILGeneratorEx.cs * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Update CpuTest.cs * Update Pseudocode.cs * Update Instructions.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdArithmetic.cs
Diffstat (limited to 'ChocolArm64')
-rw-r--r--ChocolArm64/AOpCodeTable.cs4
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs98
-rw-r--r--ChocolArm64/Translation/ILGeneratorEx.cs4
3 files changed, 104 insertions, 2 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index be22de1e..64b7e10f 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -337,6 +337,8 @@ namespace ChocolArm64
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
Set("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
+ Set("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S, typeof(AOpCodeSimd));
+ Set("0x001110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_V, typeof(AOpCodeSimd));
Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
@@ -370,6 +372,8 @@ namespace ChocolArm64
Set("0x101110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Uhadd_V, typeof(AOpCodeSimdReg));
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
Set("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
+ Set("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S, typeof(AOpCodeSimd));
+ Set("0x101110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_V, typeof(AOpCodeSimd));
Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
Set("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S, typeof(AOpCodeSimdShImm));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index f4dcf864..3a4b2210 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -205,6 +205,84 @@ namespace ChocolArm64.Instruction
}
}
+ private static void EmitQxtn(AILEmitterCtx Context, bool Signed, bool Scalar)
+ {
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+ int Elems = (!Scalar ? 8 >> Op.Size : 1);
+ int ESize = 8 << Op.Size;
+
+ int TMaxValue = (Signed ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L));
+ int TMinValue = (Signed ? -((1 << (ESize - 1))) : 0);
+
+ int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);
+
+ Context.EmitLdc_I8(0L);
+ Context.EmitSttmp();
+
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ AILLabel LblLe = new AILLabel();
+ AILLabel LblGeEnd = new AILLabel();
+
+ EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, Signed);
+
+ Context.Emit(OpCodes.Dup);
+
+ Context.EmitLdc_I4(TMaxValue);
+ Context.Emit(OpCodes.Conv_U8);
+
+ Context.Emit(Signed ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);
+
+ Context.Emit(OpCodes.Pop);
+
+ Context.EmitLdc_I4(TMaxValue);
+
+ Context.EmitLdc_I8(0x8000000L);
+ Context.EmitSttmp();
+
+ Context.Emit(OpCodes.Br_S, LblGeEnd);
+
+ Context.MarkLabel(LblLe);
+
+ Context.Emit(OpCodes.Dup);
+
+ Context.EmitLdc_I4(TMinValue);
+ Context.Emit(OpCodes.Conv_I8);
+
+ Context.Emit(Signed ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);
+
+ Context.Emit(OpCodes.Pop);
+
+ Context.EmitLdc_I4(TMinValue);
+
+ Context.EmitLdc_I8(0x8000000L);
+ Context.EmitSttmp();
+
+ Context.MarkLabel(LblGeEnd);
+
+ if (Scalar)
+ {
+ EmitVectorZeroLower(Context, Op.Rd);
+ }
+
+ EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size);
+ }
+
+ if (Part == 0)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+
+ Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+ Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+ Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
+ Context.EmitLdtmp();
+ Context.Emit(OpCodes.Conv_I4);
+ Context.Emit(OpCodes.Or);
+ Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
+ }
+
public static void Fabd_S(AILEmitterCtx Context)
{
EmitScalarBinaryOpF(Context, () =>
@@ -971,6 +1049,16 @@ namespace ChocolArm64.Instruction
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
}
+ public static void Sqxtn_S(AILEmitterCtx Context)
+ {
+ EmitQxtn(Context, Signed: true, Scalar: true);
+ }
+
+ public static void Sqxtn_V(AILEmitterCtx Context)
+ {
+ EmitQxtn(Context, Signed: true, Scalar: false);
+ }
+
public static void Sub_S(AILEmitterCtx Context)
{
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
@@ -1049,5 +1137,15 @@ namespace ChocolArm64.Instruction
{
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
}
+
+ public static void Uqxtn_S(AILEmitterCtx Context)
+ {
+ EmitQxtn(Context, Signed: false, Scalar: true);
+ }
+
+ public static void Uqxtn_V(AILEmitterCtx Context)
+ {
+ EmitQxtn(Context, Signed: false, Scalar: false);
+ }
}
}
diff --git a/ChocolArm64/Translation/ILGeneratorEx.cs b/ChocolArm64/Translation/ILGeneratorEx.cs
index 61299308..52eb4746 100644
--- a/ChocolArm64/Translation/ILGeneratorEx.cs
+++ b/ChocolArm64/Translation/ILGeneratorEx.cs
@@ -6,7 +6,7 @@ namespace ChocolArm64
static class ILGeneratorEx
{
- public static void EmitLdc_I4(this ILGenerator Generator,int Value)
+ public static void EmitLdc_I4(this ILGenerator Generator, int Value)
{
switch (Value)
{
@@ -126,4 +126,4 @@ namespace ChocolArm64
}
}
}
-} \ No newline at end of file
+}