aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions/InstEmitAlu.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitAlu.cs')
-rw-r--r--ChocolArm64/Instructions/InstEmitAlu.cs422
1 files changed, 0 insertions, 422 deletions
diff --git a/ChocolArm64/Instructions/InstEmitAlu.cs b/ChocolArm64/Instructions/InstEmitAlu.cs
deleted file mode 100644
index 25bd8e64..00000000
--- a/ChocolArm64/Instructions/InstEmitAlu.cs
+++ /dev/null
@@ -1,422 +0,0 @@
-using ChocolArm64.Decoders;
-using ChocolArm64.IntermediateRepresentation;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Intrinsics.X86;
-
-using static ChocolArm64.Instructions.InstEmitAluHelper;
-
-namespace ChocolArm64.Instructions
-{
- static partial class InstEmit
- {
- public static void Adc(ILEmitterCtx context) => EmitAdc(context, false);
- public static void Adcs(ILEmitterCtx context) => EmitAdc(context, true);
-
- private static void EmitAdc(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Add);
-
- context.EmitLdflg((int)PState.CBit);
-
- Type[] mthdTypes = new Type[] { typeof(bool) };
-
- MethodInfo mthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), mthdTypes);
-
- context.EmitCall(mthdInfo);
-
- if (context.CurrOp.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.Emit(OpCodes.Add);
-
- if (setFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitAdcsCCheck(context);
- EmitAddsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- public static void Add(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Add);
-
- public static void Adds(ILEmitterCtx context)
- {
- context.TryOptMarkCondWithoutCmp();
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Add);
-
- context.EmitZnFlagCheck();
-
- EmitAddsCCheck(context);
- EmitAddsVCheck(context);
- EmitAluStoreS(context);
- }
-
- public static void And(ILEmitterCtx context) => EmitAluOp(context, OpCodes.And);
-
- public static void Ands(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.And);
-
- EmitZeroCvFlags(context);
-
- context.EmitZnFlagCheck();
-
- EmitAluStoreS(context);
- }
-
- public static void Asrv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shr);
-
- public static void Bic(ILEmitterCtx context) => EmitBic(context, false);
- public static void Bics(ILEmitterCtx context) => EmitBic(context, true);
-
- private static void EmitBic(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.And);
-
- if (setFlags)
- {
- EmitZeroCvFlags(context);
-
- context.EmitZnFlagCheck();
- }
-
- EmitAluStore(context, setFlags);
- }
-
- public static void Cls(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- context.EmitLdc_I4(op.RegisterSize == RegisterSize.Int32 ? 32 : 64);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingSigns));
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Clz(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (Lzcnt.IsSupported)
- {
- Type tValue = op.RegisterSize == RegisterSize.Int32 ? typeof(uint) : typeof(ulong);
-
- context.EmitCall(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { tValue }));
- }
- else
- {
- context.EmitLdc_I4(op.RegisterSize == RegisterSize.Int32 ? 32 : 64);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.CountLeadingZeros));
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Eon(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.Xor);
-
- EmitAluStore(context);
- }
-
- public static void Eor(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Xor);
-
- public static void Extr(ILEmitterCtx context)
- {
- // TODO: Ensure that the Shift is valid for the Is64Bits.
- OpCodeAluRs64 op = (OpCodeAluRs64)context.CurrOp;
-
- context.EmitLdintzr(op.Rm);
-
- if (op.Shift > 0)
- {
- context.EmitLdc_I4(op.Shift);
-
- context.Emit(OpCodes.Shr_Un);
-
- context.EmitLdintzr(op.Rn);
- context.EmitLdc_I4(op.GetBitsCount() - op.Shift);
-
- context.Emit(OpCodes.Shl);
- context.Emit(OpCodes.Or);
- }
-
- EmitAluStore(context);
- }
-
- public static void Lslv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shl);
- public static void Lsrv(ILEmitterCtx context) => EmitAluOpShift(context, OpCodes.Shr_Un);
-
- public static void Sbc(ILEmitterCtx context) => EmitSbc(context, false);
- public static void Sbcs(ILEmitterCtx context) => EmitSbc(context, true);
-
- private static void EmitSbc(ILEmitterCtx context, bool setFlags)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Sub);
-
- context.EmitLdflg((int)PState.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 != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_U8);
- }
-
- context.Emit(OpCodes.Sub);
-
- if (setFlags)
- {
- context.EmitZnFlagCheck();
-
- EmitSbcsCCheck(context);
- EmitSubsVCheck(context);
- }
-
- EmitAluStore(context);
- }
-
- public static void Sub(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Sub);
-
- public static void Subs(ILEmitterCtx context)
- {
- context.TryOptMarkCondWithoutCmp();
-
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Sub);
-
- context.EmitZnFlagCheck();
-
- EmitSubsCCheck(context);
- EmitSubsVCheck(context);
- EmitAluStoreS(context);
- }
-
- public static void Orn(ILEmitterCtx context)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(OpCodes.Not);
- context.Emit(OpCodes.Or);
-
- EmitAluStore(context);
- }
-
- public static void Orr(ILEmitterCtx context) => EmitAluOp(context, OpCodes.Or);
-
- public static void Rbit(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBits32),
- nameof(SoftFallback.ReverseBits64));
-
- public static void Rev16(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBytes16_32),
- nameof(SoftFallback.ReverseBytes16_64));
-
- public static void Rev32(ILEmitterCtx context) => EmitFallback32_64(context,
- nameof(SoftFallback.ReverseBytes32_32),
- nameof(SoftFallback.ReverseBytes32_64));
-
- private static void EmitFallback32_64(ILEmitterCtx context, string name32, string name64)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- if (op.RegisterSize == RegisterSize.Int32)
- {
- SoftFallback.EmitCall(context, name32);
- }
- else
- {
- SoftFallback.EmitCall(context, name64);
- }
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Rev64(ILEmitterCtx context)
- {
- OpCodeAlu64 op = (OpCodeAlu64)context.CurrOp;
-
- context.EmitLdintzr(op.Rn);
-
- SoftFallback.EmitCall(context, nameof(SoftFallback.ReverseBytes64));
-
- context.EmitStintzr(op.Rd);
- }
-
- public static void Rorv(ILEmitterCtx context)
- {
- EmitAluLoadRn(context);
- EmitAluLoadShift(context);
-
- context.Emit(OpCodes.Shr_Un);
-
- EmitAluLoadRn(context);
-
- context.EmitLdc_I4(context.CurrOp.GetBitsCount());
-
- EmitAluLoadShift(context);
-
- context.Emit(OpCodes.Sub);
- context.Emit(OpCodes.Shl);
- context.Emit(OpCodes.Or);
-
- EmitAluStore(context);
- }
-
- public static void Sdiv(ILEmitterCtx context) => EmitDiv(context, OpCodes.Div);
- public static void Udiv(ILEmitterCtx context) => EmitDiv(context, OpCodes.Div_Un);
-
- private static void EmitDiv(ILEmitterCtx context, OpCode ilOp)
- {
- // If Rm == 0, Rd = 0 (division by zero).
- context.EmitLdc_I(0);
-
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(0);
-
- ILLabel badDiv = new ILLabel();
-
- context.Emit(OpCodes.Beq_S, badDiv);
- context.Emit(OpCodes.Pop);
-
- if (ilOp == OpCodes.Div)
- {
- // If Rn == INT_MIN && Rm == -1, Rd = INT_MIN (overflow).
- long intMin = 1L << (context.CurrOp.GetBitsCount() - 1);
-
- context.EmitLdc_I(intMin);
-
- EmitAluLoadRn(context);
-
- context.EmitLdc_I(intMin);
-
- context.Emit(OpCodes.Ceq);
-
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(-1);
-
- context.Emit(OpCodes.Ceq);
- context.Emit(OpCodes.And);
- context.Emit(OpCodes.Brtrue_S, badDiv);
- context.Emit(OpCodes.Pop);
- }
-
- EmitAluLoadRn(context);
- EmitAluLoadRm(context);
-
- context.Emit(ilOp);
-
- context.MarkLabel(badDiv);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluOp(ILEmitterCtx context, OpCode ilOp)
- {
- EmitAluLoadOpers(context);
-
- context.Emit(ilOp);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluOpShift(ILEmitterCtx context, OpCode ilOp)
- {
- EmitAluLoadRn(context);
- EmitAluLoadShift(context);
-
- context.Emit(ilOp);
-
- EmitAluStore(context);
- }
-
- private static void EmitAluLoadShift(ILEmitterCtx context)
- {
- EmitAluLoadRm(context);
-
- context.EmitLdc_I(context.CurrOp.GetBitsCount() - 1);
-
- context.Emit(OpCodes.And);
-
- // Note: Only 32-bits shift values are valid, so when the value is 64-bits
- // we need to cast it to a 32-bits integer. This is fine because we
- // AND the value and only keep the lower 5 or 6 bits anyway -- it
- // could very well fit on a byte.
- if (context.CurrOp.RegisterSize != RegisterSize.Int32)
- {
- context.Emit(OpCodes.Conv_I4);
- }
- }
-
- private static void EmitZeroCvFlags(ILEmitterCtx context)
- {
- context.EmitLdc_I4(0);
-
- context.EmitStflg((int)PState.VBit);
-
- context.EmitLdc_I4(0);
-
- context.EmitStflg((int)PState.CBit);
- }
-
- public static void EmitAluStore(ILEmitterCtx context) => EmitAluStore(context, false);
- public static void EmitAluStoreS(ILEmitterCtx context) => EmitAluStore(context, true);
-
- public static void EmitAluStore(ILEmitterCtx context, bool setFlags)
- {
- IOpCodeAlu64 op = (IOpCodeAlu64)context.CurrOp;
-
- if (setFlags || op is IOpCodeAluRs64)
- {
- context.EmitStintzr(op.Rd);
- }
- else
- {
- context.EmitStint(op.Rd);
- }
- }
- }
-}