private static void EmitAluStore(ArmEmitterContext context, Operand value) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; if (op.Rd == RegisterAlias.Aarch32Pc) { if (op.SetFlags) { // TODO: Load SPSR etc. Operand isThumb = GetFlag(PState.TFlag); Operand lblThumb = Label(); context.BranchIfTrue(lblThumb, isThumb); context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~3)))); context.MarkLabel(lblThumb); context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); } else { EmitAluWritePc(context, value); } } else { SetIntA32(context, op.Rd, value); } }
public static void Mov(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand m = GetAluM(context); if (op.SetFlags) { EmitNZFlagsCheck(context, m); } EmitAluStore(context, m); }
public static void Mov(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; EmitAluLoadOper2(context); if (op.SetFlags) { context.EmitZnFlagCheck(); } EmitAluStore(context); }
public static void Mvn(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand m = GetAluM(context); Operand res = context.BitwiseNot(m); if (op.SetFlags) { EmitNZFlagsCheck(context, res); } EmitAluStore(context, res); }
public static void Cmp(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context, setCarry: false); Operand res = context.Subtract(n, m); EmitNZFlagsCheck(context, res); EmitSubsCCheck(context, n, res); EmitSubsVCheck(context, n, m, res); }
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); }
public static void Mul(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context); Operand res = context.Multiply(n, m); if (op.SetFlags) { EmitNZFlagsCheck(context, res); } EmitAluStore(context, res); }
public static void Eor(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context); Operand res = context.BitwiseExclusiveOr(n, m); if (op.SetFlags) { EmitNZFlagsCheck(context, res); } EmitAluStore(context, res); }
public static void And(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context); Operand res = context.BitwiseAnd(n, m); if (ShouldSetFlags(context)) { EmitNZFlagsCheck(context, res); } EmitAluStore(context, res); }
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); }
public static void Rsb(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context, setCarry: false); Operand res = context.Subtract(m, n); if (op.SetFlags) { EmitNZFlagsCheck(context, res); EmitSubsCCheck(context, m, res); EmitSubsVCheck(context, m, n, res); } EmitAluStore(context, res); }
public static void Add(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context, setCarry: false); Operand res = context.Add(n, m); if (op.SetFlags) { EmitNZFlagsCheck(context, res); EmitAddsCCheck(context, n, res); EmitAddsVCheck(context, n, m, res); } EmitAluStore(context, res); }
private static void EmitAluStore(ILEmitterCtx context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; if (op.Rd == RegisterAlias.Aarch32Pc) { if (op.SetFlags) { // TODO: Load SPSR etc. context.EmitLdflg((int)PState.TBit); ILLabel lblThumb = new ILLabel(); ILLabel lblEnd = new ILLabel(); context.Emit(OpCodes.Brtrue_S, lblThumb); context.EmitLdc_I4(~3); context.Emit(OpCodes.Br_S, lblEnd); context.MarkLabel(lblThumb); context.EmitLdc_I4(~1); context.MarkLabel(lblEnd); context.Emit(OpCodes.And); context.Emit(OpCodes.Conv_U8); context.Emit(OpCodes.Ret); } else { EmitAluWritePc(context); } } else { context.EmitStint(GetRegisterAlias(context.Mode, op.Rd)); } }
public static void Sbc(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context, setCarry: false); Operand res = context.Subtract(n, m); Operand borrow = context.BitwiseExclusiveOr(GetFlag(PState.CFlag), Const(1)); res = context.Subtract(res, borrow); if (op.SetFlags) { EmitNZFlagsCheck(context, res); EmitSbcsCCheck(context, n, m); EmitSubsVCheck(context, n, m, res); } EmitAluStore(context, res); }
public static void Adc(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context, setCarry: false); Operand res = context.Add(n, m); Operand carry = GetFlag(PState.CFlag); res = context.Add(res, carry); if (ShouldSetFlags(context)) { EmitNZFlagsCheck(context, res); EmitAdcsCCheck(context, n, res); EmitAddsVCheck(context, n, m, res); } EmitAluStore(context, res); }
private static void EmitAluStore(ArmEmitterContext context, Operand value) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; EmitGenericAluStoreA32(context, op.Rd, op.SetFlags, value); }