From 31b35a9645524ce25f4bcbcd5f0df8b9784e6b52 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 24 Feb 2018 18:47:08 -0300 Subject: [PATCH] Add FABD (scalar), ADCS, SBCS instructions, update config with better default control mappings, update readme with the new mappings --- ChocolArm64/AOpCodeTable.cs | 3 ++ ChocolArm64/ATranslator.cs | 6 +-- ChocolArm64/Instruction/AInstEmitAlu.cs | 30 +++++++++++-- ChocolArm64/Instruction/AInstEmitAluHelper.cs | 19 ++++++++ .../Instruction/AInstEmitSimdArithmetic.cs | 45 +++++++++++-------- .../Instruction/AInstEmitSimdHelper.cs | 32 ++++++------- README.md | 44 +++++++++++------- Ryujinx/Ryujinx.conf | 40 ++++++++--------- 8 files changed, 138 insertions(+), 81 deletions(-) diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index 71a944cf..14ca231b 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -11,6 +11,7 @@ namespace ChocolArm64 #region "OpCode Table" //Integer Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs)); + Set("x0111010000xxxxx000000xxxxxxxxxx", AInstEmit.Adcs, typeof(AOpCodeAluRs)); Set("x00100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm)); Set("x0001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs)); Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx)); @@ -90,6 +91,7 @@ namespace ChocolArm64 Set("1101101011000000000011xxxxxxxxxx", AInstEmit.Rev64, typeof(AOpCodeAlu)); Set("x0011010110xxxxx001011xxxxxxxxxx", AInstEmit.Rorv, typeof(AOpCodeAluRs)); Set("x1011010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbc, typeof(AOpCodeAluRs)); + Set("x1111010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbcs, typeof(AOpCodeAluRs)); Set("x00100110xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sbfm, typeof(AOpCodeBfm)); Set("x0011010110xxxxx000011xxxxxxxxxx", AInstEmit.Sdiv, typeof(AOpCodeAluRs)); Set("10011011001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Smaddl, typeof(AOpCodeMul)); @@ -145,6 +147,7 @@ namespace ChocolArm64 Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns)); Set("0x001110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_V, typeof(AOpCodeSimdIns)); Set("0x101110001xxxxx000111xxxxxxxxxx", AInstEmit.Eor_V, typeof(AOpCodeSimdReg)); + Set("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S, typeof(AOpCodeSimdReg)); Set("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S, typeof(AOpCodeSimd)); Set("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S, typeof(AOpCodeSimdReg)); Set("0>0011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V, typeof(AOpCodeSimdReg)); diff --git a/ChocolArm64/ATranslator.cs b/ChocolArm64/ATranslator.cs index 04cef44f..96bbc89e 100644 --- a/ChocolArm64/ATranslator.cs +++ b/ChocolArm64/ATranslator.cs @@ -6,7 +6,7 @@ using System.Reflection.Emit; namespace ChocolArm64 { - public class ATranslator + class ATranslator { public AThread Thread { get; private set; } @@ -41,7 +41,7 @@ namespace ChocolArm64 while (Position != 0 && KeepRunning); } - internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub) + public bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub) { if (OpCode.Emitter != AInstEmit.Bl) { @@ -53,7 +53,7 @@ namespace ChocolArm64 return TryGetCachedSub(((AOpCodeBImmAl)OpCode).Imm, out Sub); } - internal bool TryGetCachedSub(long Position, out ATranslatedSub Sub) + public bool TryGetCachedSub(long Position, out ATranslatedSub Sub) { return CachedSubs.TryGetValue(Position, out Sub); } diff --git a/ChocolArm64/Instruction/AInstEmitAlu.cs b/ChocolArm64/Instruction/AInstEmitAlu.cs index 72903f5b..71d9a660 100644 --- a/ChocolArm64/Instruction/AInstEmitAlu.cs +++ b/ChocolArm64/Instruction/AInstEmitAlu.cs @@ -11,7 +11,10 @@ namespace ChocolArm64.Instruction { static partial class AInstEmit { - public static void Adc(AILEmitterCtx Context) + public static void Adc(AILEmitterCtx Context) => EmitAdc(Context, false); + public static void Adcs(AILEmitterCtx Context) => EmitAdc(Context, true); + + private static void EmitAdc(AILEmitterCtx Context, bool SetFlags) { EmitDataLoadOpers(Context); @@ -27,11 +30,19 @@ namespace ChocolArm64.Instruction if (Context.CurrOp.RegisterSize != ARegisterSize.Int32) { - Context.Emit(OpCodes.Conv_I8); + Context.Emit(OpCodes.Conv_U8); } Context.Emit(OpCodes.Add); + if (SetFlags) + { + Context.EmitZNFlagCheck(); + + EmitAddsCCheck(Context); + EmitAddsVCheck(Context); + } + EmitDataStore(Context); } @@ -145,7 +156,10 @@ 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) + public static void Sbc(AILEmitterCtx Context) => EmitSbc(Context, false); + public static void Sbcs(AILEmitterCtx Context) => EmitSbc(Context, true); + + private static void EmitSbc(AILEmitterCtx Context, bool SetFlags) { EmitDataLoadOpers(Context); @@ -165,11 +179,19 @@ namespace ChocolArm64.Instruction if (Context.CurrOp.RegisterSize != ARegisterSize.Int32) { - Context.Emit(OpCodes.Conv_I8); + Context.Emit(OpCodes.Conv_U8); } Context.Emit(OpCodes.Sub); + if (SetFlags) + { + Context.EmitZNFlagCheck(); + + EmitSbcsCCheck(Context); + EmitSubsVCheck(Context); + } + EmitDataStore(Context); } diff --git a/ChocolArm64/Instruction/AInstEmitAluHelper.cs b/ChocolArm64/Instruction/AInstEmitAluHelper.cs index e848742d..b2ea92a6 100644 --- a/ChocolArm64/Instruction/AInstEmitAluHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitAluHelper.cs @@ -41,6 +41,25 @@ namespace ChocolArm64.Instruction Context.EmitStflg((int)APState.VBit); } + public static void EmitSbcsCCheck(AILEmitterCtx Context) + { + //C = (Rn == Rm && CIn) || Rn > Rm + EmitDataLoadOpers(Context); + + Context.Emit(OpCodes.Ceq); + + Context.EmitLdflg((int)APState.CBit); + + Context.Emit(OpCodes.And); + + EmitDataLoadOpers(Context); + + Context.Emit(OpCodes.Cgt_Un); + Context.Emit(OpCodes.Or); + + Context.EmitStflg((int)APState.CBit); + } + public static void EmitSubsCCheck(AILEmitterCtx Context) { //C = Rn == Rm || Rn > Rm = !(Rn < Rm) diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index e1fd56e0..e790d678 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -101,6 +101,16 @@ namespace ChocolArm64.Instruction } } + public static void Fabd_S(AILEmitterCtx Context) + { + EmitScalarBinaryOpF(Context, () => + { + Context.Emit(OpCodes.Sub); + + EmitUnaryMathCall(Context, nameof(Math.Abs)); + }); + } + public static void Fabs_S(AILEmitterCtx Context) { EmitScalarUnaryOpF(Context, () => @@ -269,26 +279,25 @@ namespace ChocolArm64.Instruction { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; - EmitVectorExtractF(Context, Op.Rn, 0, Op.Size); - - Context.EmitLdarg(ATranslatedSub.StateArgIdx); - - Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpcr)); - - if (Op.Size == 0) + EmitScalarUnaryOpF(Context, () => { - ASoftFallback.EmitCall(Context, nameof(ASoftFallback.RoundF)); - } - else if (Op.Size == 1) - { - ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Round)); - } - else - { - throw new InvalidOperationException(); - } + Context.EmitLdarg(ATranslatedSub.StateArgIdx); - EmitScalarSetF(Context, Op.Rd, Op.Size); + Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpcr)); + + if (Op.Size == 0) + { + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.RoundF)); + } + else if (Op.Size == 1) + { + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Round)); + } + else + { + throw new InvalidOperationException(); + } + }); } public static void Fsqrt_S(AILEmitterCtx Context) diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs index 20c8be26..68ee3d3e 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs @@ -36,20 +36,18 @@ namespace ChocolArm64.Instruction { IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp; + int SizeF = Op.Size & 1; + MethodInfo MthdInfo; - if (Op.Size == 0) + if (SizeF == 0) { MthdInfo = typeof(MathF).GetMethod(Name, new Type[] { typeof(float) }); } - else if (Op.Size == 1) + else /* if (SizeF == 1) */ { MthdInfo = typeof(Math).GetMethod(Name, new Type[] { typeof(double) }); } - else - { - throw new InvalidOperationException(); - } Context.EmitCall(MthdInfo); } @@ -58,20 +56,18 @@ namespace ChocolArm64.Instruction { IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp; + int SizeF = Op.Size & 1; + MethodInfo MthdInfo; - if (Op.Size == 0) + if (SizeF == 0) { MthdInfo = typeof(MathF).GetMethod(Name, new Type[] { typeof(float), typeof(float) }); } - else if (Op.Size == 1) + else /* if (SizeF == 1) */ { MthdInfo = typeof(Math).GetMethod(Name, new Type[] { typeof(double), typeof(double) }); } - else - { - throw new InvalidOperationException(); - } Context.EmitCall(MthdInfo); } @@ -80,28 +76,26 @@ namespace ChocolArm64.Instruction { IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp; + int SizeF = Op.Size & 1; + Context.EmitLdc_I4((int)RoundMode); MethodInfo MthdInfo; Type[] Types = new Type[] { null, typeof(MidpointRounding) }; - Types[0] = Op.Size == 0 + Types[0] = SizeF == 0 ? typeof(float) : typeof(double); - if (Op.Size == 0) + if (SizeF == 0) { MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), Types); } - else if (Op.Size == 1) + else /* if (SizeF == 1) */ { MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types); } - else - { - throw new InvalidOperationException(); - } Context.EmitCall(MthdInfo); } diff --git a/README.md b/README.md index d2199244..6a241127 100644 --- a/README.md +++ b/README.md @@ -18,23 +18,33 @@ Or just drag'n'drop the *.NRO / *.NSO or the game folder on the executable if yo https://openal.org/downloads/OpenAL11CoreSDK.zip - Keyboard Input is partially supported: - - Arrows. - - Enter > "Start" & Tab > "Select" - - Qwerty: - - A > "A" (QWERTY) / Q > "A" (AZERTY) - - S > "B" - - Z > "X" (QWERTY) / W > "X" (AZERTY) - - X > "Y" - - Key_Up > "Right Stick Up" - - Key_Down > "Right Stick Down" - - Key_Left > "Right Stick Left" - - Key_Right > "Right Stick Right" - - I > "Left Stick Up" - - K > "Left Stick Down" - - J > "Left Stick Left" - - L > "Left Stick Right" - - Tab > "Minus" - - Enter > "Plus" + - Left Joycon: + - Stick Up = W + - Stick Down = S + - Stick Left = A + - Stick Right = D + - Stick Button = F + - DPad Up = Up + - DPad Down = Down + - DPad Left = Left + - DPad Right = Right + - Minus = - + - L = E + - ZL = Q + + - Right Joycon: + - Stick Up = I + - Stick Down = K + - Stick Left = J + - Stick Right = L + - Stick Button = H + - A = Z + - B = X + - X = C + - Y = V + - Plus = + + - R = U + - ZR = O - Config File: `Ryujinx.conf` should be present in executable folder. For more informations [you can go here](CONFIG.md). diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 8f791df3..7b9af87a 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -20,28 +20,28 @@ Logging_Enable_Fatal = true Logging_Enable_LogFile = false #https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs -Controls_Left_FakeJoycon_Stick_Up = 91 -Controls_Left_FakeJoycon_Stick_Down = 93 -Controls_Left_FakeJoycon_Stick_Left = 92 -Controls_Left_FakeJoycon_Stick_Right = 94 -Controls_Left_FakeJoycon_Stick_Button = 0 +Controls_Left_FakeJoycon_Stick_Up = 105 +Controls_Left_FakeJoycon_Stick_Down = 101 +Controls_Left_FakeJoycon_Stick_Left = 83 +Controls_Left_FakeJoycon_Stick_Right = 86 +Controls_Left_FakeJoycon_Stick_Button = 88 Controls_Left_FakeJoycon_DPad_Up = 45 Controls_Left_FakeJoycon_DPad_Down = 46 Controls_Left_FakeJoycon_DPad_Left = 47 Controls_Left_FakeJoycon_DPad_Right = 48 -Controls_Left_FakeJoycon_Button_Minus = 52 -Controls_Left_FakeJoycon_Button_L = 0 -Controls_Left_FakeJoycon_Button_ZL = 0 +Controls_Left_FakeJoycon_Button_Minus = 120 +Controls_Left_FakeJoycon_Button_L = 87 +Controls_Left_FakeJoycon_Button_ZL = 99 -Controls_Right_FakeJoycon_Stick_Up = 45 -Controls_Right_FakeJoycon_Stick_Down = 46 -Controls_Right_FakeJoycon_Stick_Left = 47 -Controls_Right_FakeJoycon_Stick_Right = 48 -Controls_Right_FakeJoycon_Stick_Button = 0 -Controls_Right_FakeJoycon_Button_A = 83 -Controls_Right_FakeJoycon_Button_B = 101 -Controls_Right_FakeJoycon_Button_X = 106 -Controls_Right_FakeJoycon_Button_Y = 108 -Controls_Right_FakeJoycon_Button_Plus = 49 -Controls_Right_FakeJoycon_Button_R = 0 -Controls_Right_FakeJoycon_Button_ZR = 0 +Controls_Right_FakeJoycon_Stick_Up = 91 +Controls_Right_FakeJoycon_Stick_Down = 93 +Controls_Right_FakeJoycon_Stick_Left = 92 +Controls_Right_FakeJoycon_Stick_Right = 94 +Controls_Right_FakeJoycon_Stick_Button = 90 +Controls_Right_FakeJoycon_Button_A = 108 +Controls_Right_FakeJoycon_Button_B = 106 +Controls_Right_FakeJoycon_Button_X = 85 +Controls_Right_FakeJoycon_Button_Y = 104 +Controls_Right_FakeJoycon_Button_Plus = 121 +Controls_Right_FakeJoycon_Button_R = 103 +Controls_Right_FakeJoycon_Button_ZR = 97