/// <summary> /// Link time code generator used to compile dynamically created methods during link time. /// </summary> /// <param name="compiler">The assembly compiler used to compile this method.</param> /// <param name="methodName">The name of the created method.</param> /// <param name="instructionSet">The instruction set.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception> /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception> public static LinkerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet, ITypeSystem typeSystem) { if (compiler == null) throw new ArgumentNullException(@"compiler"); if (methodName == null) throw new ArgumentNullException(@"methodName"); if (methodName.Length == 0) throw new ArgumentException(@"Invalid method name."); LinkerGeneratedType compilerGeneratedType = typeSystem.InternalTypeModule.GetType(@"Mosa.Tools.Compiler", @"LinkerGenerated") as LinkerGeneratedType; // Create the type if we need to. if (compilerGeneratedType == null) { compilerGeneratedType = new LinkerGeneratedType(typeSystem.InternalTypeModule, @"Mosa.Tools.Compiler", @"LinkerGenerated", null); typeSystem.AddInternalType(compilerGeneratedType); } MethodSignature signature = new MethodSignature(new SigType(CilElementType.Void), new SigType[0]); // Create the method // HACK: <$> prevents the method from being called from CIL LinkerGeneratedMethod method = new LinkerGeneratedMethod(typeSystem.InternalTypeModule, "<$>" + methodName, compilerGeneratedType, signature); compilerGeneratedType.AddMethod(method); LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(), method, instructionSet); methodCompiler.Compile(); return method; }
/// <summary> /// Creates the ISR methods. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateISRMethods(AssemblyCompiler compiler) { // Create Interrupt Service Routines (ISR) RuntimeMethod InterruptMethod = compiler.Assembly.EntryPoint; // TODO: replace with another entry point SigType I1 = new SigType(CilElementType.I1); SigType I4 = new SigType(CilElementType.I4); RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX); for (int i = 0; i <= 256; i++) { InstructionSet set = new InstructionSet(100); Context ctx = new Context(set, -1); ctx.SetInstruction(CPUx86.Instruction.CliInstruction); if ((i != 8) && (i < 10 || i > 14)) // For IRQ 8, 10, 11, 12, 13, 14 the cpu automatically pushed the error code ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, 0x0)); ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction); ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, i)); // TODO: Set method parameters ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, InterruptMethod); ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax); ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction); ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax); ctx.AppendInstruction(CPUx86.Instruction.StiInstruction); //ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction); CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"InterruptISR" + i.ToString(), set); } }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { InstructionSet = new InstructionSet(1024); _ctx = CreateContext(-1); _ctx.AppendInstruction(IR.Instruction.PrologueInstruction); _ctx.Other = 0; // stacksize }
/// <summary> /// Setups the specified compiler. /// </summary> /// <param name="compiler">The compiler.</param> public void Setup(IMethodCompiler compiler) { if (compiler == null) throw new ArgumentNullException ("compiler"); MethodCompiler = compiler; InstructionSet = compiler.InstructionSet; BasicBlocks = compiler.BasicBlocks; Architecture = compiler.Architecture; }
/// <summary> /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class. /// </summary> /// <param name="compiler">The assembly compiler executing this method compiler.</param> /// <param name="method">The metadata of the method to compile.</param> /// <param name="instructionSet">The instruction set.</param> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception> public LinkerMethodCompiler(AssemblyCompiler compiler, RuntimeMethod method, InstructionSet instructionSet) : base(compiler.Pipeline.Find<IAssemblyLinker>(), compiler.Architecture, compiler.Assembly, method.DeclaringType, method) { InstructionSet = instructionSet; this.Pipeline.AddRange(new IMethodCompilerStage[] { new BasicBlockBuilderStage(), new CodeGenerationStage(), }); compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline); }
/// <summary> /// Setups the specified compiler. /// </summary> /// <param name="compiler">The compiler.</param> public void Setup(IMethodCompiler compiler) { if (compiler == null) { throw new ArgumentNullException(@"compiler"); } MethodCompiler = compiler; InstructionSet = compiler.InstructionSet; BasicBlocks = compiler.BasicBlocks; Architecture = compiler.Architecture; }
/// <summary> /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class. /// </summary> /// <param name="compiler">The assembly compiler executing this method compiler.</param> /// <param name="method">The metadata of the method to compile.</param> /// <param name="instructionSet">The instruction set.</param> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception> public LinkerMethodCompiler(AssemblyCompiler compiler, ICompilationSchedulerStage compilationScheduler, RuntimeMethod method, InstructionSet instructionSet) : base(compiler.Pipeline.FindFirst<IAssemblyLinker>(), compiler.Architecture, compilationScheduler, method.DeclaringType, method, compiler.TypeSystem, compiler.TypeLayout) { this.InstructionSet = instructionSet; this.CreateBlock(-1, 0); this.Pipeline.AddRange(new IMethodCompilerStage[] { new SimpleTraceBlockOrderStage(), new PlatformStubStage(), new CodeGenerationStage(), }); compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline); }
/// <summary> /// Setups the specified compiler. /// </summary> /// <param name="compiler">The compiler.</param> public void Setup(IMethodCompiler compiler) { if (compiler == null) { throw new ArgumentNullException(@"compiler"); } methodCompiler = compiler; InstructionSet = compiler.InstructionSet; basicBlocks = compiler.BasicBlocks; architecture = compiler.Architecture; typeModule = compiler.Method.Module; typeSystem = compiler.TypeSystem; typeLayout = compiler.TypeLayout; callingConvention = architecture.GetCallingConvention(); architecture.GetTypeRequirements(BuiltInSigType.IntPtr, out nativePointerSize, out nativePointerAlignment); }
/// <summary> /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class. /// </summary> /// <param name="linker">The _linker.</param> /// <param name="architecture">The target compilation Architecture.</param> /// <param name="type">The type, which owns the method to compile.</param> /// <param name="method">The method to compile by this instance.</param> protected BaseMethodCompiler( IAssemblyLinker linker, IArchitecture architecture, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method, ITypeSystem typeSystem, ITypeLayout typeLayout) { if (architecture == null) { throw new ArgumentNullException(@"architecture"); } if (linker == null) { throw new ArgumentNullException(@"linker"); } if (compilationScheduler == null) { throw new ArgumentNullException(@"compilationScheduler"); } this.linker = linker; this.architecture = architecture; this.method = method; this.type = type; parameters = new List <Operand>(new Operand[method.Parameters.Count]); nextStackSlot = 0; basicBlocks = new List <BasicBlock>(); instructionSet = null; // this will be set later pipeline = new CompilerPipeline(); this.compilationScheduler = compilationScheduler; this.moduleTypeSystem = method.Module; this.typeSystem = typeSystem; this.typeLayout = typeLayout; }
/// <summary> /// Link time code generator used to compile dynamically created methods during link time. /// </summary> /// <param name="compiler">The assembly compiler used to compile this method.</param> /// <param name="methodName">The name of the created method.</param> /// <param name="instructionSet">The instruction set.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception> /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception> public static CompilerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet) { if (compiler == null) throw new ArgumentNullException(@"compiler"); if (methodName == null) throw new ArgumentNullException(@"methodName"); if (methodName.Length == 0) throw new ArgumentException(@"Invalid method name."); // Create the type if we need to. if (compilerGeneratedType == null) compilerGeneratedType = new CompilerGeneratedType(compiler.Assembly, @"Mosa.Tools.Compiler", @"LinkerGenerated"); // Create the method // HACK: <$> prevents the method from being called from CIL CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, "<$>" + methodName, compilerGeneratedType); compilerGeneratedType.AddMethod(method); LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(), method, instructionSet); methodCompiler.Compile(); return method; }
/// <summary> /// Initializes a new instance of the <see cref="MethodCompilerBase"/> class. /// </summary> /// <param name="linker">The _linker.</param> /// <param name="architecture">The target compilation Architecture.</param> /// <param name="module">The metadata module, that contains the type.</param> /// <param name="type">The type, which owns the _method to compile.</param> /// <param name="method">The method to compile by this instance.</param> protected MethodCompilerBase(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method) { if (architecture == null) { throw new ArgumentNullException("architecture"); } if (linker == null) { throw new ArgumentNullException("linker"); } _architecture = architecture; _linker = linker; _method = method; _module = module; _parameters = new List <Operand> (new Operand[_method.Parameters.Count]); _type = type; _nextStackSlot = 0; _basicBlocks = new List <BasicBlock> (); _instructionSet = null; // this will be set later }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="index">The index.</param> public Context(InstructionSet instructionSet, int index) { _instructionSet = instructionSet; _index = index; _block = null; }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateISRMethods() { // Get RuntimeMethod for the Mosa.Kernel.X86.IDT.InterruptHandler RuntimeType rt = RuntimeBase.Instance.TypeLoader.GetType(@"Mosa.Kernel.X86.IDT"); if (rt == null) return; RuntimeMethod InterruptMethod = FindMethod(rt, "InterruptHandler"); if (InterruptMethod == null) return; 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, 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); CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), set); } }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> void IAssemblyCompilerStage.Run() { if (!secondStage) { IntPtr entryPoint = WriteMultibootEntryPoint(); WriteMultibootHeader(entryPoint); secondStage = true; } else { var 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 application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (_pipeline == null) throw new ObjectDisposedException(@"MethodCompilerBase"); foreach (IMethodCompilerStage mcs in _pipeline) { IDisposable d = mcs as IDisposable; if (null != d) d.Dispose(); } _pipeline.Clear(); _pipeline = null; _architecture = null; _linker = null; _method = null; _module = null; _type = null; _instructionSet = null; _basicBlocks = null; }
/// <summary> /// Initializes a new instance of the <see cref="MethodCompilerBase"/> class. /// </summary> /// <param name="linker">The _linker.</param> /// <param name="architecture">The target compilation Architecture.</param> /// <param name="module">The metadata module, that contains the type.</param> /// <param name="type">The type, which owns the _method to compile.</param> /// <param name="method">The method to compile by this instance.</param> protected MethodCompilerBase( IAssemblyLinker linker, IArchitecture architecture, ICompilationSchedulerStage compilationScheduler, IMetadataModule module, RuntimeType type, RuntimeMethod method) { if (architecture == null) throw new ArgumentNullException(@"architecture"); if (linker == null) throw new ArgumentNullException(@"linker"); if (compilationScheduler == null) throw new ArgumentNullException(@"compilationScheduler"); _linker = linker; _architecture = architecture; this.compilationScheduler = compilationScheduler; _method = method; _module = module; _parameters = new List<Operand>(new Operand[_method.Parameters.Count]); _type = type; _nextStackSlot = 0; _basicBlocks = new List<BasicBlock>(); _instructionSet = null; // this will be set later }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="block">The block.</param> /// <param name="index">The index.</param> public Context(InstructionSet instructionSet, BasicBlock block, int index) { _instructionSet = instructionSet; _index = index; _block = block; }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="index">The index.</param> public Context(InstructionSet instructionSet, int index) { _instructionSet = instructionSet; _index = index; _block = null; }
/// <summary> /// Setups the specified compiler. /// </summary> /// <param name="compiler">The compiler.</param> public void Setup(IMethodCompiler compiler) { if (compiler == null) throw new ArgumentNullException(@"compiler"); methodCompiler = compiler; InstructionSet = compiler.InstructionSet; basicBlocks = compiler.BasicBlocks; architecture = compiler.Architecture; typeModule = compiler.Method.Module; typeSystem = compiler.TypeSystem; typeLayout = compiler.TypeLayout; callingConvention = architecture.GetCallingConvention(); architecture.GetTypeRequirements(BuiltInSigType.IntPtr, out nativePointerSize, out nativePointerAlignment); }
/// <summary> /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class. /// </summary> /// <param name="linker">The _linker.</param> /// <param name="architecture">The target compilation Architecture.</param> /// <param name="type">The type, which owns the method to compile.</param> /// <param name="method">The method to compile by this instance.</param> protected BaseMethodCompiler( IAssemblyLinker linker, IArchitecture architecture, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method, ITypeSystem typeSystem, ITypeLayout typeLayout) { if (architecture == null) throw new ArgumentNullException(@"architecture"); if (linker == null) throw new ArgumentNullException(@"linker"); if (compilationScheduler == null) throw new ArgumentNullException(@"compilationScheduler"); this.linker = linker; this.architecture = architecture; this.method = method; this.type = type; parameters = new List<Operand>(new Operand[method.Parameters.Count]); nextStackSlot = 0; basicBlocks = new List<BasicBlock>(); instructionSet = null; // this will be set later pipeline = new CompilerPipeline(); this.compilationScheduler = compilationScheduler; this.moduleTypeSystem = method.Module; this.typeSystem = typeSystem; this.typeLayout = typeLayout; }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="basicBlock">The basic block.</param> public Context(InstructionSet instructionSet, BasicBlock basicBlock) { _instructionSet = instructionSet; _index = basicBlock.Index; _block = basicBlock; }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="block">The block.</param> /// <param name="index">The index.</param> public Context(InstructionSet instructionSet, BasicBlock block, int index) { _instructionSet = instructionSet; _index = index; _block = block; }
/// <summary> /// Creates the IVT method. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateIVTMethod(AssemblyCompiler compiler) { InstructionSet set = new InstructionSet(4048); Context ctx = new Context(set, -1); ctx.SetInstruction(IR.Instruction.PrologueInstruction); ctx.Other = 0; // stacksize // Create the IVT Table 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); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new ConstantOperand(I4, (int)0x201000)); for (int i = 0; i <= 256; i++) { LinkerSymbol symbol = _linker.GetSymbol(@"Mosa.Tools.Compiler.LinkerGenerated.<$>InterruptISR" + i.ToString() + "()"); Operand address = new ConstantOperand(I4, (int)_linker.GetSection(SectionKind.Text).VirtualAddress + symbol.SectionAddress); ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(i * 4)), address); } ctx.AppendInstruction(IR.Instruction.EpilogueInstruction); ctx.Other = 0; CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"InterruptInit", set); }
/// <summary> /// Initializes a new instance of the <see cref="Context"/> class. /// </summary> /// <param name="instructionSet">The instruction set.</param> /// <param name="basicBlock">The basic block.</param> public Context(InstructionSet instructionSet, BasicBlock basicBlock) { _instructionSet = instructionSet; _index = basicBlock.Index; _block = basicBlock; }
/// <summary> /// Creates the ISR methods. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateISRMethods(AssemblyCompiler compiler) { // Get RuntimeMethod for the Mosa.Kernel.X86.IDT.InterruptHandler RuntimeType rt = RuntimeBase.Instance.TypeLoader.GetType(@"Mosa.Kernel.X86.IDT"); RuntimeMethod InterruptMethod = FindMethod(rt, "InterruptHandler"); SigType I1 = new SigType(CilElementType.I1); SigType I2 = new SigType(CilElementType.I4); RegisterOperand ecx1 = new RegisterOperand(I1, GeneralPurposeRegister.ECX); RegisterOperand ecx2 = new RegisterOperand(I2, GeneralPurposeRegister.ECX); for (int i = 0; i <= 256; i++) { InstructionSet set = new InstructionSet(100); Context ctx = new Context(set, -1); ctx.AppendInstruction(CPUx86.Instruction.CliInstruction); ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction); if ((i != 8) && (i < 10 || i > 14)) // 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(I2, i)); ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, InterruptMethod); // TODO: Replace next two instructions with add esp, 5 ;Stack clearing ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, ecx2); ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, ecx1); ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction); ctx.AppendInstruction(CPUx86.Instruction.StiInstruction); ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction); CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"InterruptISR" + i.ToString(), set); } }