/// <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); }
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 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); }
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; }
/// <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.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); }
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; }
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); }
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); }
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); }
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.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.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 (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); }
/// <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)); }
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); }
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 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); }
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; }
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); }
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); }