aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-03-02 19:21:54 -0300
committergdkchan <gab.dark.100@gmail.com>2018-03-02 19:23:38 -0300
commitf39a864050589ac7e757a9d72b46ac693125b382 (patch)
treeba56ae59aabca61e0efd4d68ce227b93a6b78477
parent1d71e33171f78fb40b097108fbd5915f18c608c4 (diff)
Add EXT, CMTST (vector) and UMULL (vector) instructions
-rw-r--r--ChocolArm64/AOpCodeTable.cs3
-rw-r--r--ChocolArm64/Decoder/AOpCodeSimdExt.cs14
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs5
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdCmp.cs39
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdMove.cs25
5 files changed, 86 insertions, 0 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 14ca231b..470b70e0 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -142,11 +142,13 @@ namespace ChocolArm64
Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
+ Set("0>001110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_V, typeof(AOpCodeSimdReg));
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
Set("0x001110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_V, typeof(AOpCodeSimdIns));
Set("0x101110001xxxxx000111xxxxxxxxxx", AInstEmit.Eor_V, typeof(AOpCodeSimdReg));
+ Set("0>101110000xxxxx0<xxx0xxxxxxxxxx", AInstEmit.Ext_V, typeof(AOpCodeSimdExt));
Set("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S, typeof(AOpCodeSimdReg));
Set("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S, typeof(AOpCodeSimd));
Set("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S, typeof(AOpCodeSimdReg));
@@ -262,6 +264,7 @@ namespace ChocolArm64
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_S, typeof(AOpCodeSimd));
Set("0x1011100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimd));
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
+ Set("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
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/Decoder/AOpCodeSimdExt.cs b/ChocolArm64/Decoder/AOpCodeSimdExt.cs
new file mode 100644
index 00000000..cf22d654
--- /dev/null
+++ b/ChocolArm64/Decoder/AOpCodeSimdExt.cs
@@ -0,0 +1,14 @@
+using ChocolArm64.Instruction;
+
+namespace ChocolArm64.Decoder
+{
+ class AOpCodeSimdExt : AOpCodeSimdReg
+ {
+ public int Imm4 { get; private set; }
+
+ public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
+ {
+ int Imm4 = (OpCode >> 11) & 0xf;
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index e790d678..9c1bc286 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -406,5 +406,10 @@ namespace ChocolArm64.Instruction
{
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
}
+
+ public static void Umull_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
+ }
}
} \ No newline at end of file
diff --git a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
index 97ccf0ab..76861b73 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
@@ -46,6 +46,45 @@ namespace ChocolArm64.Instruction
EmitVectorCmp(Context, OpCodes.Blt_S);
}
+ public static void Cmtst_V(AILEmitterCtx Context)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
+
+ for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
+ {
+ EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
+ EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
+
+ AILLabel LblTrue = new AILLabel();
+ AILLabel LblEnd = new AILLabel();
+
+ Context.Emit(OpCodes.And);
+
+ Context.EmitLdc_I4(0);
+
+ Context.Emit(OpCodes.Bne_Un_S, LblTrue);
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size, 0);
+
+ Context.Emit(OpCodes.Br_S, LblEnd);
+
+ Context.MarkLabel(LblTrue);
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size, (long)SzMask);
+
+ Context.MarkLabel(LblEnd);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
public static void Fccmp_S(AILEmitterCtx Context)
{
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
diff --git a/ChocolArm64/Instruction/AInstEmitSimdMove.cs b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
index aabb8f34..a4e53370 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdMove.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdMove.cs
@@ -57,6 +57,31 @@ namespace ChocolArm64.Instruction
}
}
+ public static void Ext_V(AILEmitterCtx Context)
+ {
+ AOpCodeSimdExt Op = (AOpCodeSimdExt)Context.CurrOp;
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ for (int Index = 0; Index < Bytes; Index++)
+ {
+ int Position = Op.Imm4 + Index;
+
+ int Reg = Position < Bytes ? Op.Rn : Op.Rm;
+
+ Position &= Bytes - 1;
+
+ EmitVectorExtractZx(Context, Reg, Position, 0);
+
+ EmitVectorInsert(Context, Op.Rd, Index, 0);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
public static void Fcsel_S(AILEmitterCtx Context)
{
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;