/// <summary>
        /// Link time code generator used to compile dynamically created methods during link time.
        /// </summary>
        /// <param name="compiler">The assembly compiler used to compile this method.</param>
        /// <param name="methodName">The name of the created method.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception>
        public static LinkerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet, ITypeSystem typeSystem)
        {
            if (compiler == null)
                throw new ArgumentNullException(@"compiler");
            if (methodName == null)
                throw new ArgumentNullException(@"methodName");
            if (methodName.Length == 0)
                throw new ArgumentException(@"Invalid method name.");

            LinkerGeneratedType compilerGeneratedType = typeSystem.InternalTypeModule.GetType(@"Mosa.Tools.Compiler", @"LinkerGenerated") as LinkerGeneratedType;

            // Create the type if we need to.
            if (compilerGeneratedType == null)
            {
                compilerGeneratedType = new LinkerGeneratedType(typeSystem.InternalTypeModule, @"Mosa.Tools.Compiler", @"LinkerGenerated", null);
                typeSystem.AddInternalType(compilerGeneratedType);
            }

            MethodSignature signature = new MethodSignature(BuiltInSigType.Void, new SigType[0]);

            // Create the method
            // HACK: <$> prevents the method from being called from CIL
            LinkerGeneratedMethod method = new LinkerGeneratedMethod(typeSystem.InternalTypeModule, "<$>" + methodName, compilerGeneratedType, signature);
            compilerGeneratedType.AddMethod(method);

            LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(), method, instructionSet);
            methodCompiler.Compile();
            return method;
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AotMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public AotMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
            : base(compiler, method, basicBlocks, instructionSet)
        {
            var compilerOptions = compiler.CompilerOptions;

            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new BasicBlockBuilderStage(),
                new StackSetupStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new ConvertCompoundMoveStage(),
                (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,
                (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null,
                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null,
                new PlatformStubStage(),
                new	PlatformEdgeSplitStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new CodeGenerationStage(),
            });
        }
Esempio n. 3
0
        /// <summary>
        /// Creates the ISR methods.
        /// </summary>
        private void CreateExceptionVector()
        {
            var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT");

            if (type == null)
                return;

            var method = type.FindMethodByName("ExceptionHandlerType");

            if (method == null)
                return;

            Operand exceptionMethod = Operand.CreateSymbolFromMethod(TypeSystem, method);

            Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            BasicBlocks basicBlocks = new BasicBlocks();
            InstructionSet instructionSet = new InstructionSet(25);
            Context ctx = instructionSet.CreateNewBlock(basicBlocks);
            basicBlocks.AddHeaderBlock(ctx.BasicBlock);

            // TODO - setup stack for call to the managed exception handler

            //1.
            //2.

            //3. Call the managed exception handler
            ctx.AppendInstruction(X86.Call, null, exceptionMethod);

            var vectorMethod = Compiler.CreateLinkerMethod("ExceptionVector");

            Compiler.CompileMethod(vectorMethod, basicBlocks, instructionSet);
        }
        /// <summary>
        /// Creates the interrupt service routine (ISR) methods.
        /// </summary>
        private void CreateInterruptVectors()
        {
            RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Kernel.x86.IDT");

            if (runtimeType == null)
                return;

            RuntimeMethod runtimeMethod = runtimeType.FindMethod(@"ProcessInterrupt");

            if (runtimeMethod == null)
                return;

            Operand interruptMethod = Operand.CreateSymbolFromMethod(runtimeMethod);

            Operand esp = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.ESP);

            for (int i = 0; i <= 255; i++)
            {
                InstructionSet instructionSet = new InstructionSet(100);
                Context ctx = new Context(instructionSet);

                ctx.AppendInstruction(X86.Cli);
                if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code
                    ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(BuiltInSigType.SByte, 0x0));
                ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(BuiltInSigType.SByte, (byte)i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Call, null, interruptMethod);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.Add, esp, Operand.CreateConstant(BuiltInSigType.Int32, 0x08));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), instructionSet, typeSystem);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Creates the ISR methods.
        /// </summary>
        private void CreateExceptionVector()
        {
            RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Kernel.x86.IDT");

            if (runtimeType == null)
                return;

            RuntimeMethod runtimeMethod = runtimeType.FindMethod(@"ExceptionHandler");

            if (runtimeMethod == null)
                return;

            SymbolOperand exceptionMethod = SymbolOperand.FromMethod(runtimeMethod);

            RegisterOperand esp = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.ESP);

            InstructionSet instructionSet = new InstructionSet(100);
            Context ctx = new Context(instructionSet);

            // TODO - setup stack for call to the managed exception handler

            //1.
            //2.

            //3. Call the managed exception handler
            ctx.AppendInstruction(Instruction.CallInstruction, null, exceptionMethod);

            LinkTimeCodeGenerator.Compile(this.compiler, @"ExceptionVector", instructionSet, typeSystem);
        }
Esempio n. 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        /// <param name="method">The method to compile by this instance.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="instructionSet">The instruction set.</param>
        protected BaseMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
        {
            this.Compiler = compiler;
            this.Method = method;
            this.Type = method.DeclaringType;
            this.Scheduler = compiler.CompilationScheduler;
            this.Architecture = compiler.Architecture;
            this.TypeSystem = compiler.TypeSystem;
            this.TypeLayout = Compiler.TypeLayout;
            this.InternalTrace = Compiler.InternalTrace;
            this.Linker = compiler.Linker;
            this.BasicBlocks = basicBlocks ?? new BasicBlocks();
            this.InstructionSet = instructionSet ?? new InstructionSet(256);
            this.Pipeline = new CompilerPipeline();
            this.StackLayout = new StackLayout(Architecture, method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0));
            this.VirtualRegisters = new VirtualRegisters(Architecture);
            this.LocalVariables = emptyOperandList;
            this.DominanceAnalysis = new DominanceAnalysis(Compiler.CompilerOptions.DominanceAnalysisFactory, this.BasicBlocks);

            EvaluateParameterOperands();

            this.stop = false;

            Debug.Assert(this.Linker != null);
        }
Esempio n. 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SimMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="simAdapter">The sim adapter.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public SimMethodCompiler(SimCompiler compiler, MosaMethod method, ISimAdapter simAdapter, BasicBlocks basicBlocks, InstructionSet instructionSet)
            : base(compiler, method, basicBlocks, instructionSet)
        {
            var compilerOptions = Compiler.CompilerOptions;

            // Populate the pipeline
            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new BasicBlockBuilderStage(),
                new StackSetupStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                //new SingleUseMarkerStage(),
                //new OperandUsageAnalyzerStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new ConvertCompoundMoveStage(),
                //new CheckIROperandCountStage(),
                (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,
                (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null,
                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null,
                new PlatformStubStage(),
                //new CheckPlatformOperandCountStage(),
                new	PlatformEdgeSplitStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new SimCodeGeneratorStage(simAdapter),
            });
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
        /// </summary>
        public TypeInitializerSchedulerStage()
        {
            instructionSet = new InstructionSet(1024);
            ctx = new Context(instructionSet);

            ctx.AppendInstruction(IR.IRInstruction.Prologue);
            //ctx.Other = 0; // stacksize
        }
Esempio n. 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class.
        /// </summary>
        /// <param name="assemblyCompiler">The assembly compiler executing this method compiler.</param>
        /// <param name="method">The metadata of the method to compile.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <exception cref="System.ArgumentNullException"><paramref name="assemblyCompiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception>
        public LinkerMethodCompiler(AssemblyCompiler assemblyCompiler, ICompilationSchedulerStage compilationScheduler, RuntimeMethod method, InstructionSet instructionSet)
            : base(assemblyCompiler, method.DeclaringType, method,  instructionSet, compilationScheduler)
        {
            this.CreateBlock(-1, 0);

            this.Pipeline.AddRange(new IMethodCompilerStage[] {
                new SimpleTraceBlockOrderStage(),
                new PlatformStubStage(),
                new CodeGenerationStage(),
            });

            assemblyCompiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class.
        /// </summary>
        /// <param name="compiler">The assembly compiler executing this method compiler.</param>
        /// <param name="method">The metadata of the method to compile.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public LinkerMethodCompiler(BaseCompiler compiler, RuntimeMethod method, InstructionSet instructionSet)
            : base(compiler, method, instructionSet)
        {
            BasicBlocks.CreateBlock(BasicBlock.PrologueLabel, 0);
            BasicBlocks.AddHeaderBlock(BasicBlocks.PrologueBlock);

            this.Pipeline.AddRange(new IMethodCompilerStage[] {
                new LoopAwareBlockOrderStage(),
                new PlatformStubStage(),
                new CodeGenerationStage(),
            });

            compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline);
        }
Esempio n. 11
0
        private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks)
        {
            // Create the prologue block
            var context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.PrologueLabel);

            // Add a jump instruction to the first block from the prologue
            context.AppendInstruction(IRInstruction.Jmp);
            context.SetBranch(0);
            var prologue = context.BasicBlock;
            basicBlocks.AddHeaderBlock(prologue);

            // Create the epilogue block
            context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.EpilogueLabel);
            var epilogue = context.BasicBlock;
        }
Esempio n. 12
0
        public static void Run(IInternalTrace internalLog, IPipelineStage stage, RuntimeMethod method, InstructionSet instructionSet, BasicBlocks basicBlocks)
        {
            if (internalLog == null)
                return;

            if (internalLog.TraceListener == null)
                return;

            if (!internalLog.TraceFilter.IsMatch(method, stage.Name))
                return;

            StringBuilder text = new StringBuilder();

            // Line number
            int index = 1;

            text.AppendLine(String.Format("IR representation of method {0} after stage {1}:", method, stage.Name));
            text.AppendLine();

            if (basicBlocks.Count > 0)
            {
                foreach (BasicBlock block in basicBlocks)
                {
                    text.AppendFormat("Block #{0} - Label L_{1:X4}", index, block.Label);
                    if (basicBlocks.IsHeaderBlock(block))
                        text.Append(" [Header]");
                    text.AppendLine();

                    text.AppendFormat("  Prev: ");
                    text.AppendLine(ListBlocks(block.PreviousBlocks));

                    LogInstructions(text, new Context(instructionSet, block));

                    text.AppendFormat("  Next: ");
                    text.AppendLine(ListBlocks(block.NextBlocks));

                    text.AppendLine();
                    index++;
                }
            }
            else
            {
                LogInstructions(text, new Context(instructionSet, 0));
            }

            internalLog.TraceListener.SubmitInstructionTraceInformation(method, stage.Name, text.ToString());
        }
Esempio n. 13
0
        private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks)
        {
            // Create the prologue block
            Context context = new Context(instructionSet);
            // Add a jump instruction to the first block from the prologue
            context.AppendInstruction(IRInstruction.Jmp);
            context.SetBranch(0);
            context.Label = BasicBlock.PrologueLabel;
            var prologue = basicBlocks.CreateBlock(BasicBlock.PrologueLabel, context.Index);
            basicBlocks.AddHeaderBlock(prologue);

            // Create the epilogue block
            context = new Context(instructionSet);
            // Add null instruction, necessary to generate a block index
            context.AppendInstruction(null);
            context.Label = BasicBlock.EpilogueLabel;
            var epilogue = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel, context.Index);
        }
Esempio n. 14
0
        protected override void Run()
        {
            var typeInitializer = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod;

            var basicBlocks = new BasicBlocks();
            var instructionSet = new InstructionSet(25);

            var context = instructionSet.CreateNewBlock(basicBlocks);
            basicBlocks.AddHeaderBlock(context.BasicBlock);

            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializer);

            context.AppendInstruction(IRInstruction.Call, null, entryPoint);
            context.MosaMethod = typeInitializer;

            var method = Compiler.CreateLinkerMethod(StartUpName);
            Compiler.CompileMethod(method, basicBlocks, instructionSet);

            Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text);
        }
Esempio n. 15
0
        /// <summary>
        /// Creates the interrupt service routine (ISR) methods.
        /// </summary>
        private void CreateInterruptVectors()
        {
            var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT");

            if (type == null)
                return;

            var method = type.FindMethodByName("ProcessInterrupt");

            if (method == null)
                return;

            Operand interrupt = Operand.CreateSymbolFromMethod(TypeSystem, method);

            Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            for (int i = 0; i <= 255; i++)
            {
                BasicBlocks basicBlocks = new BasicBlocks();
                InstructionSet instructionSet = new InstructionSet(25);
                Context ctx = instructionSet.CreateNewBlock(basicBlocks);
                basicBlocks.AddHeaderBlock(ctx.BasicBlock);

                ctx.AppendInstruction(X86.Cli);
                if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code
                    ctx.AppendInstruction(X86.Push, null, Operand.CreateConstantUnsignedInt(TypeSystem, 0));
                ctx.AppendInstruction(X86.Push, null, Operand.CreateConstantUnsignedInt(TypeSystem, (uint)i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Call, null, interrupt);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstantUnsignedInt(TypeSystem, 8));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString());
                Compiler.CompileMethod(interruptMethod, basicBlocks, instructionSet);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Splits the block.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <returns></returns>
        private Context Split(Context ctx, BasicBlocks basicBlocks, InstructionSet instructionSet)
        {
            Context current = ctx.Clone();

            Context next = ctx.Clone();
            next.AppendInstruction(IRInstruction.BlockStart);
            BasicBlock nextBlock = basicBlocks.CreateBlockWithAutoLabel(next.Index, current.BasicBlock.EndIndex);
            Context nextContext = new Context(instructionSet, nextBlock);

            foreach (BasicBlock block in current.BasicBlock.NextBlocks)
            {
                nextBlock.NextBlocks.Add(block);
                block.PreviousBlocks.Remove(current.BasicBlock);
                block.PreviousBlocks.Add(nextBlock);
            }

            current.BasicBlock.NextBlocks.Clear();

            current.AppendInstruction(IRInstruction.BlockEnd);
            current.BasicBlock.EndIndex = current.Index;

            return nextContext;
        }
Esempio n. 17
0
 /// <summary>
 /// Creates a method compiler
 /// </summary>
 /// <param name="method">The method to compile.</param>
 /// <param name="basicBlocks">The basic blocks.</param>
 /// <param name="instructionSet">The instruction set.</param>
 /// <returns></returns>
 public abstract BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet);
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class.
        /// </summary>
        /// <param name="assemblyCompiler">The assembly compiler.</param>
        /// <param name="type">The type, which owns the method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <param name="compilationScheduler">The compilation scheduler.</param>
        protected BaseMethodCompiler(AssemblyCompiler assemblyCompiler, RuntimeType type, RuntimeMethod method, InstructionSet instructionSet, ICompilationSchedulerStage compilationScheduler)
        {
            if (compilationScheduler == null)
                throw new ArgumentNullException(@"compilationScheduler");

            this.assemblyCompiler = assemblyCompiler;
            this.method = method;
            this.type = type;
            this.compilationScheduler = compilationScheduler;
            this.moduleTypeSystem = method.Module;

            this.architecture = assemblyCompiler.Architecture;
            this.typeSystem = assemblyCompiler.TypeSystem;
            this.typeLayout = AssemblyCompiler.TypeLayout;
            this.internalTrace = AssemblyCompiler.InternalTrace;

            this.linker = assemblyCompiler.Pipeline.FindFirst<IAssemblyLinker>();
            this.plugSystem = assemblyCompiler.Pipeline.FindFirst<IPlugSystem>();

            this.parameters = new List<Operand>(new Operand[method.Parameters.Count]);
            this.basicBlocks = new BasicBlocks();

            this.instructionSet = instructionSet ?? new InstructionSet(256);

            this.pipeline = new CompilerPipeline();

            this.stackLayout = new StackLayout(architecture, method.Parameters.Count + (method.Signature.HasThis || method.Signature.HasExplicitThis ? 1 : 0));

            this.virtualRegisterLayout = new VirtualRegisterLayout(architecture, stackLayout);

            EvaluateParameterOperands();
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (pipeline == null)
                throw new ObjectDisposedException(@"MethodCompilerBase");

            foreach (IMethodCompilerStage mcs in pipeline)
            {
                IDisposable d = mcs as IDisposable;
                if (d != null)
                    d.Dispose();
            }

            pipeline = null;
            architecture = null;
            linker = null;
            method = null;
            type = null;
            instructionSet = null;
            basicBlocks = null;
            stackLayout = null;
            locals = null;
        }
Esempio n. 20
0
        /// <summary>
        /// Replaces this operand in all uses and defs with the given operand.
        /// </summary>
        /// <param name="replacement">The replacement operand.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public void Replace(Operand replacement, InstructionSet instructionSet)
        {
            // Iterate all definition sites first
            foreach (int index in Definitions.ToArray())
            {
                Context ctx = new Context(instructionSet, index);

                if (ctx.Result != null)
                {
                    // Is this the operand?
                    if (ReferenceEquals(ctx.Result, this))
                    {
                        ctx.Result = replacement;
                    }

                }
            }

            // Iterate all use sites
            foreach (int index in Uses.ToArray())
            {
                Context ctx = new Context(instructionSet, index);

                int opIdx = 0;
                foreach (Operand r in ctx.Operands)
                {
                    // Is this the operand?
                    if (ReferenceEquals(r, this))
                    {
                        ctx.SetOperand(opIdx, replacement);
                    }

                    opIdx++;
                }
            }
        }
Esempio n. 21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Context"/> class.
 /// </summary>
 /// <param name="instructionSet">The instruction set.</param>
 public Context(InstructionSet instructionSet)
     : this(instructionSet, null, -1)
 {
 }
Esempio n. 22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Context"/> class.
 /// </summary>
 /// <param name="instructionSet">The instruction set.</param>
 /// <param name="basicBlock">The basic block.</param>
 public Context(InstructionSet instructionSet, BasicBlock basicBlock)
     : this(instructionSet, basicBlock, basicBlock.Index)
 {
 }
Esempio n. 23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Context"/> class.
 /// </summary>
 /// <param name="instructionSet">The instruction set.</param>
 /// <param name="index">The index.</param>
 public Context(InstructionSet instructionSet, int index)
     : this(instructionSet, null, index)
 {
 }
Esempio n. 24
0
        protected override void Run()
        {
            if (multibootMethod == null)
            {
                multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

                multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

                Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);

                WriteMultibootHeader();

                return;
            }

            var typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>();

            var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX);
            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
            var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);
            var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);

            var basicBlocks = new BasicBlocks();
            var instructionSet = new InstructionSet(25);

            var ctx = instructionSet.CreateNewBlock(basicBlocks);
            basicBlocks.AddHeaderBlock(ctx.BasicBlock);

            // set sentinal on the stack to indicate the start of the stack
            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero);

            // store multiboot registers eax and ebx at 0x200000 and 0x200004 respectively
            ctx.AppendInstruction(X86.Mov, ecx, Operand.CreateConstantSignedInt(TypeSystem, 0x200000));
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 4), ebx);

            // call type initializer
            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);
            ctx.AppendInstruction(X86.Call, null, entryPoint);

            // should never get here
            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet);
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        void IAssemblyCompilerStage.Run()
        {
            if (!secondStage)
            {
                IntPtr entryPoint = WriteMultibootEntryPoint();
                WriteMultibootHeader(entryPoint);
                secondStage = true;
            }
            else
            {
                ITypeInitializerSchedulerStage typeInitializerSchedulerStage = this.compiler.Pipeline.FindFirst<ITypeInitializerSchedulerStage>();

                SigType I4 = BuiltInSigType.Int32;
                RegisterOperand ecx = new RegisterOperand(I4, GeneralPurposeRegister.ECX);
                RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);
                RegisterOperand ebx = new RegisterOperand(I4, GeneralPurposeRegister.EBX);

                InstructionSet instructionSet = new InstructionSet(16);
                Context ctx = new Context(instructionSet);

                ctx.AppendInstruction(X86.Mov, ecx, new ConstantOperand(I4, 0x200000));
                ctx.AppendInstruction(X86.Mov, new MemoryOperand(ecx.Register, I4, new IntPtr(0x0)), eax);
                ctx.AppendInstruction(X86.Mov, new MemoryOperand(ecx.Register, I4, new IntPtr(0x4)), ebx);

                SymbolOperand entryPoint = SymbolOperand.FromMethod(typeInitializerSchedulerStage.TypeInitializerMethod);

                ctx.AppendInstruction(X86.Call, null, entryPoint);
                ctx.AppendInstruction(X86.Ret);

                LinkerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"MultibootInit", instructionSet, typeSystem);
                linker.EntryPoint = linker.GetSymbol(method.ToString());
            }
        }
Esempio n. 26
0
 /// <summary>
 /// Creates a method compiler
 /// </summary>
 /// <param name="method">The method to compile.</param>
 /// <param name="basicBlocks">The basic blocks.</param>
 /// <param name="instructionSet">The instruction set.</param>
 /// <returns>
 /// An instance of a MethodCompilerBase for the given type/method pair.
 /// </returns>
 public override BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
 {
     return new ExplorerMethodCompiler(this, method, basicBlocks, instructionSet, emitBinary);
 }
        /// <summary>
        /// Setups the specified compiler.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        public void Setup(IMethodCompiler compiler)
        {
            if (compiler == null)
                throw new ArgumentNullException(@"compiler");

            methodCompiler = compiler;
            instructionSet = compiler.InstructionSet;
            basicBlocks = compiler.BasicBlocks;
            architecture = compiler.Architecture;
            typeModule = compiler.Method.Module;
            typeSystem = compiler.TypeSystem;
            typeLayout = compiler.TypeLayout;
            callingConvention = architecture.GetCallingConvention();

            architecture.GetTypeRequirements(BuiltInSigType.IntPtr, out nativePointerSize, out nativePointerAlignment);
        }
Esempio n. 28
0
 /// <summary>
 /// Creates the method compiler.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <param name="basicBlocks">The basic blocks.</param>
 /// <param name="instructionSet">The instruction set.</param>
 /// <returns>
 /// An instance of a MethodCompilerBase for the given type/method pair.
 /// </returns>
 public override BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
 {
     return new AotMethodCompiler(this, method, basicBlocks, instructionSet);
 }
Esempio n. 29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Context"/> class.
 /// </summary>
 /// <param name="instructionSet">The instruction set.</param>
 /// <param name="block">The basic block.</param>
 /// <param name="index">The index.</param>
 public Context(InstructionSet instructionSet, BasicBlock block, int index)
 {
     this.instructionSet = instructionSet;
     this.index = index;
     this.block = block;
 }
Esempio n. 30
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        /// <param name="method">The method to compile by this instance.</param>
        /// <param name="instructionSet">The instruction set.</param>
        protected BaseMethodCompiler(BaseCompiler compiler, RuntimeMethod method, InstructionSet instructionSet)
        {
            this.compiler = compiler;
            this.method = method;
            this.type = method.DeclaringType;
            this.compilationScheduler = compiler.Scheduler;
            this.moduleTypeSystem = method.Module;
            this.architecture = compiler.Architecture;
            this.typeSystem = compiler.TypeSystem;
            this.typeLayout = Compiler.TypeLayout;
            this.internalTrace = Compiler.InternalTrace;
            this.linker = compiler.Linker;

            this.basicBlocks = new BasicBlocks();

            this.instructionSet = instructionSet ?? new InstructionSet(256);

            this.pipeline = new CompilerPipeline();

            this.stackLayout = new StackLayout(architecture, method.Parameters.Count + (method.Signature.HasThis || method.Signature.HasExplicitThis ? 1 : 0));

            this.virtualRegisterLayout = new VirtualRegisterLayout(architecture, stackLayout);

            EvaluateParameterOperands();

            this.stopMethodCompiler = false;
        }