예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerStage"/> class.
        /// </summary>
        public TypeInitializerStage()
        {
            basicBlocks = new BasicBlocks();

            // Create the blocks
            var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
            var startBlock    = basicBlocks.CreateBlock(BasicBlock.StartLabel);
            var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel);

            // Create the prologue instructions
            basicBlocks.AddHeadBlock(prologueBlock);
            var prologue = new Context(prologueBlock);

            prologue.AppendInstruction(IRInstruction.Prologue);
            prologue.Label = -1;
            prologue.AppendInstruction(IRInstruction.Jmp, startBlock);

            // Create the epilogue instruction
            var epilogue = new Context(epilogueBlock);

            epilogue.AppendInstruction(IRInstruction.Epilogue);

            // create start instructions
            start = new Context(startBlock);
            start.AppendInstruction(IRInstruction.Jmp, epilogueBlock);
            start.GotoPrevious();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class.
        /// </summary>
        public TypeInitializerSchedulerStage()
        {
            basicBlocks = new BasicBlocks();

            // Create the blocks
            var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
            var startBlock = basicBlocks.CreateBlock(BasicBlock.StartLabel);
            var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel);

            // Create the prologue instructions
            basicBlocks.AddHeadBlock(prologueBlock);
            var prologue = new Context(prologueBlock);
            prologue.AppendInstruction(IRInstruction.Prologue);
            prologue.Label = -1;
            prologue.AppendInstruction(IRInstruction.Jmp, startBlock);

            // Create the epilogue instruction
            var epilogue = new Context(epilogueBlock);
            epilogue.AppendInstruction(IRInstruction.Epilogue);

            // create start instructions
            start = new Context(startBlock);
            start.AppendInstruction(IRInstruction.Jmp, epilogueBlock);
            start.GotoPrevious();
        }
 /// <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);
 }
예제 #4
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);
        }
예제 #5
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 esp          = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);
            var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX);
            var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX);
            var zero         = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var stackTop     = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);

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

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, esp, 0), stackTop);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero);

            // Place the multiboot address into a static field
            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);
        }
예제 #6
0
        protected override void Finalization()
        {
            var basicBlocks = new BasicBlocks();

            // Create the blocks
            var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
            var startBlock    = basicBlocks.CreateBlock(BasicBlock.StartLabel);
            var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel);

            // Create the prologue instructions
            basicBlocks.AddHeadBlock(prologueBlock);
            var prologue = new Context(prologueBlock);

            prologue.AppendInstruction(IRInstruction.Prologue);
            prologue.Label = -1;
            prologue.AppendInstruction(IRInstruction.Jmp, startBlock);

            // Create the epilogue instruction
            var epilogue = new Context(epilogueBlock);

            epilogue.AppendInstruction(IRInstruction.Epilogue);

            var context = new Context(startBlock);

            var entrySymbol = Operand.CreateSymbolFromMethod(TypeSystem.EntryPoint, TypeSystem);

            context.AppendInstruction(IRInstruction.CallStatic, null, entrySymbol);

            var methods = new List <MosaMethod>();

            // TODO!

            foreach (var method in methods)
            {
                var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

                context.AppendInstruction(IRInstruction.CallStatic, null, symbol);
            }

            context.AppendInstruction(IRInstruction.Jmp, epilogueBlock);

            Compiler.CompileMethod(setupMethod, basicBlocks);
        }
예제 #7
0
        public static Context CreateNewBlock(this InstructionSet instructionSet, BasicBlocks basicBlocks, int label)
        {
            Context ctx = new Context(instructionSet);

            ctx.AppendInstruction(IRInstruction.BlockStart);
            int start = ctx.Index;
            ctx.AppendInstruction(IRInstruction.BlockEnd);
            int last = ctx.Index;

            BasicBlock block = basicBlocks.CreateBlock(label, start, last);
            ctx.BasicBlock = block;

            ctx.GotoPrevious();

            return ctx;
        }
예제 #8
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;
            }

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

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

            for (int i = 0; i <= 255; i++)
            {
                var basicBlocks = new BasicBlocks();
                var block       = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
                basicBlocks.AddHeadBlock(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.PushConst32, null, CreateConstant(0));
                }
                ctx.AppendInstruction(X86.PushConst32, null, CreateConstant(i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Push32, null, esp);
                ctx.AppendInstruction(X86.CallStatic, null, interrupt);
                ctx.AppendInstruction(X86.Pop32, esp);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.AddConst32, esp, esp, CreateConstant(8));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString());
                Compiler.CompileMethod(interruptMethod, basicBlocks);
            }
        }
