private static void EmitCcmp(ILEmitterCtx context, CcmpOp cmpOp) { OpCodeCcmp64 op = (OpCodeCcmp64)context.CurrOp; ILLabel lblTrue = new ILLabel(); ILLabel lblEnd = new ILLabel(); context.EmitCondBranch(lblTrue, op.Cond); context.EmitLdc_I4((op.Nzcv >> 0) & 1); context.EmitStflg((int)PState.VBit); context.EmitLdc_I4((op.Nzcv >> 1) & 1); context.EmitStflg((int)PState.CBit); context.EmitLdc_I4((op.Nzcv >> 2) & 1); context.EmitStflg((int)PState.ZBit); context.EmitLdc_I4((op.Nzcv >> 3) & 1); context.EmitStflg((int)PState.NBit); context.Emit(OpCodes.Br_S, lblEnd); context.MarkLabel(lblTrue); EmitAluLoadOpers(context); if (cmpOp == CcmpOp.Cmp) { context.Emit(OpCodes.Sub); context.EmitZnFlagCheck(); EmitSubsCCheck(context); EmitSubsVCheck(context); } else if (cmpOp == CcmpOp.Cmn) { context.Emit(OpCodes.Add); context.EmitZnFlagCheck(); EmitAddsCCheck(context); EmitAddsVCheck(context); } else { throw new ArgumentException(nameof(cmpOp)); } context.Emit(OpCodes.Pop); context.MarkLabel(lblEnd); }
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 Ands(ILEmitterCtx context) { EmitAluLoadOpers(context); context.Emit(OpCodes.And); EmitZeroCvFlags(context); context.EmitZnFlagCheck(); EmitAluStoreS(context); }
public static void Adds(ILEmitterCtx context) { EmitAluLoadOpers(context); context.Emit(OpCodes.Add); context.EmitZnFlagCheck(); EmitAddsCCheck(context); EmitAddsVCheck(context); EmitAluStoreS(context); }
public static void Mov(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; EmitAluLoadOper2(context); if (op.SetFlags) { context.EmitZnFlagCheck(); } EmitAluStore(context); }
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 Subs(ILEmitterCtx context) { context.TryOptMarkCondWithoutCmp(); EmitDataLoadOpers(context); context.Emit(OpCodes.Sub); context.EmitZnFlagCheck(); EmitSubsCCheck(context); EmitSubsVCheck(context); EmitDataStoreS(context); }
public static void Cmp(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; EmitAluLoadOpers(context, setCarry: false); context.Emit(OpCodes.Sub); context.EmitZnFlagCheck(); EmitSubsCCheck(context); EmitSubsVCheck(context); context.Emit(OpCodes.Pop); }
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 Sub(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; EmitAluLoadOpers(context, setCarry: false); context.Emit(OpCodes.Sub); if (op.SetFlags) { context.EmitZnFlagCheck(); EmitSubsCCheck(context); EmitSubsVCheck(context); } EmitAluStore(context); }