Exemple #1
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            Operand result = context.Result;

            RegisterOperand tmp = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EDX);
            MemoryOperand operand = new MemoryOperand(context.Operand1.Type, GeneralPurposeRegister.EDX, new System.IntPtr(0));

            context.SetInstruction(CPUx86.Instruction.MovInstruction, tmp, context.Operand1);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, operand);
        }
Exemple #2
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            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(CPUx86.Instruction.MovInstruction, edx, dest);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, value);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, memory, eax);
        }
Exemple #3
0
        /// <summary>
        /// Replaces the instrinsic call site
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeSystem">The type system.</param>
        public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
        {
            MemoryOperand operand = new MemoryOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX, new System.IntPtr(0));
            context.SetInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX), context.Operand1);
            context.AppendInstruction(CPUx86.Instruction.LgdtInstruction, null, operand);

            RegisterOperand ax = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), GeneralPurposeRegister.EAX);
            RegisterOperand ds = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.DS);
            RegisterOperand es = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.ES);
            RegisterOperand fs = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.FS);
            RegisterOperand gs = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.GS);
            RegisterOperand ss = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I2), SegmentRegister.SS);

            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ax, new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), (int)0x00000010));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ds, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, es, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, fs, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, gs, ax);
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, ss, ax);
            context.AppendInstruction(CPUx86.Instruction.FarJmpInstruction);
            context.AppendInstruction(CPUx86.Instruction.NopInstruction);
            context.Previous.SetBranch(context.Offset);
        }
        private static void SplitFromNonConstantOperand(Operand operand, out Operand operandLow, out Operand operandHigh)
        {
            SigType HighType = (operand.Type.Type == CilElementType.I8) ? new SigType(CilElementType.I4) : new SigType(CilElementType.U4);
            SigType U4 = new SigType(CilElementType.U4);

            // No, could be a member or a plain memory operand
            MemberOperand memberOperand = operand as MemberOperand;
            if (memberOperand != null)
            {
                // We need to keep the member reference, otherwise the linker can't fixup
                // the member address.
                operandLow = new MemberOperand(memberOperand.Member, U4, memberOperand.Offset);
                operandHigh = new MemberOperand(memberOperand.Member, HighType, new IntPtr(memberOperand.Offset.ToInt64() + 4));
            }
            else
            {
                // Plain memory, we can handle it here
                MemoryOperand memoryOperand = (MemoryOperand)operand;
                operandLow = new MemoryOperand(U4, memoryOperand.Base, memoryOperand.Offset);
                operandHigh = new MemoryOperand(HighType, memoryOperand.Base, new IntPtr(memoryOperand.Offset.ToInt64() + 4));
            }
        }
Exemple #5
0
        /// <summary>
        /// Emits the displacement operand.
        /// </summary>
        /// <param name="displacement">The displacement operand.</param>
        private void EmitDisplacement(MemoryOperand displacement)
        {
            byte[] disp;

            MemberOperand member = displacement as MemberOperand;
            LabelOperand label = displacement as LabelOperand;
            if (null != label)
            {
                int pos = (int)(_codeStream.Position - _codeStreamBasePosition);
                disp = LittleEndianBitConverter.GetBytes ((uint)_linker.Link (LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method, pos, 0, label.Name, IntPtr.Zero));
            }
            else if (null != member)
            {
                int pos = (int)(_codeStream.Position - _codeStreamBasePosition);
                disp = LittleEndianBitConverter.GetBytes ((uint)_linker.Link (LinkType.AbsoluteAddress | LinkType.I4, _compiler.Method, pos, 0, member.Member, member.Offset));
            }
            else
            {
                disp = LittleEndianBitConverter.GetBytes (displacement.Offset.ToInt32 ());
            }

            _codeStream.Write (disp, 0, disp.Length);
        }
Exemple #6
0
        /// <summary>
        /// Calculates the value of the modR/M byte and SIB bytes.
        /// </summary>
        /// <param name="regField">The modR/M regfield value.</param>
        /// <param name="op1">The destination operand.</param>
        /// <param name="op2">The source operand.</param>
        /// <param name="sib">A potential SIB byte to emit.</param>
        /// <param name="displacement">An immediate displacement to emit.</param>
        /// <returns>The value of the modR/M byte.</returns>
        private static byte? CalculateModRM(byte? regField, Operand op1, Operand op2, out byte? sib, out MemoryOperand displacement)
        {
            byte? modRM = null;

            displacement = null;

            // FIXME: Handle the SIB byte
            sib = null;

            RegisterOperand rop1 = op1 as RegisterOperand, rop2 = op2 as RegisterOperand;
            MemoryOperand mop1 = op1 as MemoryOperand, mop2 = op2 as MemoryOperand;

            // Normalize the operand order
            if (null == rop1 && null != rop2)
            {
                // Swap the memory operands
                rop1 = rop2;
                rop2 = null;
                mop2 = mop1;
                mop1 = null;
            }

            if (null != regField)
                modRM = (byte)(regField.Value << 3);

            if (null != rop1 && null != rop2)
            {
                // mod = 11b, reg = rop1, r/m = rop2
                modRM = (byte)((3 << 6) | (rop1.Register.RegisterCode << 3) | rop2.Register.RegisterCode);
            }
            // Check for register/memory combinations
            else if (null != mop2 && null != mop2.Base)
            {
                // mod = 10b, reg = rop1, r/m = mop2
                modRM = (byte)(modRM.GetValueOrDefault () | (2 << 6) | (byte)mop2.Base.RegisterCode);
                if (null != rop1)
                {
                    modRM |= (byte)(rop1.Register.RegisterCode << 3);
                }
                displacement = mop2;
            }
            else if (null != mop2)
            {
                // mod = 10b, r/m = mop1, reg = rop2
                modRM = (byte)(modRM.GetValueOrDefault () | 5);
                if (null != rop1)
                {
                    modRM |= (byte)(rop1.Register.RegisterCode << 3);
                }
                displacement = mop2;
            }
            else if (null != mop1 && null != mop1.Base)
            {
                // mod = 10b, r/m = mop1, reg = rop2
                modRM = (byte)(modRM.GetValueOrDefault () | (2 << 6) | mop1.Base.RegisterCode);
                if (null != rop2)
                {
                    modRM |= (byte)(rop2.Register.RegisterCode << 3);
                }
                displacement = mop1;
            }
            else if (null != mop1)
            {
                // mod = 10b, r/m = mop1, reg = rop2
                modRM = (byte)(modRM.GetValueOrDefault () | 5);
                if (null != rop2)
                {
                    modRM |= (byte)(rop2.Register.RegisterCode << 3);
                }
                displacement = mop1;
            }
            else if (null != rop1)
            {
                modRM = (byte)(modRM.GetValueOrDefault () | (3 << 6) | rop1.Register.RegisterCode);
            }

            return modRM;
        }
