AppendInstruction() приватный Метод

Appends an (empty) instruction after the current index.
private AppendInstruction ( ) : void
Результат void
Пример #1
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)
        {
            // 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);
        }
Пример #2
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters)
        {
            //var result = context.Result;
            var op2 = context.Operand1;
            var constant = Operand.CreateConstant(BuiltInSigType.IntPtr, parameters.Count * 4);

            var eax = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX); // FIXME - need access to virtual register allocator
            var edx = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX); // FIXME - need access to virtual register allocator
            var esp = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.ESP); // FIXME - need access to virtual register allocator
            var ebp = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EBP); // FIXME - need access to virtual register allocator
            context.SetInstruction(X86.Sub, esp, constant);
            context.AppendInstruction(X86.Mov, edx, esp);

            var size = parameters.Count * 4;
            foreach (var parameter in parameters)
            {
                context.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(BuiltInSigType.IntPtr, edx, new IntPtr(size - 4)), Operand.CreateMemoryAddress(BuiltInSigType.IntPtr, ebp, new IntPtr(size + 8)));
                size -= 4;
            }

            context.AppendInstruction(X86.Mov, eax, op2);
            context.AppendInstruction(X86.Call, null, eax);
            context.AppendInstruction(X86.Add, esp, constant);
            //context.AppendInstruction(X86.Mov,result, Operand.CreateCPURegister(result.Type, GeneralPurposeRegister.EAX));
        }
Пример #3
0
        /// <summary>
        /// Adds the epilogue instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        private void AddEpilogueInstructions(Context context)
        {
            Operand ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);
            Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            Operand edx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDX);
            Operand edi = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDI);
            Operand ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX);
            Operand ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);

            context.SetInstruction(X86.Nop);

            if (SaveRegisters)
            {
                context.AppendInstruction(X86.Pop, ebx);
                context.AppendInstruction(X86.Pop, ecx);
                context.AppendInstruction(X86.Pop, edi);

                // Save EDX for int32 return values (or do not save EDX for non-int64 return values)
                if (!MethodCompiler.Method.Signature.ReturnType.IsUI8)
                {
                    context.AppendInstruction(X86.Pop, edx);
                }
            }

            if (MethodCompiler.StackLayout.StackSize != 0)
            {
                context.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstantSignedInt(TypeSystem, -MethodCompiler.StackLayout.StackSize));
            }

            context.AppendInstruction(X86.Pop, ebp);
            context.AppendInstruction(X86.Ret);
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Div"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Div(Context context)
        {
            if (context.Result.IsCPURegister && context.Result2.IsCPURegister && context.Operand1.IsCPURegister)
                if (context.Result.Register == GeneralPurposeRegister.EDX &&
                    context.Result2.Register == GeneralPurposeRegister.EAX &&
                    context.Operand1.Register == GeneralPurposeRegister.EDX &&
                    context.Operand2.Register == GeneralPurposeRegister.EAX)
                    return;

            Operand operand1 = context.Operand1;
            Operand operand2 = context.Operand2;
            Operand operand3 = context.Operand3;
            Operand result = context.Result;
            Operand result2 = context.Result2;

            Operand EAX = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
            Operand EDX = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDX);

            context.SetInstruction(X86.Mov, EDX, operand1);
            context.AppendInstruction(X86.Mov, EAX, operand2);

            if (operand3.IsCPURegister)
            {
                context.AppendInstruction2(X86.Div, EDX, EAX, EDX, EAX, operand3);
            }
            else
            {
                Operand v3 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);
                context.AppendInstruction(X86.Mov, v3, operand3);
                context.AppendInstruction2(X86.Div, EDX, EAX, EDX, EAX, v3);
            }

            context.AppendInstruction(X86.Mov, result2, EAX);
            context.AppendInstruction(X86.Mov, result, EDX);
        }
Пример #5
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            Operand result = context.Result;
            Operand eax = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4);

            context.AppendInstruction(X86.Add, eax, eax, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, GeneralPurposeRegister.ESP));
            context.AppendInstruction(X86.Mov, eax, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.U4, eax, 0));
            context.AppendInstruction(X86.Mov, result, eax);
        }
Пример #6
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            Operand esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            context.SetInstruction(X86.Mov, esp, context.Operand1);
            context.AppendInstruction(X86.Popad);
            context.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(methodCompiler.TypeSystem, 0x08));
            context.AppendInstruction(X86.Sti);
            context.AppendInstruction(X86.IRetd);
        }
Пример #7
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters)
        {
            Operand esp = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.ESP);

            context.SetInstruction(X86.Mov, esp, context.Operand1);
            context.AppendInstruction(X86.Popad);
            context.AppendInstruction(X86.Add, esp, Operand.CreateConstant(BuiltInSigType.Int32, 0x08));
            context.AppendInstruction(X86.Sti);
            context.AppendInstruction(X86.IRetd);
        }
Пример #8
0
        /// <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;

            Operand interruptMethod = Operand.CreateSymbolFromMethod(runtimeMethod);

            Operand esp = Operand.CreateCPURegister(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, Operand.CreateConstant(BuiltInSigType.SByte, 0x0));
                ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(BuiltInSigType.SByte, (byte)i));
                ctx.AppendInstruction(X86.Pushad);
                ctx.AppendInstruction(X86.Call, null, interruptMethod);
                ctx.AppendInstruction(X86.Popad);
                ctx.AppendInstruction(X86.Add, esp, Operand.CreateConstant(BuiltInSigType.Int32, 0x08));
                ctx.AppendInstruction(X86.Sti);
                ctx.AppendInstruction(X86.IRetd);

                LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), instructionSet, typeSystem);
            }
        }
Пример #9
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)
        {
            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);
        }
Пример #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 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);
        }
Пример #11
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            var dest = context.Operand1;

            var v0 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Void, SSE2Register.XMM0);
            var zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0);
            var offset16 = Operand.CreateConstant(methodCompiler.TypeSystem, 16);

            context.SetInstruction(X86.PXor, InstructionSize.Size128, v0, v0, v0);
            context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, dest, zero, v0);
            context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, dest, offset16, v0);
        }
Пример #12
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="methodCompiler">The method compiler.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            Operand result = context.Result;
            Operand methodAddress = context.Operand1;
            Operand newESP = context.Operand2;

            Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);

            context.SetInstruction(X86.Call, null, methodAddress);
            context.AppendInstruction(IRInstruction.Gen, eax);
            context.AppendInstruction(X86.Mov, result, eax);
        }
Пример #13
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters)
        {
            Operand operand1 = context.Operand1;
            Operand operand2 = context.Operand2;

            Operand edx = Operand.CreateCPURegister(operand1.Type, GeneralPurposeRegister.EDX);
            Operand eax = Operand.CreateCPURegister(operand2.Type, GeneralPurposeRegister.EAX);

            context.SetInstruction(X86.Mov, edx, operand1);
            context.AppendInstruction(X86.Mov, eax, operand2);
            context.AppendInstruction(X86.Out, null, edx, eax);
        }
Пример #14
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);
        }
Пример #15
0
 /// <summary>
 /// Replaces the intrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeSystem">The type system.</param>
 void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
 {
     Operand result = context.Result;
     Operand operand = context.Operand1;
     Operand eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
     Operand ecx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX);
     Operand reg = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);
     context.SetInstruction(X86.Mov, eax, operand);
     context.AppendInstruction(X86.Mov, ecx, methodCompiler.ConstantZero);
     context.AppendInstruction(X86.CpuId, eax, eax);
     context.AppendInstruction(X86.Mov, result, reg);
 }
Пример #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;
     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.EDX);
     context.SetInstruction(Instruction.MovInstruction, eax, operand);
     context.AppendInstruction(Instruction.XorInstruction, ecx, ecx);
     context.AppendInstruction(Instruction.CpuIdEdxInstruction);
     context.AppendInstruction(Instruction.MovInstruction, result, reg);
 }
Пример #17
0
 /// <summary>
 /// Replaces the intrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeSystem">The type system.</param>
 void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem, IList<RuntimeParameter> parameters)
 {
     Operand result = context.Result;
     Operand operand = context.Operand1;
     Operand eax = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.EAX);
     Operand ecx = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.ECX);
     Operand reg = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.EDX);
     context.SetInstruction(X86.Mov, eax, operand);
     context.AppendInstruction(X86.Xor, ecx, ecx);
     context.AppendInstruction(X86.CpuId, eax, eax);
     context.AppendInstruction(X86.Mov, result, reg);
 }
Пример #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 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);
        }
Пример #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);
        }
Пример #20
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            Operand dest = context.Operand1;
            Operand value = context.Operand2;

            Operand v1 = methodCompiler.CreateVirtualRegister(dest.Type);
            Operand v2 = methodCompiler.CreateVirtualRegister(value.Type);
            Operand memory = Operand.CreateMemoryAddress(context.InvokeMethod.Signature.Parameters[1].ParameterType, v1, 0);

            context.SetInstruction(X86.Mov, v1, dest);
            context.AppendInstruction(X86.Mov, v2, value);
            context.AppendInstruction(X86.Mov, memory, v2);
        }
