From 88c6160c62b000d155a829b23e6207d78b7dccfa Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 15 Mar 2018 22:36:47 -0300 Subject: [PATCH] Add MLA (vector by element), fixes some cases of MUL (vector by element)? --- ChocolArm64/AOpCodeTable.cs | 1 + ChocolArm64/Decoder/AOpCodeSimdRegElem.cs | 5 ++--- ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 9 +++++++++ ChocolArm64/Instruction/AInstEmitSimdHelper.cs | 7 +++++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index d32bd9cd24..9240c0a7a9 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -228,6 +228,7 @@ namespace ChocolArm64 Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg)); Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit)); Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg)); + Set("0x101111xxxxxxxx0000x0xxxxxxxxxx", AInstEmit.Mla_Ve, typeof(AOpCodeSimdRegElem)); Set("0x101110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mls_V, typeof(AOpCodeSimdReg)); Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); diff --git a/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs b/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs index 721da88faa..d6dc4bd231 100644 --- a/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs +++ b/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs @@ -11,9 +11,8 @@ namespace ChocolArm64.Decoder switch (Size) { case 1: - Index = (OpCode >> 21) & 1 | - (OpCode >> 10) & 2 | - (OpCode >> 18) & 4; + Index = (OpCode >> 20) & 3 | + (OpCode >> 9) & 4; Rm &= 0xf; diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index bf980a581e..989b470ea4 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -335,6 +335,15 @@ namespace ChocolArm64.Instruction }); } + public static void Mla_Ve(AILEmitterCtx Context) + { + EmitVectorTernaryOpByElemZx(Context, () => + { + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Add); + }); + } + public static void Mls_V(AILEmitterCtx Context) { EmitVectorTernaryOpZx(Context, () => diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs index 4e45a11d6a..d8642e99a8 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs @@ -381,13 +381,16 @@ namespace ChocolArm64.Instruction } EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); - EmitVectorExtract(Context, Op.Rm, Index, Op.Size, Signed); + EmitVectorExtract(Context, Op.Rm, Elem, Op.Size, Signed); Emit(); - EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + EmitVectorInsertTmp(Context, Index, Op.Size); } + Context.EmitLdvectmp(); + Context.EmitStvec(Op.Rd); + if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd);