/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var address = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.I4); context.SetInstruction(IRInstruction.Move, address, Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, Multiboot0695Stage.MultibootEBX)); context.AppendInstruction(IRInstruction.Move, result, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.I4, address, 0)); }
private static void PatchConstructor(BaseMethodCompiler methodCompiler) { Operand thisOperand = methodCompiler.Parameters[0]; Operand instanceOperand = methodCompiler.Parameters[1]; Operand methodPointerOperand = methodCompiler.Parameters[2]; var size = methodCompiler.Architecture.NativeInstructionSize; MosaField methodPointerField = GetField(methodCompiler.Method.DeclaringType, "methodPointer"); int methodPointerOffset = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField); Operand methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset); MosaField instanceField = GetField(methodCompiler.Method.DeclaringType, "instance"); int instanceOffset = methodCompiler.TypeLayout.GetFieldOffset(instanceField); Operand instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset); var context = new Context(CreateMethodStructure(methodCompiler, true)); Operand v1 = methodCompiler.CreateVirtualRegister(thisOperand.Type); Operand v2 = methodCompiler.CreateVirtualRegister(methodPointerOperand.Type); Operand v3 = methodCompiler.CreateVirtualRegister(instanceOperand.Type); context.AppendInstruction(IRInstruction.LoadInteger, v1, methodCompiler.StackFrame, thisOperand); context.AppendInstruction(IRInstruction.LoadInteger, v2, methodCompiler.StackFrame, methodPointerOperand); context.AppendInstruction(IRInstruction.LoadInteger, v3, methodCompiler.StackFrame, instanceOperand); context.AppendInstruction(IRInstruction.StoreInteger, size, null, v1, methodPointerOffsetOperand, v2); context.MosaType = methodPointerOperand.Type; context.AppendInstruction(IRInstruction.StoreInteger, size, null, v1, instanceOffsetOperand, v3); context.MosaType = instanceOperand.Type; context.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var operand = context.Operand1; if (!operand.IsConstant) { // try to find the constant - a bit of a hack Context ctx = new Context(operand.Definitions[0]); if (ctx.Instruction == IRInstruction.Move && ctx.Operand1.IsConstant) { operand = ctx.Operand1; } } Debug.Assert(operand.IsConstant); int irq = (int)operand.ConstantSignedLongInteger; // Find the method var method = methodCompiler.TypeSystem.DefaultLinkerType.FindMethodByName("InterruptISR" + irq.ToString()); if (method == null) { throw new InvalidCompilerException(); } context.SetInstruction(IRInstruction.Move, context.Result, Operand.CreateSymbolFromMethod(methodCompiler.TypeSystem, method)); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Debug.Assert(context.Result.IsI4 | context.Result.IsU4); Operand zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0); context.SetInstruction(X86.MovzxLoad, InstructionSize.Size16, context.Result, context.Operand1, zero); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var dividend = context.Operand1; var divisor = context.Operand2; if (result.IsR8) { var xmm1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var xmm2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var xmm3 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var size = InstructionSize.Size64; context.SetInstruction(X86.Divsd, size, xmm1, dividend, divisor); context.AppendInstruction(X86.Roundsd, size, xmm2, xmm1, Operand.CreateConstant(methodCompiler.TypeSystem.BuiltIn.U1, 0x3)); context.AppendInstruction(X86.Mulsd, size, xmm3, divisor, xmm2); context.AppendInstruction(X86.Subsd, size, result, dividend, xmm3); } else { var xmm1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var xmm2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var xmm3 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var size = InstructionSize.Size32; context.SetInstruction(X86.Divss, size, xmm1, dividend, divisor); context.AppendInstruction(X86.Roundss, size, xmm2, xmm1, Operand.CreateConstant(methodCompiler.TypeSystem.BuiltIn.U1, 0x3)); context.AppendInstruction(X86.Mulss, size, xmm3, divisor, xmm2); context.AppendInstruction(X86.Subss, size, result, dividend, xmm3); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand methodAddress = context.Operand1; Operand newESP = context.Operand2; context.SetInstruction(X86.Call, null, methodAddress); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var zero = Operand.CreateConstant(methodCompiler.TypeSystem.BuiltIn.I4, 0); var MultibootEAX = Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, Multiboot0695Stage.MultibootEAX); context.SetInstruction(IRInstruction.Load2, context.Result, MultibootEAX, zero); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand imm = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.SetInstruction(X86.MovCR, imm, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, control)); context.AppendInstruction(X86.Mov, result, imm); }
private static void PatchBeginInvoke(BaseMethodCompiler methodCompiler) { var nullOperand = Operand.GetNull(methodCompiler.TypeSystem); var context = new Context(CreateMethodStructure(methodCompiler, true)); context.AppendInstruction(IRInstruction.Return, null, nullOperand); context.AddBranchTarget(methodCompiler.BasicBlocks.EpilogueBlock); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand eax = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.AppendInstruction(X86.Add, eax, eax, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, GeneralPurposeRegister.ESP)); context.AppendInstruction(X86.Mov, eax, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.U4, eax, 0)); context.AppendInstruction(X86.Mov, result, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { // Create constant operand and pointer to variable containing the lock Operand const0 = Operand.CreateConstantSignedInt(methodCompiler.TypeSystem, 0x0); Operand locked = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Pointer, context.Operand1, 0); // Set the variable locked to 0 signifying that the lock is free context.SetInstruction(X86.Mov, locked, const0); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand edx = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Pointer); Operand operand = Operand.CreateMemoryAddress(context.Operand1.Type, edx, 0); context.SetInstruction(X86.Mov, edx, context.Operand1); context.AppendInstruction(X86.Mov, result, operand); }
public static void Run(BaseMethodCompiler methodCompiler, IPipelineStage stage) { Run( methodCompiler.Trace, methodCompiler.FormatStageName(stage), methodCompiler.Method, methodCompiler.BasicBlocks ); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var ctor = context.Operand1; var thisObject = context.Operand2; var result = context.Result; context.SetInstruction(IRInstruction.Call, null, ctor, thisObject); context.AppendInstruction(IRInstruction.MoveInteger, result, thisObject); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand operand1 = context.Operand1; Operand v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.SetInstruction(X86.Mov, v1, operand1); context.AppendInstruction(X86.Mov, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, SegmentRegister.FS), v1); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand operand1 = context.Operand1; Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); Operand cr = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, control); context.SetInstruction(X86.Mov, eax, operand1); context.AppendInstruction(X86.MovCR, cr, eax); }
public static void Run(BaseMethodCompiler methodCompiler, IPipelineStage stage) { Run( methodCompiler.InternalTrace, stage, methodCompiler.Method, methodCompiler.InstructionSet, methodCompiler.BasicBlocks ); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand size = context.Operand1; Operand esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); context.SetInstruction(X86.Sub, esp, esp, size); context.AppendInstruction(X86.Mov, result, esp); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand methodAddress = context.Operand1; Operand newESP = context.Operand2; Operand esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); Operand edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDX); context.SetInstruction(X86.Call, null, methodAddress); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); context.SetInstruction(X86.Mov, esp, context.Operand1); context.AppendInstruction(X86.Popad); context.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(methodCompiler.TypeSystem, 0x08)); context.AppendInstruction(X86.Sti); context.AppendInstruction(X86.IRetd); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Pointer); Operand operand = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.U2, v1, 0); Debug.Assert(result.IsI4 | result.IsU4); context.SetInstruction(X86.Mov, v1, context.Operand1); context.AppendInstruction(X86.Movzx, InstructionSize.Size16, result, operand); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand methodAddress = context.Operand1; Operand newESP = context.Operand2; Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); context.SetInstruction(X86.Call, null, methodAddress); context.AppendInstruction(IRInstruction.Gen, eax); context.AppendInstruction(X86.Mov, result, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand operand = context.Operand1; Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); Operand ecx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); Operand reg = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); context.SetInstruction(X86.Mov, eax, operand); context.AppendInstruction(X86.Mov, ecx, methodCompiler.ConstantZero); context.AppendInstruction(X86.CpuId, eax, eax); context.AppendInstruction(X86.Mov, result, reg); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var dest = context.Operand1; var v0 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Void, SSE2Register.XMM0); var zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0); var offset16 = Operand.CreateConstant(methodCompiler.TypeSystem, 16); context.SetInstruction(X86.PXor, InstructionSize.Size128, v0, v0, v0); context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, dest, zero, v0); context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, dest, offset16, v0); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand dest = context.Operand1; Operand value = context.Operand2; Operand v1 = methodCompiler.CreateVirtualRegister(dest.Type); Operand v2 = methodCompiler.CreateVirtualRegister(value.Type); Operand memory = Operand.CreateMemoryAddress(context.InvokeMethod.Signature.Parameters[1].ParameterType, v1, 0); context.SetInstruction(X86.Mov, v1, dest); context.AppendInstruction(X86.Mov, v2, value); context.AppendInstruction(X86.Mov, memory, v2); }
private static Context CreateNewBlock(BaseMethodCompiler methodCompiler) { var basicBlocks = methodCompiler.BasicBlocks; Context context = new Context(methodCompiler.InstructionSet); context.AppendInstruction(null); context.Label = 0; var newblock = basicBlocks.CreateBlock(basicBlocks.Count, context.Index); context.BasicBlock = newblock; return context; }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var dest = context.Operand1; // The size will be 128 bits var v0 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Void, SSE2Register.XMM0); var memDest1 = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Void, dest, 0); var memDest2 = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Void, dest, 16); context.SetInstruction(X86.PXor, InstructionSize.Size128, v0, v0, v0); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest1, v0); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest2, v0); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand n = context.Operand1; Operand d = context.Operand2; Operand result = context.Result; Operand result2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); Operand op0L, op0H; LongOperandTransformationStage.SplitLongOperand(methodCompiler, n, out op0L, out op0H); context.SetInstruction2(X86.Div, result2, result, op0H, op0L, d); }
private static Context CreateMethodStructure(BaseMethodCompiler methodCompiler, bool linkEpilogueBlock) { var basicBlocks = methodCompiler.BasicBlocks; CreatePrologueAndEpilogueBlocks(methodCompiler.InstructionSet, basicBlocks); var context = methodCompiler.InstructionSet.CreateNewBlock(basicBlocks, 0); basicBlocks.LinkBlocks(basicBlocks.PrologueBlock, context.BasicBlock); if (linkEpilogueBlock) basicBlocks.LinkBlocks(context.BasicBlock, basicBlocks.EpilogueBlock); return context; }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand v0 = context.Operand1; Operand v1 = context.Operand2; Operand v2 = context.Operand3; Operand v3 = context.GetOperand(3); Operand esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); Operand ebp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); Operand ebx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); Operand ecx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); Operand exceptionRegister = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Object, methodCompiler.Architecture.ExceptionRegister); // Move all virtual registers into physical registers - necessary since stack frame pointer will change context.SetInstruction(X86.Mov, eax, v0); context.AppendInstruction(X86.Mov, ebx, v1); context.AppendInstruction(X86.Mov, ecx, v2); context.AppendInstruction(X86.Mov, exceptionRegister, v3); // Update the frame and stack registers context.AppendInstruction(X86.Mov, ebp, ecx); context.AppendInstruction(X86.Mov, esp, ebx); context.AppendInstruction(X86.Jmp, null, eax); // future - common code (refactor opportunity) context.GotoNext(); // Remove all remaining instructions in block and clear next block list while (!context.IsBlockEndInstruction) { if (!context.IsEmpty) { context.SetInstruction(X86.Nop); } context.GotoNext(); } var nextBlocks = context.Block.NextBlocks; foreach (var next in nextBlocks) { next.PreviousBlocks.Remove(context.Block); } nextBlocks.Clear(); }