From 31b35a9645524ce25f4bcbcd5f0df8b9784e6b52 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 24 Feb 2018 18:47:08 -0300 Subject: Add FABD (scalar), ADCS, SBCS instructions, update config with better default control mappings, update readme with the new mappings --- ChocolArm64/Instruction/AInstEmitAlu.cs | 30 ++++++++++++-- ChocolArm64/Instruction/AInstEmitAluHelper.cs | 19 +++++++++ ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 47 +++++++++++++--------- ChocolArm64/Instruction/AInstEmitSimdHelper.cs | 32 ++++++--------- 4 files changed, 86 insertions(+), 42 deletions(-) (limited to 'ChocolArm64/Instruction') 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) - { - ASoftFallback.EmitCall(Context, nameof(ASoftFallback.RoundF)); - } - else if (Op.Size == 1) - { - ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Round)); - } - else + EmitScalarUnaryOpF(Context, () => { - throw new InvalidOperationException(); - } - - EmitScalarSetF(Context, Op.Rd, Op.Size); + Context.EmitLdarg(ATranslatedSub.StateArgIdx); + + 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); } -- cgit v1.2.3