/// <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);
        }
Exemple #10
0
        /// <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);
        }
Exemple #13
0
 /// <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);
        }
Exemple #15
0
        /// <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);
        }
Exemple #16
0
        /// <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);
        }
Exemple #17
0
        /// <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);
        }
Exemple #18
0
 /// <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);
 }
Exemple #19
0
        /// <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;
        }
Exemple #21
0
        /// <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);
            }
        }