diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-06-25 18:40:55 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-06-25 18:40:55 -0300 |
| commit | 37a6e84fd49a4e73747281e92d795c5401be901e (patch) | |
| tree | be0deff4b27f9c57c450ce2146bee919059d23b2 /ChocolArm64/Instruction | |
| parent | 8f4cd35ade6204aac01ecee9f4303a4e9ac191a4 (diff) | |
Add REV16/32 (vector) instructions and fix REV64
Diffstat (limited to 'ChocolArm64/Instruction')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdLogical.cs | 32 |
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); |
