From 37a6e84fd49a4e73747281e92d795c5401be901e Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 25 Jun 2018 18:40:55 -0300 Subject: [PATCH] Add REV16/32 (vector) instructions and fix REV64 --- ChocolArm64/AOpCodeTable.cs | 2 ++ .../Instruction/AInstEmitSimdLogical.cs | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index c0c38bb39..fcaee3847 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -347,6 +347,8 @@ namespace ChocolArm64 SetA64("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg)); SetA64("0x00111100000xxx< 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; @@ -152,15 +168,25 @@ namespace ChocolArm64.Instruction 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);