aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-03-06 21:36:49 -0300
committergdkchan <gab.dark.100@gmail.com>2018-03-06 21:36:49 -0300
commitbe0e4007dc92e24a77bdc36a40d2450c41d9b560 (patch)
tree66fa62381cba101e336000865a1c3e561f3298d5
parent4f177c9ee7452274f5e792349e9b443d78a27816 (diff)
Add SMLAL (vector), fix EXT instruction
-rw-r--r--ChocolArm64/AOpCodeTable.cs1
-rw-r--r--ChocolArm64/Decoder/AOpCodeSimdExt.cs2
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs9
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdHelper.cs21
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdMove.cs13
5 files changed, 37 insertions, 9 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 6b250b4b..5afdbd1f 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -243,6 +243,7 @@ namespace ChocolArm64
Set("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V, typeof(AOpCodeSimdShImm));
Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg));
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("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
diff --git a/ChocolArm64/Decoder/AOpCodeSimdExt.cs b/ChocolArm64/Decoder/AOpCodeSimdExt.cs
index cf22d654..888e4470 100644
--- a/ChocolArm64/Decoder/AOpCodeSimdExt.cs
+++ b/ChocolArm64/Decoder/AOpCodeSimdExt.cs
@@ -8,7 +8,7 @@ namespace ChocolArm64.Decoder
public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{
- int Imm4 = (OpCode >> 11) & 0xf;
+ Imm4 = (OpCode >> 11) & 0xf;
}
}
} \ No newline at end of file
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 9f5cc64f..b2d190f1 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -374,6 +374,15 @@ namespace ChocolArm64.Instruction
EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
}
+ public static void Smlal_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmTernaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Add);
+ });
+ }
+
public static void Smull_V(AILEmitterCtx Context)
{
EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
index 33e4d548..e6ead99a 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
@@ -459,15 +459,25 @@ namespace ChocolArm64.Instruction
public static void EmitVectorWidenRnRmBinaryOpSx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorWidenRnRmBinaryOp(Context, Emit, true);
+ EmitVectorWidenRnRmOp(Context, Emit, false, true);
}
public static void EmitVectorWidenRnRmBinaryOpZx(AILEmitterCtx Context, Action Emit)
{
- EmitVectorWidenRnRmBinaryOp(Context, Emit, false);
+ EmitVectorWidenRnRmOp(Context, Emit, false, false);
}
- public static void EmitVectorWidenRnRmBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed)
+ public static void EmitVectorWidenRnRmTernaryOpSx(AILEmitterCtx Context, Action Emit)
+ {
+ EmitVectorWidenRnRmOp(Context, Emit, true, true);
+ }
+
+ public static void EmitVectorWidenRnRmTernaryOpZx(AILEmitterCtx Context, Action Emit)
+ {
+ EmitVectorWidenRnRmOp(Context, Emit, true, false);
+ }
+
+ public static void EmitVectorWidenRnRmOp(AILEmitterCtx Context, Action Emit, bool Ternary, bool Signed)
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
@@ -477,6 +487,11 @@ namespace ChocolArm64.Instruction
for (int Index = 0; Index < Elems; Index++)
{
+ if (Ternary)
+ {
+ EmitVectorExtract(Context, Op.Rd, Index, Op.Size + 1, Signed);
+ }
+
EmitVectorExtract(Context, Op.Rn, Part + Index, Op.Size, Signed);
EmitVectorExtract(Context, Op.Rm, Part + Index, Op.Size, Signed);
diff --git a/ChocolArm64/Instruction/AInstEmitSimdMove.cs b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
index a4e53370..3f427ad8 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdMove.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
@@ -63,15 +63,18 @@ namespace ChocolArm64.Instruction
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Position = Op.Imm4;
+
for (int Index = 0; Index < Bytes; Index++)
{
- int Position = Op.Imm4 + Index;
-
- int Reg = Position < Bytes ? Op.Rn : Op.Rm;
+ int Reg = Op.Imm4 + Index < Bytes ? Op.Rn : Op.Rm;
- Position &= Bytes - 1;
+ if (Position == Bytes)
+ {
+ Position = 0;
+ }
- EmitVectorExtractZx(Context, Reg, Position, 0);
+ EmitVectorExtractZx(Context, Reg, Position++, 0);
EmitVectorInsert(Context, Op.Rd, Index, 0);
}