protected override void EmitInstruction(Context context, BaseCodeEmitter codeEmitter) { long start = codeEmitter.CurrentPosition; base.EmitInstruction(context, codeEmitter); long end = codeEmitter.CurrentPosition; byte opcodeSize = (byte)(end - start); var instruction = simAdapter.Convert(context, MethodCompiler.Method, BasicBlocks, opcodeSize); instruction.Source = context.ToString(); // context.Instruction.ToString(context); simAdapter.SimCPU.AddInstruction((ulong)(sectionAddress + startPosition + start), instruction); return; }
/// <summary> /// Dumps this instance. /// </summary> protected void Dump(bool before) { Debug.WriteLine(string.Empty); Debug.WriteLine("METHOD: " + MethodCompiler.Method.FullName); Debug.WriteLine("STAGE : " + (before ? "[BEFORE] " : "[AFTER] ") + GetType().Name); Debug.WriteLine(string.Empty); for (int index = 0; index < BasicBlocks.Count; index++) { for (Context ctx = new Context(BasicBlocks[index]); !ctx.IsBlockEndInstruction; ctx.GotoNext()) { if (!ctx.IsEmpty) { Debug.WriteLine(ctx.ToString()); } } } }
/// <summary> /// Dumps this instance. /// </summary> protected void Dump(bool before) { Debug.WriteLine(string.Empty); Debug.WriteLine("METHOD: " + MethodCompiler.Method.FullName); Debug.WriteLine("STAGE : " + (before ? "[BEFORE] " : "[AFTER] ") + GetType().Name); Debug.WriteLine(string.Empty); for (int index = 0; index < BasicBlocks.Count; index++) for (Context ctx = new Context(BasicBlocks[index]); !ctx.IsBlockEndInstruction; ctx.GotoNext()) if (!ctx.IsEmpty) Debug.WriteLine(ctx.ToString()); }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { const int LargeAlignment = 16; int alignedSize = size - (size % NativeAlignment); int largeAlignedTypeSize = size - (size % LargeAlignment); Debug.Assert(size > 0); var src = source; var dest = destination; Debug.Assert(src.IsMemoryAddress && dest.IsMemoryAddress, context.ToString()); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmpLarge = Operand.CreateCPURegister(destination.Type.TypeSystem.BuiltIn.Void, SSE2Register.XMM1); context.AppendInstruction(X86.Lea, srcReg, src); context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < largeAlignedTypeSize; i += LargeAlignment) { // Large aligned moves allow 128bits to be copied at a time var memSrc = Operand.CreateMemoryAddress(destination.Type.TypeSystem.BuiltIn.Void, srcReg, i); var memDest = Operand.CreateMemoryAddress(destination.Type.TypeSystem.BuiltIn.Void, dstReg, i); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, tmpLarge, memSrc); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest, tmpLarge); } for (int i = largeAlignedTypeSize; i < alignedSize; i += NativeAlignment) { context.AppendInstruction(X86.Mov, InstructionSize.Size32, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size32, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } for (int i = alignedSize; i < size; i++) { context.AppendInstruction(X86.Mov, InstructionSize.Size8, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size8, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { int alignedSize = size - (size % NativeAlignment); Debug.Assert(size > 0); var src = source; var dest = destination; Debug.Assert(src.IsMemoryAddress && dest.IsMemoryAddress, context.ToString()); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); context.AppendInstruction(X86.Lea, srcReg, src); context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < alignedSize; i += NativeAlignment) { context.AppendInstruction(X86.Mov, InstructionSize.Size32, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size32, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } for (int i = alignedSize; i < size; i++) { context.AppendInstruction(X86.Mov, InstructionSize.Size8, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size8, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
/// <summary> /// Called to emit a list of instructions offered by the instruction provider. /// </summary> protected virtual void EmitInstructions() { foreach (BasicBlock block in basicBlocks) { BlockStart(block); for (Context context = new Context(instructionSet, block); !context.EndOfInstruction; context.GotoNext()) if (context.Instruction != null) if (!context.Ignore) { IPlatformInstruction instruction = context.Instruction as IPlatformInstruction; if (instruction != null) instruction.Emit(context, codeEmitter); else Trace(InternalTrace.CompilerEvent.Error, "Missing Code Transformation: " + context.ToString()); } BlockEnd(block); } }
void IIRVisitor.CompoundMove(Context context) { var type = context.Result.Type; int typeSize = TypeLayout.GetTypeSize(type); int alignedTypeSize = typeSize - (typeSize % NativeAlignment); Debug.Assert(typeSize > 0, MethodCompiler.Method.FullName); var src = context.Operand1; var dest = context.Result; Debug.Assert((src.IsMemoryAddress || src.IsSymbol) && dest.IsMemoryAddress, context.ToString()); var srcReg = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); var dstReg = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); var tmp = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); context.SetInstruction(X86.Nop); if (src.IsSymbol) { context.AppendInstruction(X86.Mov, srcReg, src); } else { context.AppendInstruction(X86.Lea, srcReg, src); } context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < alignedTypeSize; i += NativeAlignment) { context.AppendInstruction(X86.Mov, InstructionSize.Size32, tmp, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size32, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, dstReg, i), tmp); } for (int i = alignedTypeSize; i < typeSize; i++) { context.AppendInstruction(X86.Mov, InstructionSize.Size8, tmp, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size8, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
private void CompoundMove(Context context) { var type = context.Result.Type; int typeSize = TypeLayout.GetTypeSize(type); int alignedTypeSize = typeSize - (typeSize % NativeAlignment); int largeAlignedTypeSize = typeSize - (typeSize % LargeAlignment); Debug.Assert(typeSize > 0, MethodCompiler.Method.FullName); var src = context.Operand1; var dest = context.Result; Debug.Assert((src.IsMemoryAddress || src.IsSymbol) && dest.IsMemoryAddress, context.ToString()); var srcReg = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); var dstReg = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); var tmp = MethodCompiler.CreateVirtualRegister(dest.Type.TypeSystem.BuiltIn.I4); var tmpLarge = Operand.CreateCPURegister(MethodCompiler.TypeSystem.BuiltIn.Void, SSE2Register.XMM1); context.SetInstruction(X86.Nop); if (src.IsSymbol) { context.AppendInstruction(X86.Mov, srcReg, src); } else { context.AppendInstruction(X86.Lea, srcReg, src); } context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < largeAlignedTypeSize; i += LargeAlignment) { // Large Aligned moves allow 128bits to be copied at a time var index = Operand.CreateConstant(TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovupsLoad, tmpLarge, srcReg, index); context.AppendInstruction(X86.MovupsStore, null, dstReg, index, tmpLarge); } for (int i = largeAlignedTypeSize; i < alignedTypeSize; i += NativeAlignment) { var index = Operand.CreateConstant(TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovLoad, InstructionSize.Size32, tmp, srcReg, index); context.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, dstReg, index, tmp); } for (int i = alignedTypeSize; i < typeSize; i++) { var index = Operand.CreateConstant(TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovzxLoad, InstructionSize.Size8, tmp, srcReg, index); context.AppendInstruction(X86.MovStore, InstructionSize.Size8, null, dstReg, index, tmp); } }