예제 #9
0
        protected override void CreateMultibootMethod()
        {
            var startUpType      = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var initializeMethod = startUpType.FindMethodByName("Initialize");
            var entryPoint       = Operand.CreateSymbolFromMethod(initializeMethod, TypeSystem);

            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EAX);
            var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EBX);
            var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EBP);
            var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(MultibootEAX, TypeSystem);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(MultibootEBX, TypeSystem);

            var stackTop = CreateConstant(STACK_ADDRESS);
            var zero     = CreateConstant(0);
            var offset   = CreateConstant(8);

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

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

            //ctx.AppendInstruction(X64.Cli);

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X64.Mov64, esp, stackTop);
            ctx.AppendInstruction(X64.Mov64, ebp, stackTop);
            ctx.AppendInstruction(X64.MovStore64, null, esp, zero, zero);
            ctx.AppendInstruction(X64.MovStore64, null, esp, offset, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X64.MovStore64, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X64.MovStore64, null, multibootEBX, zero, ebx);

            //ctx.AppendInstruction(X64.Sti);
            ctx.AppendInstruction(X64.Call, null, entryPoint);
            ctx.AppendInstruction(X64.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks);

            MethodScanner.MethodInvoked(initializeMethod, multibootMethod);
            MethodScanner.MethodInvoked(multibootMethod, multibootMethod);
        }
예제 #10
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);
        }
예제 #11
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;
        }
예제 #12
0
        protected override void RunPreCompile()
        {
            var sseInitMethod = 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.AddHeadBlock(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(sseInitMethod, basicBlocks);

            var startUpType   = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var startUpMethod = startUpType.FindMethodByName("Stage2");

            Compiler.PlugSystem.CreatePlug(sseInitMethod, startUpMethod);
        }
예제 #13
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.AddHeadBlock(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);
        }
예제 #14
0
        protected override void RunPreCompile()
        {
            var sseInitMethod = 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.AddHeadBlock(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(sseInitMethod, basicBlocks);

            var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var startUpMethod = startUpType.FindMethodByName("Stage2");

            Compiler.PlugSystem.CreatePlug(sseInitMethod, startUpMethod);
        }
예제 #15
0
        protected override void Run()
        {
            var typeInitializer = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod;

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeadBlock(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);
        }
예제 #16
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);
        }
예제 #17
0
        protected override void RunPostCompile()
        {
            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);
            var zero     = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var four     = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 4);

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

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.Mov, InstructionSize.Size32, esp, stackTop);
            ctx.AppendInstruction(X86.Mov, InstructionSize.Size32, ebp, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, zero);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, four, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx);

            var startUpType   = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var startUpMethod = startUpType.FindMethodByName("Initialize");

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

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

            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks);

            WriteMultibootHeader();
        }
예제 #18
0
        private void CreateMultibootMethod()
        {
            var startUpType      = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var initializeMethod = startUpType.FindMethodByName("Initialize");

            Compiler.GetMethodData(initializeMethod).DoNotInline = true;

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

            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(MultibootEAX, TypeSystem);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(MultibootEBX, TypeSystem);

            var stackTop = CreateConstant(InitialStackAddress);
            var zero     = CreateConstant(0);
            var offset   = CreateConstant(4);

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

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.Mov32, esp, stackTop);
            ctx.AppendInstruction(X86.Mov32, ebp, stackTop);
            ctx.AppendInstruction(X86.MovStore32, null, esp, zero, zero);
            ctx.AppendInstruction(X86.MovStore32, null, esp, offset, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore32, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore32, null, multibootEBX, zero, ebx);

            ctx.AppendInstruction(X86.Call, null, entryPoint);              // FUTURE: Remove line (SetupStage)
            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks);
        }
예제 #19
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);
        }
예제 #20
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++)
            {
                var basicBlocks = new BasicBlocks();
                var block = basicBlocks.CreateBlock();
                basicBlocks.AddHeadBlock(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);
            }
        }
예제 #21
0
        protected override void RunPostCompile()
        {
            WriteMultibootHeader();

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

            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var zero     = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);

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

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, ebp, zero, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx);

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

            Compiler.CompileMethod(multibootMethod, basicBlocks);

            Linker.SetFirst(multibootHeader);
        }
예제 #22
0
        public static BasicBlocks CreateBasicBlockInstructionSet()
        {
            var basicBlocks = new BasicBlocks();

            var block = basicBlocks.CreateBlock();

            basicBlocks.AddHeadBlock(block);

            var context = new Context(block);

            var x  = Operand.CreateVirtualRegister(null, 1);
            var y  = Operand.CreateVirtualRegister(null, 2);
            var z  = Operand.CreateVirtualRegister(null, 3);
            var r  = Operand.CreateVirtualRegister(null, 4);
            var t1 = Operand.CreateVirtualRegister(null, 5);
            var t2 = Operand.CreateVirtualRegister(null, 6);
            var w  = Operand.CreateVirtualRegister(null, 7);

            context.AppendInstruction(IRInstruction.MulUnsigned32, t1, x, y);
            context.AppendInstruction(IRInstruction.MulUnsigned32, t2, x, z);
            context.AppendInstruction(IRInstruction.Add32, r, t1, t2);

            return(basicBlocks);
        }
