/// <summary>
 /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
 /// </summary>
 public TypeInitializerSchedulerStage()
 {
     basicBlocks = new BasicBlocks();
     var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
     basicBlocks.AddHeaderBlock(block);
     context = new Context(block);
 }
Esempio n. 2
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);
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
        /// </summary>
        public TypeInitializerSchedulerStage()
        {
            basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);

            basicBlocks.AddHeaderBlock(block);
            context = new Context(block);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
        /// </summary>
        public TypeInitializerSchedulerStage()
        {
            basicBlocks = new BasicBlocks();
            instructionSet = new InstructionSet(25);
            context = instructionSet.CreateNewBlock(basicBlocks);
            basicBlocks.AddHeaderBlock(context.BasicBlock);

            context.AppendInstruction(IRInstruction.Prologue);
        }
        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();

                Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
                Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

                return;
            }

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.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 multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX);
            var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX);

            var basicBlocks = new BasicBlocks();
            var block       = basicBlocks.CreateBlock();

            basicBlocks.AddHeaderBlock(block);
            var ctx = new Context(block);

            // set sentinel 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);

            ctx.AppendInstruction(X86.Mov, ecx, multibootEax);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax);
            ctx.AppendInstruction(X86.Mov, ecx, multibootEbx);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), 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, 0);
        }
Esempio n. 6
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;
        }
        /// <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++)
            {
                var basicBlocks = new BasicBlocks();
                var block       = basicBlocks.CreateBlock();
                basicBlocks.AddHeaderBlock(block);
                var ctx = new Context(block);

                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(TypeSystem, 0));
                }
                ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Push, null, esp);
                ctx.AppendInstruction(X86.Call, null, interrupt);
                ctx.AppendInstruction(X86.Pop, esp);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, 8));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString());
                Compiler.CompileMethod(interruptMethod, basicBlocks, 0);
            }
        }
Esempio n. 8
0
        protected override void Run()
        {
            Debug.Assert(setupMethod == null, "SSE setup method already generated!");

            setupMethod = Compiler.CreateLinkerMethod("SSEInit");

            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX);
            var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0);
            var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4);

            var basicBlocks = new BasicBlocks();
            var block       = basicBlocks.CreateBlock();

            basicBlocks.AddHeaderBlock(block);
            var ctx = new Context(block);

            /*
             * ;enable SSE and the like
             *      mov eax, cr0
             *      and ax, 0xFFFB		;clear coprocessor emulation CR0.EM
             *      or ax, 0x2			;set coprocessor monitoring  CR0.MP
             *      mov cr0, eax
             *      mov eax, cr4
             *      or ax, 3 << 9		;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
             *      mov cr4, eax
             *      ret
             */

            ctx.AppendInstruction(X86.MovCR, eax, cr0);
            ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB));
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2));
            ctx.AppendInstruction(X86.MovCR, cr0, eax);

            ctx.AppendInstruction(X86.MovCR, eax, cr4);
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600));
            ctx.AppendInstruction(X86.MovCR, cr4, eax);

            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(setupMethod, basicBlocks, 0);

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

            typeInitializerSchedulerStage.Schedule(setupMethod);
        }
Esempio n. 9
0
        private static BasicBlocks CreateBasicBlockInstructionSet()
        {
            var basicBlocks = new BasicBlocks();

            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeaderBlock(block);

            var context = new Context(block);

            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);

            return basicBlocks;
        }
Esempio n. 10
0
        private static BasicBlocks CreateBasicBlockInstructionSet()
        {
            var basicBlocks = new BasicBlocks();

            var block = basicBlocks.CreateBlock();

            basicBlocks.AddHeaderBlock(block);

            var context = new Context(block);

            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);
            context.AppendInstruction(IRInstruction.Nop);

            return(basicBlocks);
        }
Esempio n. 11
0
        protected override void Run()
        {
            var typeInitializer = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod;

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeaderBlock(block);
            var context = new Context(block);

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

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

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

            Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text);
        }
Esempio n. 12
0
        protected override void Run()
        {
            Debug.Assert(setupMethod == null, "SSE setup method already generated!");

            setupMethod = Compiler.CreateLinkerMethod("SSEInit");

            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX);
            var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0);
            var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4);

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeaderBlock(block);
            var ctx = new Context(block);

            /*
               ;enable SSE and the like
                mov eax, cr0
                and ax, 0xFFFB		;clear coprocessor emulation CR0.EM
                or ax, 0x2			;set coprocessor monitoring  CR0.MP
                mov cr0, eax
                mov eax, cr4
                or ax, 3 << 9		;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
                mov cr4, eax
                ret
            */

            ctx.AppendInstruction(X86.MovCR, eax, cr0);
            ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB));
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2));
            ctx.AppendInstruction(X86.MovCR, cr0, eax);

            ctx.AppendInstruction(X86.MovCR, eax, cr4);
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600));
            ctx.AppendInstruction(X86.MovCR, cr4, eax);

            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(setupMethod, basicBlocks, 0);

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>();
            typeInitializerSchedulerStage.Schedule(setupMethod);
        }
