aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-02-24 18:47:08 -0300
committergdkchan <gab.dark.100@gmail.com>2018-02-24 18:47:08 -0300
commit31b35a9645524ce25f4bcbcd5f0df8b9784e6b52 (patch)
treefe523cb14748d5f2eb6c3417fcf36a0549089f65 /ChocolArm64/Instruction
parentc02a2b510f4f461c96e4a98e0059f35b5dde97c9 (diff)
Add FABD (scalar), ADCS, SBCS instructions, update config with better default control mappings, update readme with the new mappings
Diffstat (limited to 'ChocolArm64/Instruction')
-rw-r--r--ChocolArm64/Instruction/AInstEmitAlu.cs30
-rw-r--r--ChocolArm64/Instruction/AInstEmitAluHelper.cs19
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs47
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdHelper.cs32
4 files changed, 86 insertions, 42 deletions
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);
}