Пример #21
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            var dest = context.Operand1;

            // The size will be 128 bits
            var v0 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Void, SSE2Register.XMM0);
            var memDest1 = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Void, dest, 0);
            var memDest2 = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Void, dest, 16);

            context.SetInstruction(X86.PXor, InstructionSize.Size128, v0, v0, v0);
            context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest1, v0);
            context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest2, v0);
        }
Пример #22
0
        /// <summary>
        /// Adds the prologue instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        private void AddPrologueInstructions(Context context)
        {
            Operand ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);
            Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            context.SetInstruction(X86.Push, null, ebp);
            context.AppendInstruction(X86.Mov, ebp, esp);

            if (MethodCompiler.StackSize != 0)
            {
                context.AppendInstruction(X86.Sub, esp, esp, Operand.CreateConstant(TypeSystem, -MethodCompiler.StackSize));
            }
        }
Пример #23
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            var dest = context.Operand1;
            var src = context.Operand2;

            var v0 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Void);
            var v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Void);
            var zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0);
            var offset16 = Operand.CreateConstant(methodCompiler.TypeSystem, 16);

            context.SetInstruction(X86.MovupsLoad, InstructionSize.Size128, v0, dest, zero);
            context.AppendInstruction(X86.MovupsLoad, InstructionSize.Size128, v1, dest, offset16);
            context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, null, dest, zero, v0);
            context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, null, dest, offset16, v1);
        }
Пример #24
0
        /// <summary>
        /// Adds the epilogue instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        private void AddEpilogueInstructions(Context context)
        {
            Operand ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);
            Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            context.Empty();

            if (MethodCompiler.StackSize != 0)
            {
                context.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, -MethodCompiler.StackSize));
            }

            context.AppendInstruction(X86.Pop, ebp);
            context.AppendInstruction(X86.Ret);
        }
Пример #25
0
        public static Context CreateNewBlock(this InstructionSet instructionSet, BasicBlocks basicBlocks)
        {
            Context ctx = new Context(instructionSet);

            ctx.AppendInstruction(IRInstruction.BlockStart);
            int start = ctx.Index;
            ctx.AppendInstruction(IRInstruction.BlockEnd);
            int last = ctx.Index;

            BasicBlock block = basicBlocks.CreateBlockWithAutoLabel(start, last);
            ctx.BasicBlock = block;

            ctx.GotoPrevious();

            return ctx;
        }
        private void HandleSplitAnd(Context context)
        {
            Operand r8 = Operand.CreateCPURegister(context.Operand1.Type, GeneralPurposeRegister.R8);

            context.SetInstruction(AVR32.Mov, r8, context.Operand1);
            context.AppendInstruction(AVR32.And, context.Result, r8);
        }
Пример #27
0
 /// <summary>
 /// Replaces the intrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeSystem">The type system.</param>
 void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
 {
     var result = context.Result;
     var address = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.I4);
     context.SetInstruction(IRInstruction.Move, address, Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, Multiboot0695Stage.MultibootEBX));
     context.AppendInstruction(IRInstruction.Move, result, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.I4, address, 0));
 }
Пример #28
0
        /// <summary>
        /// Replaces the intrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler)
        {
            var ctor = context.Operand1;
            var thisObject = context.Operand2;
            var result = context.Result;
            var esp = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Pointer, GeneralPurposeRegister.ESP);
            var edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.Pointer, GeneralPurposeRegister.EDX);
            var espMovment = Operand.CreateConstant(methodCompiler.TypeSystem, 4);

            context.SetInstruction(X86.Sub, esp, esp, espMovment);
            context.AppendInstruction(X86.Mov, edx, esp);
            context.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.Pointer, edx, 0), thisObject);
            context.AppendInstruction(X86.Call, null, ctor);
            context.AppendInstruction(X86.Add, esp, esp, espMovment);
            context.AppendInstruction(X86.Mov, result, thisObject);
        }