Esempio n. 13
0
        protected override void Run()
        {
            TypeInitializerSchedulerStage typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>();

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

            Operand entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);

            context.AppendInstruction(IRInstruction.Call, null, entryPoint);
            context.MosaMethod = typeInitializerSchedulerStage.TypeInitializerMethod;
            //context.AppendInstruction(IRInstruction.Break);

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

            Linker.EntryPoint = Linker.GetSymbol(method.FullName);
        }
Esempio n. 14
0
        protected override void Run()
        {
            var typeInitializer = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>().TypeInitializerMethod;

            var basicBlocks = new BasicBlocks();
            var block       = basicBlocks.CreateBlock();

            basicBlocks.AddHeaderBlock(block);
            var context = new Context(block);

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

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

            var method = Compiler.CreateLinkerMethod(StartUpName);

            Compiler.CompileMethod(method, basicBlocks, 0);

            Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text);
        }
        /// <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++)
            {
                var basicBlocks = new BasicBlocks();
                var block = basicBlocks.CreateBlock();
                basicBlocks.AddHeaderBlock(block);
                var ctx = new Context(block);

                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(TypeSystem, 0));
                ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Push, null, esp);
                ctx.AppendInstruction(X86.Call, null, interrupt);
                ctx.AppendInstruction(X86.Pop, esp);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, 8));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString());
                Compiler.CompileMethod(interruptMethod, basicBlocks, 0);
            }
        }
Esempio n. 16
0
 private void DecodeProtectedRegionTargets()
 {
     foreach (var handler in MethodCompiler.Method.ExceptionHandlers)
     {
         if (handler.TryStart != 0)
         {
             var block = GetBlockByLabel(handler.TryStart);
         }
         if (handler.TryEnd != 0)
         {
             var block = GetBlockByLabel(handler.TryEnd);
         }
         if (handler.HandlerStart != 0)
         {
             var block = GetBlockByLabel(handler.HandlerStart);
             BasicBlocks.AddHeaderBlock(block);
         }
         if (handler.FilterOffset != null)
         {
             var block = GetBlockByLabel(handler.FilterOffset.Value);
             BasicBlocks.AddHeaderBlock(block);
         }
     }
 }
Esempio n. 17
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. 18
0
        protected override void Run()
        {
            if (multibootMethod == null)
            {
                multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

                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 basicBlocks = new BasicBlocks();
            var instructionSet = new InstructionSet(25);

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

            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);

            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);

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

            Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet);

            Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
        protected override void Run()
        {
            // No CIL decoding if this is a linker generated method
            if (MethodCompiler.Method.IsLinkerGenerated)
            {
                return;
            }

            var plugMethod = MethodCompiler.Compiler.PlugSystem.GetPlugMethod(MethodCompiler.Method);

            if (plugMethod != null)
            {
                var plugSymbol = Operand.CreateSymbolFromMethod(TypeSystem, plugMethod);
                var context    = CreateNewBlockContext(-1);
                context.AppendInstruction(IRInstruction.Jmp, null, plugSymbol);
                BasicBlocks.AddHeaderBlock(context.Block);
                return;
            }

            if (MethodCompiler.Method.Code.Count == 0)
            {
                if (DelegatePatcher.PatchDelegate(MethodCompiler))
                {
                    return;
                }

                MethodCompiler.Stop();
                return;
            }

            MethodCompiler.SetLocalVariables(MethodCompiler.Method.LocalVariables);

            // Create the prologue block
            var prologue = CreateNewBlock(BasicBlock.PrologueLabel);

            BasicBlocks.AddHeaderBlock(prologue);

            var jmpNode = new InstructionNode();

            jmpNode.Label = BasicBlock.PrologueLabel;
            jmpNode.Block = prologue;
            prologue.First.Insert(jmpNode);

            // Create starting block
            var startBlock = CreateNewBlock(0);

            jmpNode.SetInstruction(IRInstruction.Jmp, startBlock);

            DecodeInstructionTargets();

            DecodeProtectedRegionTargets();

            /* Decode the instructions */
            DecodeInstructions();

            foreach (var block in BasicBlocks)
            {
                if (!block.HasPreviousBlocks && !BasicBlocks.HeadBlocks.Contains(block))
                {
                    // block was targeted (probably by an leave instruction within a protected region)
                    BasicBlocks.AddHeaderBlock(block);
                }
            }

            // This makes it easier to review --- it's not necessary
            BasicBlocks.OrderByLabel();
        }
Esempio n. 21
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();

                Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
                Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

                return;
            }

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.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 multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX);
            var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX);

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeaderBlock(block);
            var ctx = new Context(block);

            // set sentinel 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);

            ctx.AppendInstruction(X86.Mov, ecx, multibootEax);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax);
            ctx.AppendInstruction(X86.Mov, ecx, multibootEbx);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), 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, 0);
        }