diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs index a3a8477e..e42136b8 100644 --- a/Ryujinx/Cpu/AOpCodeTable.cs +++ b/Ryujinx/Cpu/AOpCodeTable.cs @@ -203,6 +203,7 @@ namespace ChocolArm64 Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg)); Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit)); Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg)); + Set("0x101110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mls_V, typeof(AOpCodeSimdReg)); Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs index 245862a6..d6ebcc3f 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdArithmetic.cs @@ -182,8 +182,7 @@ namespace ChocolArm64.Instruction EmitScalarTernaryRaOpF(Context, () => { Context.Emit(OpCodes.Mul); - Context.Emit(OpCodes.Neg); - Context.Emit(OpCodes.Add); + Context.Emit(OpCodes.Sub); }); } @@ -262,6 +261,15 @@ namespace ChocolArm64.Instruction }); } + public static void Mls_V(AILEmitterCtx Context) + { + EmitVectorTernaryOpZx(Context, () => + { + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Sub); + }); + } + public static void Mul_V(AILEmitterCtx Context) { EmitVectorBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul)); diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs index e4cdc9c5..97f28816 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitSimdHelper.cs @@ -210,14 +210,14 @@ namespace ChocolArm64.Instruction { AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp; - EmitVectorOpByElemF(Context, Emit, Op.Index); + EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: false); } public static void EmitVectorTernaryOpByElemF(AILEmitterCtx Context, Action Emit) { AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp; - EmitVectorOpByElemF(Context, Emit, Op.Index); + EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: true); } public static void EmitVectorOpF(AILEmitterCtx Context, Action Emit, OperFlags Opers) @@ -256,7 +256,7 @@ namespace ChocolArm64.Instruction } } - public static void EmitVectorOpByElemF(AILEmitterCtx Context, Action Emit, int Elem) + public static void EmitVectorOpByElemF(AILEmitterCtx Context, Action Emit, int Elem, bool Ternary) { AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; @@ -266,6 +266,11 @@ namespace ChocolArm64.Instruction for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++) { + if (Ternary) + { + EmitVectorExtractF(Context, Op.Rd, Index, SizeF); + } + EmitVectorExtractF(Context, Op.Rn, Index, SizeF); EmitVectorExtractF(Context, Op.Rm, Elem, SizeF);