/// <summary>
/// Visitation function for <see cref="IX86Visitor.Mov"/> instructions.
/// </summary>
/// <param name="context">The context.</param>
public void Mov(Context context)
{
if (context.Result.IsCPURegister && context.Operand1.IsCPURegister && context.Result.Register == context.Operand1.Register)
{
context.Empty();
return;
}
// Mov can not use ESI or EDI registers with 8 or 16 bit memory or register
if (context.Operand1.IsCPURegister && (context.Result.IsMemoryAddress || context.Result.IsCPURegister)
&& (context.Result.IsByte || context.Result.IsShort || context.Result.IsChar || context.Result.IsBoolean)
&& (context.Operand1.Register == GeneralPurposeRegister.ESI || context.Operand1.Register == GeneralPurposeRegister.EDI))
{
Operand source = context.Operand1;
Operand dest = context.Result;
var replace = (dest.IsMemoryAddress && dest.EffectiveOffsetBase == GeneralPurposeRegister.EAX)
? GeneralPurposeRegister.EBX : GeneralPurposeRegister.EAX;
Operand reg = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, replace);
context.SetInstruction2(X86.Xchg, reg, source, source, reg);
context.AppendInstruction(X86.Mov, dest, reg);
context.AppendInstruction2(X86.Xchg, source, reg, reg, source);
}
}