Base class of a method compiler.
A method compiler is responsible for compiling a single function of an object. There are various classes derived from BaseMethodCompiler, which provide specific features, such as jit compilation, runtime optimized jitting and others. MethodCompilerBase instances are usually created by invoking CreateMethodCompiler on a specific compiler instance.
Inheritance: IMethodCompiler, IDisposable
コード例 #1
0
 /// <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));
 }
コード例 #2
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);
        }
コード例 #3
0
        /// <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));
        }
コード例 #4
0
ファイル: Get16.cs プロジェクト: Zahovay/MOSA-Project
        /// <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);
        }
コード例 #5
0
ファイル: Remainder.cs プロジェクト: yonglehou/MOSA-Project
        /// <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);
            }
        }
コード例 #6
0
ファイル: FrameCall.cs プロジェクト: tgiphil/MOSA-Project
        /// <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);
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
ファイル: GetEip.cs プロジェクト: tea/MOSA-Project
        /// <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);
        }
コード例 #11
0
ファイル: SpinUnlock.cs プロジェクト: tea/MOSA-Project
        /// <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);
        }
コード例 #12
0
ファイル: Get.cs プロジェクト: tea/MOSA-Project
        /// <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);
        }
コード例 #13
0
 public static void Run(BaseMethodCompiler methodCompiler, IPipelineStage stage)
 {
     Run(
         methodCompiler.Trace,
         methodCompiler.FormatStageName(stage),
         methodCompiler.Method,
         methodCompiler.BasicBlocks
     );
 }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
ファイル: SetFS.cs プロジェクト: Zahovay/MOSA-Project
        /// <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);
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
 public static void Run(BaseMethodCompiler methodCompiler, IPipelineStage stage)
 {
     Run(
         methodCompiler.InternalTrace,
         stage,
         methodCompiler.Method,
         methodCompiler.InstructionSet,
         methodCompiler.BasicBlocks
     );
 }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
ファイル: FrameCall.cs プロジェクト: charsleysa/MOSA-Project
        /// <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);
        }
コード例 #20
0
ファイル: SwitchTask.cs プロジェクト: Zahovay/MOSA-Project
        /// <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);
        }
コード例 #21
0
ファイル: Get16.cs プロジェクト: yonglehou/MOSA-Project
        /// <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);
        }
コード例 #22
0
        /// <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);
        }
コード例 #23
0
ファイル: CpuIdEbx.cs プロジェクト: tgiphil/MOSA-Project
 /// <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);
 }
コード例 #24
0
ファイル: Memclr256.cs プロジェクト: Zahovay/MOSA-Project
        /// <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);
        }
コード例 #25
0
ファイル: Set.cs プロジェクト: yonglehou/MOSA-Project
        /// <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);
        }
コード例 #26
0
        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;
        }
コード例 #27
0
ファイル: Memclr256.cs プロジェクト: pacificIT/MOSA-Project
        /// <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);
        }
コード例 #28
0
ファイル: Div.cs プロジェクト: tgiphil/MOSA-Project
        /// <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);
        }
コード例 #29
0
ファイル: DelegatePatcher.cs プロジェクト: tea/MOSA-Project
        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;
        }
コード例 #30
0
ファイル: FrameJump.cs プロジェクト: tgiphil/MOSA-Project
        /// <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();
        }