Exemple #7
0
        /// <summary>
        /// Compares with the given operand for equality.
        /// </summary>
        /// <param name="other">The other operand to compare with.</param>
        /// <returns>The return value is true if the operands are equal; false if not.</returns>
        public override bool Equals(Operand other)
        {
            MemoryOperand mop = other as MemoryOperand;

            return(null != mop && mop.Type == Type && mop.Offset == Offset && mop.Base == Base);
        }
        /// <summary>
        /// Visitation function for ThrowInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IR.IIRVisitor.ThrowInstruction(Context context)
        {
            int pointOfThrow = 4;
            int exceptionObject = 12;
            SigType u4 = new SigType(CilElementType.U4);

            RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Platforms.x86.ExceptionEngine, Mosa.Platforms.x86");
            RuntimeMethod runtimeMethod = runtimeType.FindMethod(@"ThrowException");
            SymbolOperand method = SymbolOperand.FromMethod(runtimeMethod);

            //UNUSED:
            //Operand callTarget = context.Result;

            MemoryOperand pointOfThrowOperand = new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(pointOfThrow));
            MemoryOperand exceptionObjectOperand = new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(exceptionObject));

            RegisterOperand esp = new RegisterOperand(u4, GeneralPurposeRegister.ESP);
            RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX);

            // Save current stack
            context.SetInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.ESP));
            // Save point of call
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, pointOfThrowOperand);
            // Pass thrown exception
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, exceptionObjectOperand);
            // Save registers
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.EBP));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.EDI));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.ESI));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.EBX));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.EDX));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.ECX));
            context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new RegisterOperand(u4, GeneralPurposeRegister.EAX));

            // Pass them to the exception handling routine as parameters
            context.AppendInstruction(CPUx86.Instruction.SubInstruction, esp, new ConstantOperand(esp.Type, 40));
            context.AppendInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(u4, GeneralPurposeRegister.EDX), esp);

            for (int i = 0; i < 10; ++i)
            {
                context.AppendInstruction(CPUx86.Instruction.PopInstruction, eax);
                context.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(u4, GeneralPurposeRegister.EDX, new IntPtr(i * 4)), eax);
            }

            // Call exception handling
            context.AppendInstruction(CPUx86.Instruction.CallInstruction, null, method);

            // Compile exception handling if necessary
            if (!exceptionHandlingCompiled)
            {
                //FIXME
                //this.methodCompiler.Scheduler.ScheduleTypeForCompilation(typeSystem.GetType(@"Mosa.Platforms.x86.RegisterContext, Mosa.Platforms.x86"));
                //this.methodCompiler.Scheduler.ScheduleTypeForCompilation(typeSystem.GetType(@"Mosa.Platforms.x86.ExceptionEngine, Mosa.Platforms.x86"));
                //(this.typeLayout as TypeLayoutStage).CreateSequentialLayout(typeSystem.GetType(@"Mosa.Platforms.x86.RegisterContext, Mosa.Platforms.x86"));
                //(this.typeLayout as TypeLayoutStage).CreateSequentialLayout(typeSystem.GetType(@"Mosa.Platforms.x86.ExceptionEngine, Mosa.Platforms.x86"));
                //(this.typeLayout as TypeLayoutStage).BuildMethodTable(typeSystem.GetType(@"Mosa.Platforms.x86.RegisterContext, Mosa.Platforms.x86"));
                //(this.typeLayout as TypeLayoutStage).BuildMethodTable(typeSystem.GetType(@"Mosa.Platforms.x86.ExceptionEngine, Mosa.Platforms.x86"));
                exceptionHandlingCompiled = true;
            }
        }
Exemple #9
0
 /// <summary>
 /// Replaces the instrinsic call site
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeSystem">The type system.</param>
 public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem)
 {
     MemoryOperand operand = new MemoryOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX, new System.IntPtr(0));
     context.SetInstruction(CPUx86.Instruction.MovInstruction, new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EAX), context.Operand1);
     context.AppendInstruction(CPUx86.Instruction.LidtInstruction, null, operand);
 }