/// <summary> /// Assigns the registers. /// </summary> private void AssignRegisters() { List<LiveRange> active = new List<LiveRange>(); _registers = FillRegisterList(); for (int i = 0; i < _liveRanges.Count; i++) { LiveRange lr = _liveRanges[i]; ExpireOldRanges(lr.Start, active); Register reg = AllocateRegister(lr.Op); if (reg == null) reg = SpillRegister(active, lr); Debug.Assert(reg != null, @"Failed to allocate a register type."); RegisterOperand rop = new RegisterOperand(lr.Op.Type, reg); ReplaceOperand(lr, rop); ; lr.Reg = reg; int insIdx = active.FindIndex(delegate(LiveRange match) { return ((lr.End - match.End) > 0); }); active.Insert(insIdx + 1, lr); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { // Retrieve register context //context.SetInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.ESP, new IntPtr(28))); // Restore registers (Note: EAX and EDX are NOT restored!) //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EDX), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(28))); //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EBX), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(4))); //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EDI), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(20))); //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.ESI), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(16))); //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.ESP), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(32))); //context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EBP), new MemoryOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX, new IntPtr(24))); //uint ebp, uint esp, int eip RegisterOperand edx = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EDX); RegisterOperand ebp = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EBP); RegisterOperand esp = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.ESP); // Restore registers context.AppendInstruction(X86.Mov, new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.ESP), context.Operand1); // Jmp to EIP (stored in EDX) context.AppendInstruction(X86.Jmp, null, edx); //context.SetOperand(0, edx); }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateExceptionVector() { RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Kernel.x86.IDT"); if (runtimeType == null) return; RuntimeMethod runtimeMethod = runtimeType.FindMethod(@"ExceptionHandler"); if (runtimeMethod == null) return; SymbolOperand exceptionMethod = SymbolOperand.FromMethod(runtimeMethod); RegisterOperand esp = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.ESP); InstructionSet instructionSet = new InstructionSet(100); Context ctx = new Context(instructionSet); // TODO - setup stack for call to the managed exception handler //1. //2. //3. Call the managed exception handler ctx.AppendInstruction(Instruction.CallInstruction, null, exceptionMethod); LinkTimeCodeGenerator.Compile(this.compiler, @"ExceptionVector", instructionSet, typeSystem); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { var result = context.Result; //var op1 = context.Operand1; var op2 = context.Operand2; var eax = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX); var edx = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX); var esp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.ESP); var ebp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EBP); context.SetInstruction(X86.Sub, esp, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4)); context.AppendInstruction(X86.Mov, edx, esp); var size = parameters.Count * 4; foreach (var parameter in parameters) { context.AppendInstruction(X86.Mov, new MemoryOperand(BuiltInSigType.IntPtr, edx.Register, new IntPtr(size - 4)), new MemoryOperand(BuiltInSigType.IntPtr, ebp.Register, new IntPtr(size + 8))); size -= 4; } context.AppendInstruction(X86.Mov, eax, op2); context.AppendInstruction(X86.Call, null, new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX)); context.AppendInstruction(X86.Add, esp, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4)); context.AppendInstruction(X86.Mov,result, new RegisterOperand(result.Type, GeneralPurposeRegister.EAX)); }
/// <summary> /// Creates the interrupt service routine (ISR) methods. /// </summary> private void CreateInterruptVectors() { RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Kernel.x86.IDT"); if (runtimeType == null) return; RuntimeMethod runtimeMethod = runtimeType.FindMethod(@"ProcessInterrupt"); if (runtimeMethod == null) return; SymbolOperand interruptMethod = SymbolOperand.FromMethod(runtimeMethod); RegisterOperand esp = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { InstructionSet instructionSet = new InstructionSet(100); Context ctx = new Context(instructionSet); 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, new ConstantOperand(BuiltInSigType.SByte, 0x0)); ctx.AppendInstruction(X86.Push, null, new ConstantOperand(BuiltInSigType.SByte, (byte)i)); ctx.AppendInstruction(X86.Pushad); ctx.AppendInstruction(X86.Call, null, interruptMethod); ctx.AppendInstruction(X86.Popad); ctx.AppendInstruction(X86.Add, esp, new ConstantOperand(BuiltInSigType.Int32, 0x08)); ctx.AppendInstruction(X86.Sti); ctx.AppendInstruction(X86.IRetd); LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), instructionSet, typeSystem); } }
/// <summary> /// Converts the given instruction from three address format to a two address format. /// </summary> /// <param name="ctx">The conversion context.</param> private static void ThreeTwoAddressConversion(Context ctx) { if (!(ctx.Instruction is BaseIRInstruction)) return; if (ctx.Instruction is IntegerCompare || ctx.Instruction is FloatCompare || ctx.Instruction is Load || ctx.Instruction is Store || ctx.Instruction is Call || ctx.Instruction is ZeroExtendedMove || ctx.Instruction is SignExtendedMove) return; Operand result = ctx.Result; Operand op1 = ctx.Operand1; Operand op2 = ctx.Operand2; // Create registers for different data types RegisterOperand eax = new RegisterOperand(op1.Type, op1.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX); RegisterOperand storeOperand = new RegisterOperand(result.Type, result.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX); ctx.Result = storeOperand; ctx.Operand1 = op2; ctx.Operand2 = null; ctx.OperandCount = 1; if (op1.StackType != StackTypeCode.F) { if (IsSigned(op1) && !(op1 is ConstantOperand)) ctx.InsertBefore().SetInstruction(IRInstruction.SignExtendedMove, eax, op1); else if (IsUnsigned(op1) && !(op1 is ConstantOperand)) ctx.InsertBefore().SetInstruction(IRInstruction.ZeroExtendedMove, eax, op1); else ctx.InsertBefore().SetInstruction(X86.Mov, eax, op1); } else { if (op1.Type.Type == CilElementType.R4) { if (op1 is ConstantOperand) { Context before = ctx.InsertBefore(); before.SetInstruction(X86.Mov, eax, op1); before.AppendInstruction(X86.Cvtss2sd, eax, eax); } else { ctx.InsertBefore().SetInstruction(X86.Cvtss2sd, eax, op1); } } else { ctx.InsertBefore().SetInstruction(X86.Mov, eax, op1); } } ctx.AppendInstruction(X86.Mov, result, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand result = context.Result; RegisterOperand imm = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX); context.SetInstruction(IR.Instruction.MoveInstruction, imm, new RegisterOperand(BuiltInSigType.UInt32, control)); context.AppendInstruction(IR.Instruction.MoveInstruction, result, imm); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand operand1 = context.Operand1; RegisterOperand eax = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.EAX); RegisterOperand cr = new RegisterOperand(BuiltInSigType.UInt32, control); context.SetInstruction(IR.IRInstruction.Move, eax, operand1); context.AppendInstruction(IR.IRInstruction.Move, cr, eax); }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IR.IIRVisitor.AddressOfInstruction(Context context) { var opRes = context.Result; RegisterOperand register = new RegisterOperand(opRes.Type, GeneralPurposeRegister.EAX); context.Result = register; context.ReplaceInstructionOnly(Instruction.LeaInstruction); //context.Ignore = true; context.AppendInstruction(Instruction.MovInstruction, opRes, register); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand result = context.Result; RegisterOperand tmp = new RegisterOperand(BuiltInSigType.Ptr, GeneralPurposeRegister.EDX); MemoryOperand operand = new MemoryOperand(context.Operand1.Type, GeneralPurposeRegister.EDX, new System.IntPtr(0)); context.SetInstruction(X86.Mov, tmp, context.Operand1); context.AppendInstruction(X86.Mov, result, operand); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { //var result = context.Result; //var op1 = context.Operand1; //var op2 = context.Operand2; //var eax = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX); //var edx = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX); //var esp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.ESP); //var ebp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EBP); //context.SetInstruction(Instruction.SubInstruction, esp, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4 + 4)); //context.AppendInstruction(Instruction.MovInstruction, edx, esp); //var size = parameters.Count * 4 + 4; //foreach (var parameter in parameters) //{ // context.AppendInstruction(Instruction.MovInstruction, new MemoryOperand(BuiltInSigType.IntPtr, edx.Register, new IntPtr(size - 4)), new MemoryOperand(BuiltInSigType.IntPtr, ebp.Register, new IntPtr(size + 4))); // size -= 4; //} //context.AppendInstruction(Instruction.MovInstruction, new MemoryOperand(BuiltInSigType.IntPtr, edx.Register, new IntPtr(size - 4)), op1); //context.AppendInstruction(Instruction.MovInstruction, eax, op2); //context.AppendInstruction(Instruction.CallPointerInstruction, null, new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX)); //context.AppendInstruction(Instruction.AddInstruction, esp, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4 + 4)); //context.AppendInstruction(Instruction.MovInstruction, result, new RegisterOperand(result.Type, GeneralPurposeRegister.EAX)); var result = context.Result; var op1 = context.Operand1; var op2 = context.Operand2; var r8 = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R8); var r9 = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R9); var sp = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.SP); var r11 = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R11); var r10 = new RegisterOperand(BuiltInSigType.UInt32, GeneralPurposeRegister.R10); context.SetInstruction(Instruction.SubInstruction, sp, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4 + 4)); context.AppendInstruction(Instruction.MovInstruction, r9, sp); var size = parameters.Count * 4 + 4; foreach (var parameter in parameters) { context.AppendInstruction(Instruction.LdInstruction, r10, new MemoryOperand(BuiltInSigType.IntPtr, r11.Register, new IntPtr(size + 4))); context.AppendInstruction(Instruction.StInstruction, new MemoryOperand(BuiltInSigType.IntPtr, r9.Register, new IntPtr(size - 4)), r10); size -= 4; } context.AppendInstruction(Instruction.LdInstruction, r10, op1); context.AppendInstruction(Instruction.StInstruction, new MemoryOperand(BuiltInSigType.IntPtr, r9.Register, new IntPtr(size - 4)), r10); context.AppendInstruction(Instruction.MovInstruction, r8, op2); context.AppendInstruction(Instruction.IcallInstruction, null, new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.R8)); context.AppendInstruction(Instruction.MovInstruction, r10, new ConstantOperand(BuiltInSigType.IntPtr, parameters.Count * 4)); context.AppendInstruction(Instruction.AddInstruction, sp, r10); context.AppendInstruction(Instruction.StInstruction, result, new RegisterOperand(result.Type, GeneralPurposeRegister.R8)); }
/// <summary> /// Addresses the of instruction. /// </summary> /// <param name="context">The context.</param> void IIRVisitor.AddressOf(Context context) { var opRes = context.Result; RegisterOperand register = new RegisterOperand(opRes.Type, GeneralPurposeRegister.EAX); //VirtualRegisterOperand register = methodCompiler.VirtualRegisterLayout.AllocateVirtualRegister(opRes.Type); context.Result = register; context.ReplaceInstructionOnly(X86.Lea); context.AppendInstruction(X86.Mov, opRes, register); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="context">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context context, MachineCodeEmitter emitter) { if (context.Result is RegisterOperand) { RegisterOperand sp = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.SP); RegisterOperand register = context.Operand1 as RegisterOperand; emitter.EmitTwoRegisterInstructions((byte)0x0D, (byte)sp.Register.RegisterCode, (byte)register.Register.RegisterCode); // st.w --Rp, Rs } else throw new Exception("Not supported combination of operands"); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { SigType I4 = BuiltInSigType.Int32; RegisterOperand esp = new RegisterOperand(I4, GeneralPurposeRegister.ESP); context.SetInstruction(X86.Mov, esp, context.Operand1); context.AppendInstruction(X86.Popad); context.AppendInstruction(X86.Add, esp, new ConstantOperand(I4, 0x08)); context.AppendInstruction(X86.Sti); context.AppendInstruction(X86.IRetd); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand result = context.Result; Operand operand1 = context.Operand1; RegisterOperand edx = new RegisterOperand(operand1.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand(result.Type, GeneralPurposeRegister.EAX); context.SetInstruction(X86.Mov, edx, operand1); context.AppendInstruction(X86.In, eax, edx); context.AppendInstruction(X86.Mov, result, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand result = context.Result; SigType u4 = BuiltInSigType.UInt32; RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX); context.SetInstruction(X86.Pop, eax); context.AppendInstruction(X86.Add, eax, new RegisterOperand(u4, GeneralPurposeRegister.ESP)); context.AppendInstruction(X86.Mov, eax, new MemoryOperand(GeneralPurposeRegister.EAX, u4, new IntPtr(0))); context.AppendInstruction(X86.Mov, result, eax); context.AppendInstruction(X86.Push, null, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand operand1 = context.Operand1; Operand operand2 = context.Operand2; RegisterOperand edx = new RegisterOperand(operand1.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand(operand2.Type, GeneralPurposeRegister.EAX); context.SetInstruction(Instruction.MovInstruction, edx, operand1); context.AppendInstruction(Instruction.MovInstruction, eax, operand2); context.AppendInstruction(Instruction.OutInstruction, null, edx, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand result = context.Result; Operand operand = context.Operand1; RegisterOperand eax = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.EAX); RegisterOperand ecx = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.ECX); RegisterOperand reg = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.EAX); context.SetInstruction(X86.Mov, eax, operand); context.AppendInstruction(X86.Xor, ecx, ecx); context.AppendInstruction(X86.CpuId, eax, eax); context.AppendInstruction(X86.Mov, result, reg); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { Operand dest = context.Operand1; Operand value = context.Operand2; RegisterOperand edx = new RegisterOperand(dest.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand(value.Type, GeneralPurposeRegister.EAX); MemoryOperand memory = new MemoryOperand(new SigType(context.InvokeTarget.Signature.Parameters[1].Type), GeneralPurposeRegister.EDX, new IntPtr(0)); context.SetInstruction(X86.Mov, edx, dest); context.AppendInstruction(X86.Mov, eax, value); context.AppendInstruction(X86.Mov, memory, eax); }
private RegisterOperand AllocateRegister(SigType sigType) { RegisterOperand result; if (RequiresSseOperation(sigType)) { result = new RegisterOperand(sigType, SSE2Register.XMM6); } else { result = new RegisterOperand(sigType, GeneralPurposeRegister.EAX); } return result; }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters) { MemoryOperand operand = new MemoryOperand(BuiltInSigType.Ptr, GeneralPurposeRegister.EAX, new System.IntPtr(0)); context.SetInstruction(X86.Mov, new RegisterOperand(BuiltInSigType.Ptr, GeneralPurposeRegister.EAX), context.Operand1); context.AppendInstruction(X86.Lgdt, null, operand); RegisterOperand ax = new RegisterOperand(BuiltInSigType.Int16, GeneralPurposeRegister.EAX); RegisterOperand ds = new RegisterOperand(BuiltInSigType.Int16, SegmentRegister.DS); RegisterOperand es = new RegisterOperand(BuiltInSigType.Int16, SegmentRegister.ES); RegisterOperand fs = new RegisterOperand(BuiltInSigType.Int16, SegmentRegister.FS); RegisterOperand gs = new RegisterOperand(BuiltInSigType.Int16, SegmentRegister.GS); RegisterOperand ss = new RegisterOperand(BuiltInSigType.Int16, SegmentRegister.SS); context.AppendInstruction(X86.Mov, ax, new ConstantOperand(BuiltInSigType.Int32, (int)0x00000010)); context.AppendInstruction(X86.Mov, ds, ax); context.AppendInstruction(X86.Mov, es, ax); context.AppendInstruction(X86.Mov, fs, ax); context.AppendInstruction(X86.Mov, gs, ax); context.AppendInstruction(X86.Mov, ss, ax); context.AppendInstruction(X86.FarJmp); }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Call"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.Call(Context context) { Operand destinationOperand = context.Operand1; if (destinationOperand == null) return; if (destinationOperand is SymbolOperand) return; if (!(destinationOperand is RegisterOperand)) { Context before = context.InsertBefore(); RegisterOperand eax = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX); before.SetInstruction(X86.Mov, eax, destinationOperand); context.Operand1 = eax; } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Shr"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.Shr(Context context) { if (context.Operand1 is ConstantOperand) return; RegisterOperand ecx = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.ECX); Context before = context.InsertBefore(); before.SetInstruction(X86.Mov, ecx, context.Operand1); context.Operand1 = context.Result; }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Mul"/> instructions. /// </summary> /// <param name="ctx">The context.</param> void IX86Visitor.Mul(Context ctx) { if (ctx.Operand1 is ConstantOperand) { RegisterOperand ecx = new RegisterOperand(ctx.Operand1.Type, GeneralPurposeRegister.ECX); Context before = ctx.InsertBefore(); before.SetInstruction(X86.Push, null, ecx); before.AppendInstruction(X86.Mov, ecx, ctx.Operand1); ctx.Operand1 = ecx; ctx.AppendInstruction(X86.Pop, ecx); } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Movzx"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.Movzx(Context context) { if (Is32Bit(context.Operand1)) { context.ReplaceInstructionOnly(X86.Mov); } else { Operand result = context.Result; if (!(result is RegisterOperand)) { RegisterOperand ecx = new RegisterOperand(context.Result.Type, GeneralPurposeRegister.ECX); context.SetInstruction(X86.Movzx, ecx, context.Operand1); context.AppendInstruction(X86.Mov, result, ecx); } } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.IDiv"/> instructions. /// </summary> /// <param name="context">The context.</param> void IX86Visitor.IDiv(Context context) { Context before = context.InsertBefore(); before.SetInstruction(X86.Cdq); if (context.Operand1 is ConstantOperand) { RegisterOperand ecx = new RegisterOperand(context.Operand1.Type, GeneralPurposeRegister.ECX); before.AppendInstruction(X86.Mov, ecx, context.Operand1); context.Operand1 = ecx; } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.DirectMultiplication"/> instructions. /// </summary> /// <param name="ctx">The context.</param> void IX86Visitor.DirectMultiplication(Context ctx) { Operand op = ctx.Operand1; if (op is ConstantOperand) { RegisterOperand ebx = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.EBX); ctx.SetInstruction(X86.Push, null, ebx); ctx.AppendInstruction(X86.Mov, ebx, op); ctx.AppendInstruction(X86.IDiv, ebx); ctx.AppendInstruction(X86.Pop, ebx); } else { ctx.SetInstruction(X86.IDiv, null, op); } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Cvttss2si"/> instructions. /// </summary> /// <param name="ctx">The context.</param> void IX86Visitor.Cvttss2si(Context ctx) { Operand result = ctx.Result; RegisterOperand register = new RegisterOperand(result.Type, GeneralPurposeRegister.EAX); if (!(result is RegisterOperand)) { ctx.Result = register; ctx.AppendInstruction(X86.Mov, result, register); } }
/// <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 = BuiltInSigType.Int32; 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); ctx.AppendInstruction(X86.Mov, ecx, new ConstantOperand(I4, 0x200000)); ctx.AppendInstruction(X86.Mov, new MemoryOperand(ecx.Register, I4, new IntPtr(0x0)), eax); ctx.AppendInstruction(X86.Mov, new MemoryOperand(ecx.Register, I4, new IntPtr(0x4)), ebx); SymbolOperand entryPoint = SymbolOperand.FromMethod(typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); ctx.AppendInstruction(X86.Ret); LinkerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"MultibootInit", instructionSet, typeSystem); linker.EntryPoint = linker.GetSymbol(method.ToString()); } }
/// <summary> /// Visitation function for <see cref="IX86Visitor.Cmp"/> instructions. /// </summary> /// <param name="ctx">The context.</param> void IX86Visitor.Cmp(Context ctx) { Operand left = ctx.Operand1; Operand right = ctx.Operand2; if (left is ConstantOperand) { RegisterOperand ecx = new RegisterOperand(left.Type, GeneralPurposeRegister.ECX); Context before = ctx.InsertBefore(); before.SetInstruction(X86.Push, null, ecx); before.AppendInstruction(X86.Mov, ecx, left); ctx.Operand1 = ecx; ctx.AppendInstruction(X86.Pop, ecx); } if (right is ConstantOperand && !Is32Bit(left)) { RegisterOperand edx = new RegisterOperand(BuiltInSigType.Int32, GeneralPurposeRegister.EBX); Context before = ctx.InsertBefore(); before.SetInstruction(X86.Push, null, edx); if (IsSigned(left)) before.AppendInstruction(X86.Movsx, edx, left); else before.AppendInstruction(X86.Movzx, edx, left); ctx.Operand1 = edx; ctx.AppendInstruction(X86.Pop, edx); } }