diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs index 344911bce..cf3d11c79 100644 --- a/Ryujinx/Cpu/AOpCodeTable.cs +++ b/Ryujinx/Cpu/AOpCodeTable.cs @@ -157,6 +157,7 @@ namespace ChocolArm64 Set("x0011110xx011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Fix, typeof(AOpCodeSimdCvt)); Set("x0011110xx011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Fix, typeof(AOpCodeSimdCvt)); Set("00011110xx1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S, typeof(AOpCodeSimdReg)); + Set("00011111xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S, typeof(AOpCodeSimdReg)); Set("00011110xx1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S, typeof(AOpCodeSimdReg)); Set("00011110xx1xxxxx011010xxxxxxxxxx", AInstEmit.Fmaxnm_S, typeof(AOpCodeSimdReg)); Set("00011110xx1xxxxx010110xxxxxxxxxx", AInstEmit.Fmin_S, typeof(AOpCodeSimdReg)); @@ -170,6 +171,7 @@ namespace ChocolArm64 Set("x0011110xx100111000000xxxxxxxxxx", AInstEmit.Fmov_Itof, typeof(AOpCodeSimdCvt)); Set("x0011110xx101110000000xxxxxxxxxx", AInstEmit.Fmov_Ftoi1, typeof(AOpCodeSimdCvt)); Set("x0011110xx101111000000xxxxxxxxxx", AInstEmit.Fmov_Itof1, typeof(AOpCodeSimdCvt)); + Set("00011111xx0xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fmsub_S, typeof(AOpCodeSimdReg)); Set("00011110xx1xxxxx000010xxxxxxxxxx", AInstEmit.Fmul_S, typeof(AOpCodeSimdReg)); Set("0x1011100x1xxxxx110111xxxxxxxxxx", AInstEmit.Fmul_V, typeof(AOpCodeSimdReg)); Set("0x0011111<> 16) & 0x1f; Bit3 = ((OpCode >> 3) & 0x1) != 0; + Ra = (OpCode >> 10) & 0x1f; + Rm = (OpCode >> 16) & 0x1f; } } } \ No newline at end of file diff --git a/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs b/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs index 8822d69e7..ab4c2fd22 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs @@ -258,6 +258,20 @@ namespace ChocolArm64.Instruction public static void Fdiv_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Div); + public static void Fmadd_S(AILEmitterCtx Context) + { + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; + + Context.EmitLdvecsf(Op.Ra); + Context.EmitLdvecsf(Op.Rn); + Context.EmitLdvecsf(Op.Rm); + + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Add); + + Context.EmitStvecsf(Op.Rd); + } + public static void Fmax_S(AILEmitterCtx Context) => EmitMathOp3(Context, nameof(Math.Max)); public static void Fmin_S(AILEmitterCtx Context) => EmitMathOp3(Context, nameof(Math.Min)); @@ -327,6 +341,23 @@ namespace ChocolArm64.Instruction Context.EmitStvec(Op.Rd); } + public static void Fmsub_S(AILEmitterCtx Context) + { + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; + + Context.EmitLdvecsf(Op.Ra); + Context.EmitLdvecsf(Op.Rn); + + Context.Emit(OpCodes.Neg); + + Context.EmitLdvecsf(Op.Rm); + + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Sub); + + Context.EmitStvecsf(Op.Rd); + } + public static void Fmul_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Mul); public static void Fneg_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Neg);