Пример #29
0
        /// <summary>
        /// Runs the specified method compiler.
        /// </summary>
        void IMethodCompilerStage.Run()
        {
            if (methodCompiler.PlugSystem != null)
                if (methodCompiler.PlugSystem.GetPlugMethod(this.methodCompiler.Method) != null)
                    return;

            List<StackOperand> locals = CollectLocalVariablesFromIL();

            // Iterate and collect locals from all blocks
            foreach (BasicBlock block in basicBlocks)
            {
                CollectLocalVariables(locals, block);
            }

            // Sort all found locals
            OrderVariables(locals, callingConvention);

            // Now we assign increasing stack offsets to each variable
            localsSize = LayoutVariables(locals, callingConvention, callingConvention.OffsetOfFirstLocal, 1);

            // Layout parameters
            LayoutParameters(methodCompiler);

            // Create a prologue instruction
            Context prologueCtx = new Context(instructionSet, FindBlock(-1)).InsertBefore();
            prologueCtx.SetInstruction(IR.Instruction.PrologueInstruction);
            prologueCtx.Label = -1;

            // Create an epilogue instruction
            Context epilogueCtx = new Context(instructionSet, FindBlock(Int32.MaxValue));
            epilogueCtx.AppendInstruction(IR.Instruction.EpilogueInstruction);
            epilogueCtx.Label = Int32.MaxValue;
        }
Пример #30
0
        /// <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);
        }
Пример #31
0
        private static void PatchInvoke(BaseMethodCompiler methodCompiler)
        {
            // check if instance is null (if so, it's a static call to the methodPointer)

            MosaField methodPointerField         = GetField(methodCompiler.Method.DeclaringType, "methodPointer");
            int       methodPointerOffset        = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField);
            Operand   methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset);

            MosaField instanceField         = GetField(methodCompiler.Method.DeclaringType, "instance");
            int       instanceOffset        = methodCompiler.TypeLayout.GetFieldOffset(instanceField);
            Operand   instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset);

            var  size       = methodCompiler.Architecture.NativeInstructionSize;
            bool withReturn = (methodCompiler.Method.Signature.ReturnType != null);

            Context b0 = new Context(CreateMethodStructure(methodCompiler, false));
            Context b1 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            Context b2 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            Context b3 = new Context(methodCompiler.BasicBlocks.CreateBlock());

            Operand[] vrs = new Operand[methodCompiler.Parameters.Length];

            for (int i = 0; i < methodCompiler.Parameters.Length; i++)
            {
                vrs[i] = methodCompiler.VirtualRegisters.Allocate(methodCompiler.Parameters[i].Type);
                b0.AppendInstruction(IRInstruction.Move, vrs[i], methodCompiler.Parameters[i]);
            }

            Operand thisOperand = vrs[0];

            Operand opMethod   = methodCompiler.VirtualRegisters.Allocate(methodCompiler.TypeSystem.BuiltIn.U4);
            Operand opInstance = methodCompiler.VirtualRegisters.Allocate(thisOperand.Type);
            Operand opCompare  = methodCompiler.VirtualRegisters.Allocate(methodCompiler.TypeSystem.BuiltIn.I4);

            Operand opReturn = withReturn ? methodCompiler.VirtualRegisters.Allocate(methodCompiler.Method.Signature.ReturnType) : null;
            Operand c0       = Operand.CreateConstant(methodCompiler.TypeSystem, 0);

            b0.AppendInstruction(IRInstruction.Load, size, opMethod, thisOperand, methodPointerOffsetOperand);
            b0.AppendInstruction(IRInstruction.Load, size, opInstance, thisOperand, instanceOffsetOperand);
            b0.AppendInstruction(IRInstruction.IntegerCompare, ConditionCode.Equal, opCompare, opInstance, c0);
            b0.AppendInstruction(IRInstruction.IntegerCompareBranch, ConditionCode.Equal, null, opCompare, c0);
            b0.AddBranchTarget(b2.Block);
            b0.AppendInstruction(IRInstruction.Jmp, b1.Block);

            // no instance
            b1.AppendInstruction(IRInstruction.Call, opReturn, opMethod);
            b1.InvokeMethod = methodCompiler.Method;
            for (int i = 1; i < methodCompiler.Parameters.Length; i++)
            {
                b1.AddOperand(vrs[i]);
            }
            if (withReturn)
            {
                b1.SetResult(0, opReturn);
            }
            b1.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // instance
            b2.AppendInstruction(IRInstruction.Call, opReturn, opMethod);
            b2.InvokeMethod = methodCompiler.Method;
            b2.AddOperand(opInstance);
            for (int i = 1; i < methodCompiler.Parameters.Length; i++)
            {
                b2.AddOperand(vrs[i]);
            }
            if (withReturn)
            {
                b2.SetResult(0, opReturn);
            }
            b2.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // return
            b3.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock);
            if (withReturn)
            {
                b3.SetOperand(0, opReturn);
            }
        }
