/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> void IAssemblyCompilerStage.Run() { if (!secondStage) { IntPtr entryPoint = WriteMultibootEntryPoint(); WriteMultibootHeader(entryPoint); secondStage = true; } else { ITypeInitializerSchedulerStage typeInitializerSchedulerStage = this.compiler.Pipeline.FindFirst <ITypeInitializerSchedulerStage>(); SigType I4 = new SigType(CilElementType.I4); RegisterOperand ecx = new RegisterOperand(I4, GeneralPurposeRegister.ECX); RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX); RegisterOperand ebx = new RegisterOperand(I4, GeneralPurposeRegister.EBX); InstructionSet instructionSet = new InstructionSet(16); Context ctx = new Context(instructionSet, -1); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new ConstantOperand(I4, 0x200000)); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x0)), eax); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x4)), ebx); SymbolOperand entryPoint = SymbolOperand.FromMethod(typeInitializerSchedulerStage.Method); ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, null, entryPoint); ctx.AppendInstruction(CPUx86.Instruction.RetInstruction); LinkerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"MultibootInit", instructionSet, typeSystem); this.linker.EntryPoint = this.linker.GetSymbol(method.ToString()); } }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public void Run(AssemblyCompiler compiler) { _ctx.AppendInstruction(IR.Instruction.CallInstruction); _ctx.InvokeTarget = compiler.Assembly.EntryPoint; _ctx.AppendInstruction(IR.Instruction.EpilogueInstruction); _ctx.Other = 0; _method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", InstructionSet); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> void IAssemblyCompilerStage.Run() { ITypeModule mainTypeModule = typeSystem.MainTypeModule; if (mainTypeModule.MetadataModule.EntryPoint.RID != 0) { RuntimeMethod entrypoint = mainTypeModule.GetMethod(mainTypeModule.MetadataModule.EntryPoint); Schedule(entrypoint); } ctx.AppendInstruction(IR.Instruction.EpilogueInstruction); ctx.Other = 0; method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", instructionSet, typeSystem); }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateISRMethods() { // Get RuntimeMethod for the Mosa.Kernel.x86.IDT.InterruptHandler RuntimeType rt = typeSystem.GetType(@"Mosa.Kernel.x86.IDT"); if (rt == null) { return; } RuntimeMethod InterruptMethod = FindMethod(rt, "InterruptHandler"); if (InterruptMethod == null) { return; } SymbolOperand interruptMethod = SymbolOperand.FromMethod(InterruptMethod); SigType I1 = new SigType(CilElementType.I1); SigType I4 = new SigType(CilElementType.I4); RegisterOperand esp = new RegisterOperand(I4, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { InstructionSet set = new InstructionSet(100); Context ctx = new Context(set, -1); ctx.AppendInstruction(CPUx86.Instruction.CliInstruction); if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu automatically pushed the error code { ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I1, 0x0)); } ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I1, (byte)i)); ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction); ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, null, interruptMethod); ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction); ctx.AppendInstruction(CPUx86.Instruction.AddInstruction, esp, new ConstantOperand(I4, 0x08)); ctx.AppendInstruction(CPUx86.Instruction.StiInstruction); ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction); //LinkerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), set, typeSystem); } }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public void Run(AssemblyCompiler compiler) { if (compiler == null) { throw new ArgumentNullException(@"compiler"); } IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker>(); Debug.Assert(linker != null, @"No linker??"); if (!secondStage) { IntPtr entryPoint = WriteMultibootEntryPoint(linker); WriteMultibootHeader(compiler, linker, entryPoint); secondStage = true; } else { TypeInitializerSchedulerStage typeInitializerSchedulerStage = compiler.Pipeline.Find <TypeInitializerSchedulerStage>(); SigType I4 = new SigType(CilElementType.I4); RegisterOperand ecx = new RegisterOperand(I4, GeneralPurposeRegister.ECX); RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX); RegisterOperand ebx = new RegisterOperand(I4, GeneralPurposeRegister.EBX); InstructionSet instructionSet = new InstructionSet(16); Context ctx = new Context(instructionSet, -1); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new ConstantOperand(I4, 0x200000)); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x0)), eax); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x4)), ebx); ctx.AppendInstruction(IR.Instruction.CallInstruction); ctx.InvokeTarget = typeInitializerSchedulerStage.Method; ctx.AppendInstruction(CPUx86.Instruction.NopInstruction); ctx.AppendInstruction(CPUx86.Instruction.NopInstruction); ctx.AppendInstruction(CPUx86.Instruction.RetInstruction); CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"MultibootInit", instructionSet); linker.EntryPoint = linker.GetSymbol(method); } }