예제 #23
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);
        }
예제 #24
0
        protected override void RunPostCompile()
        {
            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);
            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var four = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 4);

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.Mov, InstructionSize.Size32, esp, stackTop);
            ctx.AppendInstruction(X86.Mov, InstructionSize.Size32, ebp, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, zero);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, four, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx);

            var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var startUpMethod = startUpType.FindMethodByName("Initialize");

            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, startUpMethod);
            ctx.AppendInstruction(X86.Call, null, entryPoint);

            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks);

            WriteMultibootHeader();
        }
예제 #25
0
 /// <summary>
 /// Creates the new block.
 /// </summary>
 /// <param name="blockLabel">The label.</param>
 /// <param name="instructionLabel">The instruction label.</param>
 /// <returns></returns>
 private BasicBlock CreateNewBlock(int blockLabel, int instructionLabel)
 {
     return(BasicBlocks.CreateBlock(blockLabel, instructionLabel));
 }
예제 #26
0
        protected BasicBlocks CopyInstructions()
        {
            var newBasicBlocks = new BasicBlocks();
            var mapBlocks      = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count);
            var map            = new Dictionary <Operand, Operand>();

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.CreateBlock(block.Label);
                mapBlocks.Add(block, newBlock);
            }

            var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel);

            foreach (var operand in MethodCompiler.Parameters)
            {
                if (operand.Definitions.Count > 0)
                {
                    var newOp = Map(operand, map);

                    var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index);

                    var moveInstruction = StoreOnStack(newOperand.Type)
                                                ? IRInstruction.MoveCompound
                                                : GetMoveInstruction(newOperand.Type);

                    var moveNode = new InstructionNode(moveInstruction, newOperand, newOp);

                    newPrologueBlock.BeforeLast.Insert(moveNode);

                    // redirect map from parameter to virtual register going forward
                    map.Remove(operand);
                    map.Add(operand, newOperand);
                }
            }

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.GetByLabel(block.Label);

                for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                    {
                        continue;
                    }

                    var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount);
                    newNode.Size          = node.Size;
                    newNode.ConditionCode = node.ConditionCode;

                    if (node.BranchTargets != null)
                    {
                        // copy targets
                        foreach (var target in node.BranchTargets)
                        {
                            newNode.AddBranchTarget(mapBlocks[target]);
                        }
                    }

                    // copy results
                    for (int i = 0; i < node.ResultCount; i++)
                    {
                        var op    = node.GetResult(i);
                        var newOp = Map(op, map);

                        newNode.SetResult(i, newOp);
                    }

                    // copy operands
                    for (int i = 0; i < node.OperandCount; i++)
                    {
                        var op    = node.GetOperand(i);
                        var newOp = Map(op, map);

                        newNode.SetOperand(i, newOp);
                    }

                    // copy other
                    if (node.MosaType != null)
                    {
                        newNode.MosaType = node.MosaType;
                    }
                    if (node.MosaField != null)
                    {
                        newNode.MosaField = node.MosaField;
                    }
                    if (node.InvokeMethod != null)
                    {
                        newNode.InvokeMethod = node.InvokeMethod;
                    }

                    newBlock.BeforeLast.Insert(newNode);
                }
            }

            var trace = CreateTraceLog("InlineMap");

            if (trace.Active)
            {
                foreach (var entry in map)
                {
                    trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString());
                }
            }

            return(newBasicBlocks);
        }
예제 #27
0
        protected override void RunPostCompile()
        {
            WriteMultibootHeader();

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

            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var multibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, ebp, zero, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx);

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

            Compiler.CompileMethod(multibootMethod, basicBlocks);

            Linker.SetFirst(multibootHeader);
        }