Пример #32
0
        private static void PatchInvoke(MethodCompiler methodCompiler)
        {
            // check if instance is null (if so, it's a static call to the methodPointer)

            var loadInstruction    = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Load32 : IRInstruction.Load64;
            var compareInstruction = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Compare32x32 : IRInstruction.Compare64x64;
            var branchInstruction  = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Branch32 : IRInstruction.Branch64;
            var nativeIntegerType  = methodCompiler.Architecture.Is32BitPlatform ? methodCompiler.TypeSystem.BuiltIn.U4 : methodCompiler.TypeSystem.BuiltIn.U8;

            var methodPointerField         = GetField(methodCompiler.Method.DeclaringType, "methodPointer");
            int methodPointerOffset        = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField);
            var methodPointerOffsetOperand = methodCompiler.CreateConstant(methodPointerOffset);

            var instanceField         = GetField(methodCompiler.Method.DeclaringType, "instance");
            int instanceOffset        = methodCompiler.TypeLayout.GetFieldOffset(instanceField);
            var instanceOffsetOperand = methodCompiler.CreateConstant(instanceOffset);

            var  size       = methodCompiler.Architecture.NativeInstructionSize;
            bool withReturn = (methodCompiler.Method.Signature.ReturnType == null) ? false : !methodCompiler.Method.Signature.ReturnType.IsVoid;

            var b0 = new Context(CreateMethodStructure(methodCompiler));
            var b1 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            var b2 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            var b3 = new Context(methodCompiler.BasicBlocks.CreateBlock());

            var vrs = new Operand[methodCompiler.Parameters.Length];

            for (int i = 0; i < methodCompiler.Parameters.Length; i++)
            {
                var type = methodCompiler.Parameters[i].Type;

                if (!MosaTypeLayout.CanFitInRegister(type))
                {
                    b0.AppendInstruction(IRInstruction.LoadParamCompound, vrs[i], methodCompiler.Parameters[i]);
                    b0.MosaType = type;
                }
                else
                {
                    vrs[i] = methodCompiler.VirtualRegisters.Allocate(methodCompiler.Parameters[i].Type);

                    var paramLoadInstruction = BaseMethodCompilerStage.GetLoadParameterInstruction(vrs[i].Type, methodCompiler.Architecture.Is32BitPlatform);

                    b0.AppendInstruction(paramLoadInstruction, vrs[i], methodCompiler.Parameters[i]);
                    b0.MosaType = type;
                }
            }

            var thisOperand = vrs[0];

            var opMethod   = methodCompiler.VirtualRegisters.Allocate(nativeIntegerType);
            var opInstance = methodCompiler.VirtualRegisters.Allocate(thisOperand.Type);
            var opCompare  = methodCompiler.VirtualRegisters.Allocate(nativeIntegerType);

            var opReturn = withReturn ? methodCompiler.AllocateVirtualRegisterOrStackSlot(methodCompiler.Method.Signature.ReturnType) : null;

            b0.AppendInstruction(loadInstruction, opMethod, thisOperand, methodPointerOffsetOperand);
            b0.AppendInstruction(loadInstruction, opInstance, thisOperand, instanceOffsetOperand);
            b0.AppendInstruction(compareInstruction, ConditionCode.Equal, opCompare, opInstance, methodCompiler.ConstantZero);
            b0.AppendInstruction(branchInstruction, ConditionCode.Equal, null, opCompare, methodCompiler.ConstantZero, b2.Block);

            //b0.AddBranchTarget(b2.Block);
            b0.AppendInstruction(IRInstruction.Jmp, b1.Block);

            var operands = new List <Operand>(methodCompiler.Parameters.Length + 1);

            for (int i = 1; i < methodCompiler.Parameters.Length; i++)
            {
                operands.Add(vrs[i]);
            }

            var result = withReturn ? opReturn : null;

            // no instance
            b1.AppendInstruction(IRInstruction.CallDynamic, result, opMethod, operands);
            b1.InvokeMethod = methodCompiler.Method;
            b1.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // instance
            b2.AppendInstruction(IRInstruction.CallDynamic, result, opMethod, opInstance, operands);
            b2.InvokeMethod = methodCompiler.Method;
            b2.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // return
            if (opReturn != null)
            {
                var setReturn = BaseMethodCompilerStage.GetSetReturnInstruction(opReturn.Type, methodCompiler.Architecture.Is32BitPlatform);
                b3.AppendInstruction(setReturn, null, opReturn);
            }

            b3.AppendInstruction(IRInstruction.Jmp, methodCompiler.BasicBlocks.EpilogueBlock);
        }