aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-06-25 18:40:55 -0300
committergdkchan <gab.dark.100@gmail.com>2018-06-25 18:40:55 -0300
commit37a6e84fd49a4e73747281e92d795c5401be901e (patch)
treebe0deff4b27f9c57c450ce2146bee919059d23b2 /ChocolArm64/Instruction
parent8f4cd35ade6204aac01ecee9f4303a4e9ac191a4 (diff)
Add REV16/32 (vector) instructions and fix REV64
Diffstat (limited to 'ChocolArm64/Instruction')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdLogical.cs32
1 files changed, 29 insertions, 3 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
index cb6ee4cd..163151f8 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs
@@ -1,6 +1,7 @@
using ChocolArm64.Decoder;
using ChocolArm64.State;
using ChocolArm64.Translation;
+using System;
using System.Reflection.Emit;
using System.Runtime.Intrinsics.X86;
@@ -144,23 +145,48 @@ namespace ChocolArm64.Instruction
EmitVectorImmBinaryOp(Context, () => Context.Emit(OpCodes.Or));
}
+ public static void Rev16_V(AILEmitterCtx Context)
+ {
+ EmitRev_V(Context, ContainerSize: 1);
+ }
+
+ public static void Rev32_V(AILEmitterCtx Context)
+ {
+ EmitRev_V(Context, ContainerSize: 2);
+ }
+
public static void Rev64_V(AILEmitterCtx Context)
{
+ EmitRev_V(Context, ContainerSize: 3);
+ }
+
+ private static void EmitRev_V(AILEmitterCtx Context, int ContainerSize)
+ {
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
int Elems = Bytes >> Op.Size;
- int RevIndex = Elems - 1;
+ if (Op.Size >= ContainerSize)
+ {
+ throw new InvalidOperationException();
+ }
+
+ int ContainerMask = (1 << (ContainerSize - Op.Size)) - 1;
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
{
- EmitVectorExtractZx(Context, Op.Rn, RevIndex--, Op.Size);
+ int RevIndex = Index ^ ContainerMask;
- EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
+ EmitVectorExtractZx(Context, Op.Rn, RevIndex, Op.Size);
+
+ EmitVectorInsertTmp(Context, Index, Op.Size);
}
+ Context.EmitLdvectmp();
+ Context.EmitStvec(Op.Rd);
+
if (Op.RegisterSize == ARegisterSize.SIMD64)
{
EmitVectorZeroUpper(Context, Op.Rd);