aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-07-19 02:06:28 +0200
committergdkchan <gab.dark.100@gmail.com>2018-07-18 21:06:28 -0300
commitfa5545aab80c056fa7e1f8d516a5add79eb30d8b (patch)
treebe3d187e7de2658c018e2a38ab5baeca623a5e8d /ChocolArm64/Instruction/AInstEmitSimdHelper.cs
parent120fe6b74a0d2903471bfaeb25ef8265712fc576 (diff)
Implement Ssubw_V and Usubw_V instructions. (#287)
* Update AOpCodeTable.cs * Update AInstEmitSimdHelper.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdMove.cs * Update AInstEmitSimdCmp.cs * Update Instructions.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdHelper.cs')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdHelper.cs77
1 files changed, 52 insertions, 25 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
index 7716e298..0bd1a629 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
@@ -419,20 +419,25 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1;
int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> SizeF + 2;
- for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++)
+ bool Rd = (Opers & OperFlags.Rd) != 0;
+ bool Rn = (Opers & OperFlags.Rn) != 0;
+ bool Rm = (Opers & OperFlags.Rm) != 0;
+
+ for (int Index = 0; Index < Elems; Index++)
{
- if (Opers.HasFlag(OperFlags.Rd))
+ if (Rd)
{
EmitVectorExtractF(Context, Op.Rd, Index, SizeF);
}
- if (Opers.HasFlag(OperFlags.Rn))
+ if (Rn)
{
EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
}
- if (Opers.HasFlag(OperFlags.Rm))
+ if (Rm)
{
EmitVectorExtractF(Context, ((AOpCodeSimdReg)Op).Rm, Index, SizeF);
}
@@ -469,8 +474,9 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1;
int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> SizeF + 2;
- for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++)
+ for (int Index = 0; Index < Elems; Index++)
{
if (Ternary)
{
@@ -531,19 +537,23 @@ namespace ChocolArm64.Instruction
int Bytes = Op.GetBitsCount() >> 3;
int Elems = Bytes >> Op.Size;
+ bool Rd = (Opers & OperFlags.Rd) != 0;
+ bool Rn = (Opers & OperFlags.Rn) != 0;
+ bool Rm = (Opers & OperFlags.Rm) != 0;
+
for (int Index = 0; Index < Elems; Index++)
{
- if (Opers.HasFlag(OperFlags.Rd))
+ if (Rd)
{
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
}
- if (Opers.HasFlag(OperFlags.Rn))
+ if (Rn)
{
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
}
- if (Opers.HasFlag(OperFlags.Rm))
+ if (Rm)
{
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
}
@@ -662,9 +672,6 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
- Context.EmitLdvec(Op.Rd);
- Context.EmitStvectmp();
-
int Elems = 8 >> Op.Size;
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
@@ -707,9 +714,6 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
- Context.EmitLdvec(Op.Rd);
- Context.EmitStvectmp();
-
int Elems = 8 >> Op.Size;
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
@@ -747,21 +751,25 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
- int Bytes = Op.GetBitsCount() >> 3;
-
- int Elems = Bytes >> Op.Size;
- int Half = Elems >> 1;
+ int Words = Op.GetBitsCount() >> 4;
+ int Pairs = Words >> Op.Size;
- for (int Index = 0; Index < Elems; Index++)
+ for (int Index = 0; Index < Pairs; Index++)
{
- int Elem = (Index & (Half - 1)) << 1;
+ int Idx = Index << 1;
- EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 0, Op.Size, Signed);
- EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 1, Op.Size, Signed);
+ EmitVectorExtract(Context, Op.Rn, Idx, Op.Size, Signed);
+ EmitVectorExtract(Context, Op.Rn, Idx + 1, Op.Size, Signed);
Emit();
- EmitVectorInsertTmp(Context, Index, Op.Size);
+ EmitVectorExtract(Context, Op.Rm, Idx, Op.Size, Signed);
+ EmitVectorExtract(Context, Op.Rm, Idx + 1, Op.Size, Signed);
+
+ Emit();
+
+ EmitVectorInsertTmp(Context, Pairs + Index, Op.Size);
+ EmitVectorInsertTmp(Context, Index, Op.Size);
}
Context.EmitLdvectmp();
@@ -818,7 +826,7 @@ namespace ChocolArm64.Instruction
int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0;
- long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (1L << ESize) - 1L;
+ long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (long)(~0UL >> (64 - ESize));
long TMinValue = SignedDst ? -((1 << (ESize - 1))) : 0;
Context.EmitLdc_I8(0L);
@@ -871,7 +879,7 @@ namespace ChocolArm64.Instruction
if (Scalar)
{
- EmitVectorZeroLower(Context, Op.Rd);
+ EmitVectorZeroLowerTmp(Context);
}
EmitVectorInsertTmp(Context, Part + Index, Op.Size);
@@ -963,6 +971,11 @@ namespace ChocolArm64.Instruction
EmitVectorInsert(Context, Rd, 0, 3, 0);
}
+ public static void EmitVectorZeroLowerTmp(AILEmitterCtx Context)
+ {
+ EmitVectorInsertTmp(Context, 0, 3, 0);
+ }
+
public static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
{
EmitVectorInsert(Context, Rd, 1, 3, 0);
@@ -1008,6 +1021,20 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Reg);
}
+ public static void EmitVectorInsertTmp(AILEmitterCtx Context, int Index, int Size, long Value)
+ {
+ ThrowIfInvalid(Index, Size);
+
+ Context.EmitLdc_I8(Value);
+ Context.EmitLdvectmp();
+ Context.EmitLdc_I4(Index);
+ Context.EmitLdc_I4(Size);
+
+ AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorInsertInt));
+
+ Context.EmitStvectmp();
+ }
+
public static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
{
ThrowIfInvalidF(Index, Size);