예제 #28
0
        protected BasicBlocks CopyInstructions()
        {
            var newBasicBlocks = new BasicBlocks();
            var mapBlocks      = new Dictionary <BasicBlock, BasicBlock>(BasicBlocks.Count);
            var map            = new Dictionary <Operand, Operand>();
            var staticCalls    = new List <MosaMethod>();

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.CreateBlock(block.Label);
                mapBlocks.Add(block, newBlock);
            }

            var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel);

            foreach (var operand in MethodCompiler.Parameters)
            {
                if (operand.Definitions.Count > 0)
                {
                    var newOp = Map(operand, map);

                    var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index);

                    var moveInstruction = !MosaTypeLayout.CanFitInRegister(newOperand)
                                                ? IRInstruction.MoveCompound
                                                : GetMoveInstruction(newOperand.Type);

                    var moveNode = new InstructionNode(moveInstruction, newOperand, newOp);

                    newPrologueBlock.BeforeLast.Insert(moveNode);

                    // redirect map from parameter to virtual register going forward
                    map.Remove(operand);
                    map.Add(operand, newOperand);
                }
            }

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.GetByLabel(block.Label);

                for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmptyOrNop)
                    {
                        continue;
                    }

                    if (node.Instruction == IRInstruction.CallStatic)
                    {
                        staticCalls.AddIfNew(node.Operand1.Method);
                    }

                    var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount)
                    {
                        ConditionCode = node.ConditionCode,
                        InvokeMethod  = node.InvokeMethod,
                        MosaField     = node.MosaField,
                        MosaType      = node.MosaType,

                        //Label = callSiteNode.Label,
                    };

                    if (node.BranchTargets != null)
                    {
                        // copy targets
                        foreach (var target in node.BranchTargets)
                        {
                            newNode.AddBranchTarget(mapBlocks[target]);
                        }
                    }

                    // copy results
                    for (int i = 0; i < node.ResultCount; i++)
                    {
                        var op    = node.GetResult(i);
                        var newOp = Map(op, map);

                        newNode.SetResult(i, newOp);
                    }

                    // copy operands
                    for (int i = 0; i < node.OperandCount; i++)
                    {
                        var op    = node.GetOperand(i);
                        var newOp = Map(op, map);

                        newNode.SetOperand(i, newOp);
                    }

                    // copy other
                    if (node.MosaType != null)
                    {
                        newNode.MosaType = node.MosaType;
                    }

                    if (node.MosaField != null)
                    {
                        newNode.MosaField = node.MosaField;
                    }

                    newBlock.BeforeLast.Insert(newNode);
                }
            }

            var trace = CreateTraceLog("InlineMap", 9);

            if (trace != null)
            {
                foreach (var entry in map)
                {
                    trace.Log($"{entry.Value} from: {entry.Key}");
                }
            }

            return(newBasicBlocks);
        }
예제 #29
0
 public static void CreateBlock(this BasicBlocks basicBlocks, int index)
 {
     basicBlocks.CreateBlock(index);
 }
        protected BasicBlocks CopyInstructions()
        {
            var newBasicBlocks = new BasicBlocks();
            var mapBlocks = new Dictionary<BasicBlock, BasicBlock>(BasicBlocks.Count);
            var map = new Dictionary<Operand, Operand>();

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.CreateBlock(block.Label);
                mapBlocks.Add(block, newBlock);
            }

            var newPrologueBlock = newBasicBlocks.GetByLabel(BasicBlock.PrologueLabel);

            foreach (var operand in MethodCompiler.Parameters)
            {
                if (operand.Definitions.Count > 0)
                {
                    var newOp = Map(operand, map);

                    var newOperand = Operand.CreateVirtualRegister(operand.Type, -operand.Index);

                    newPrologueBlock.BeforeLast.Insert(new InstructionNode(IRInstruction.Move, newOperand, newOp));

                    // redirect map from parameter to virtual register going forward
                    map.Remove(operand);
                    map.Add(operand, newOperand);
                }
            }

            foreach (var block in BasicBlocks)
            {
                var newBlock = newBasicBlocks.GetByLabel(block.Label);

                for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                        continue;

                    var newNode = new InstructionNode(node.Instruction, node.OperandCount, node.ResultCount);
                    newNode.Size = node.Size;
                    newNode.ConditionCode = node.ConditionCode;

                    if (node.BranchTargets != null)
                    {
                        // copy targets
                        foreach (var target in node.BranchTargets)
                        {
                            newNode.AddBranchTarget(mapBlocks[target]);
                        }
                    }

                    // copy results
                    for (int i = 0; i < node.ResultCount; i++)
                    {
                        var op = node.GetResult(i);

                        var newOp = Map(op, map);

                        newNode.SetResult(i, newOp);
                    }

                    // copy operands
                    for (int i = 0; i < node.OperandCount; i++)
                    {
                        var op = node.GetOperand(i);

                        var newOp = Map(op, map);

                        newNode.SetOperand(i, newOp);
                    }

                    // copy other
                    if (node.MosaType != null)
                        newNode.MosaType = node.MosaType;
                    if (node.MosaField != null)
                        newNode.MosaField = node.MosaField;
                    if (node.InvokeMethod != null)
                        newNode.InvokeMethod = node.InvokeMethod;

                    newBlock.BeforeLast.Insert(newNode);
                }
            }

            var trace = CreateTraceLog("InlineMap");

            if (trace.Active)
            {
                foreach (var entry in map)
                {
                    trace.Log(entry.Value.ToString() + " from: " + entry.Key.ToString());
                }
            }

            return newBasicBlocks;
        }
예제 #31
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);
        }
예제 #32
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(Multiboot0695Stage.MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
                Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

                return;
            }

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

            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 esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var MultibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);

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

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, ebp, zero, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, MultibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, 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);
        }