diff options
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitAlu.cs')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitAlu.cs | 422 |
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); - } - } - } -} |
