diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs index cf3d11c790..a7deb2c7f8 100644 --- a/Ryujinx/Cpu/AOpCodeTable.cs +++ b/Ryujinx/Cpu/AOpCodeTable.cs @@ -10,6 +10,7 @@ namespace ChocolArm64 { #region "OpCode Table" //Integer + Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs)); Set("x0010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm)); Set("x0001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs)); Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx)); @@ -85,6 +86,7 @@ namespace ChocolArm64 Set("x101101011000000000010xxxxxxxxxx", AInstEmit.Rev32, typeof(AOpCodeAlu)); Set("1101101011000000000011xxxxxxxxxx", AInstEmit.Rev64, typeof(AOpCodeAlu)); Set("x0011010110xxxxx001011xxxxxxxxxx", AInstEmit.Rorv, typeof(AOpCodeAluRs)); + Set("x1011010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbc, typeof(AOpCodeAluRs)); Set("x00100110xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sbfm, typeof(AOpCodeBfm)); Set("x0011010110xxxxx000011xxxxxxxxxx", AInstEmit.Sdiv, typeof(AOpCodeAluRs)); Set("10011011001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Smaddl, typeof(AOpCodeMul)); diff --git a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs index f963f6f7d7..ac9c43c377 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs @@ -1,6 +1,8 @@ using ChocolArm64.Decoder; using ChocolArm64.State; using ChocolArm64.Translation; +using System; +using System.Reflection; using System.Reflection.Emit; using static ChocolArm64.Instruction.AInstEmitAluHelper; @@ -9,6 +11,30 @@ namespace ChocolArm64.Instruction { static partial class AInstEmit { + public static void Adc(AILEmitterCtx Context) + { + EmitDataLoadOpers(Context); + + Context.Emit(OpCodes.Add); + + Context.EmitLdflg((int)APState.CBit); + + Type[] MthdTypes = new Type[] { typeof(bool) }; + + MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes); + + Context.EmitCall(MthdInfo); + + if (Context.CurrOp.RegisterSize != ARegisterSize.Int32) + { + Context.Emit(OpCodes.Conv_I8); + } + + Context.Emit(OpCodes.Add); + + EmitDataStore(Context); + } + public static void Add(AILEmitterCtx Context) => EmitDataOp(Context, OpCodes.Add); public static void Adds(AILEmitterCtx Context) @@ -105,6 +131,34 @@ namespace ChocolArm64.Instruction public static void Lslv(AILEmitterCtx Context) => EmitDataOpShift(Context, OpCodes.Shl); public static void Lsrv(AILEmitterCtx Context) => EmitDataOpShift(Context, OpCodes.Shr_Un); + public static void Sbc(AILEmitterCtx Context) + { + EmitDataLoadOpers(Context); + + Context.Emit(OpCodes.Sub); + + Context.EmitLdflg((int)APState.CBit); + + Type[] MthdTypes = new Type[] { typeof(bool) }; + + MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes); + + Context.EmitCall(MthdInfo); + + Context.EmitLdc_I4(1); + + Context.Emit(OpCodes.Xor); + + if (Context.CurrOp.RegisterSize != ARegisterSize.Int32) + { + Context.Emit(OpCodes.Conv_I8); + } + + Context.Emit(OpCodes.Sub); + + EmitDataStore(Context); + } + public static void Sub(AILEmitterCtx Context) => EmitDataOp(Context, OpCodes.Sub); public static void Subs(AILEmitterCtx Context)