/// <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(); }
private void DecodeProtectedRegionTargets() { foreach (var handler in 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.AddHeadBlock(block); BasicBlocks.AddHandlerHeadBlock(block); } if (handler.FilterStart != null) { var block = GetBlockByLabel(handler.FilterStart.Value); BasicBlocks.AddHeadBlock(block); BasicBlocks.AddHandlerHeadBlock(block); } } }
/// <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(); }
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); }
protected override void Run() { if (!MethodCompiler.IsCILStream) { return; } // No CIL decoding if this is a linker generated method Debug.Assert(!MethodData.IsCompilerGenerated); MethodCompiler.SetLocalVariables(Method.LocalVariables); // Create the prologue block var prologue = CreateNewBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeadBlock(prologue); var jmpNode = new InstructionNode() { Label = BasicBlock.PrologueLabel, Block = prologue }; prologue.First.Insert(jmpNode); // Create starting block var startBlock = CreateNewBlock(0); jmpNode.SetInstruction(IRInstruction.Jmp, startBlock); DecodeInstructionTargets(); DecodeProtectedRegionTargets(); DecodeInstructions(); foreach (var block in BasicBlocks) { if (!block.HasPreviousBlocks && !block.IsHeadBlock) { // block was targeted (probably by an leave instruction within a protected region) BasicBlocks.AddHeadBlock(block); } } InitializePromotedLocalVariablesToVirtualRegisters(); InsertExceptionStartInstructions(); InsertFlowOrJumpInstructions(); // This makes it easier to review --- it's not necessary BasicBlocks.OrderByLabel(); }
/// <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); } }
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); }
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); }
private static BasicBlocks CreateBasicBlockInstructionSet() { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(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; }
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); }
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); }
private static BasicBlocks CreateBasicBlockInstructionSet() { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(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); }
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); }
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); }
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); }
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(); }
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); }
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); }
/// <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); } }
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); }
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); }
protected override void Run() { if (IsMethodPlugged) { var plugMethod = MethodCompiler.Compiler.PlugSystem.GetReplacement(MethodCompiler.Method); Debug.Assert(plugMethod != null); var plugSymbol = Operand.CreateSymbolFromMethod(plugMethod, TypeSystem); var context = CreateNewBlockContext(-1, -1); context.AppendInstruction(IRInstruction.Jmp, null, plugSymbol); BasicBlocks.AddHeadBlock(context.Block); return; } // No CIL decoding if this is a linker generated method if (MethodCompiler.Method.IsLinkerGenerated) { return; } if (MethodCompiler.Method.Code.Count == 0) { if (DelegatePatcher.PatchDelegate(MethodCompiler)) { return; } MethodCompiler.Stop(); return; } if (CompilerOptions.EnableStatistics) { counts = new int[CILInstruction.MaxOpCodeValue]; } MethodCompiler.SetLocalVariables(MethodCompiler.Method.LocalVariables); // Create the prologue block var prologue = CreateNewBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeadBlock(prologue); var jmpNode = new InstructionNode() { Label = BasicBlock.PrologueLabel, 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 && !block.IsHeadBlock) { // block was targeted (probably by an leave instruction within a protected region) BasicBlocks.AddHeadBlock(block); } } // This makes it easier to review --- it's not necessary BasicBlocks.OrderByLabel(); }
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); }
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); }
protected override void Run() { if (!MethodCompiler.IsCILDecodeRequired) { return; } // No CIL decoding if this is a linker generated method Debug.Assert(!Method.IsCompilerGenerated); if (!Method.HasImplementation) { //if (DelegatePatcher.PatchDelegate(MethodCompiler)) // return; MethodCompiler.Stop(); return; } if (CompilerOptions.EnableStatistics) { counts = new int[CILInstruction.MaxOpCodeValue]; } MethodCompiler.SetLocalVariables(Method.LocalVariables); // Create the prologue block var prologue = CreateNewBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeadBlock(prologue); var jmpNode = new InstructionNode() { Label = BasicBlock.PrologueLabel, 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 && !block.IsHeadBlock) { // block was targeted (probably by an leave instruction within a protected region) BasicBlocks.AddHeadBlock(block); } } // This makes it easier to review --- it's not necessary BasicBlocks.OrderByLabel(); }