示例#1
0
        /// <summary>
        /// Performs a stack layout of all local variables in the list.
        /// </summary>
        /// <param name="locals">The enumerable holding all locals.</param>
        /// <param name="callingConvention">The cc.</param>
        /// <param name="offsetOfFirst">Specifies the offset of the first stack operand in the list.</param>
        /// <param name="direction">The direction.</param>
        /// <returns></returns>
        private static int LayoutVariables(List<Operand> locals, ICallingConvention callingConvention, int offsetOfFirst, int direction)
        {
            int offset = offsetOfFirst;

            foreach (Operand operand in locals)
            {
                // Does the offset fit the alignment requirement?
                int alignment;
                int size;
                int padding;
                int thisOffset;

                callingConvention.GetStackRequirements(operand, out size, out alignment);
                if (direction == 1)
                {
                    padding = (offset % alignment);
                    offset -= (padding + size);
                    thisOffset = offset;
                }
                else
                {
                    padding = (offset % alignment);
                    if (padding != 0)
                        padding = alignment - padding;

                    thisOffset = offset;
                    offset += (padding + size);
                }

                operand.Offset = new IntPtr(thisOffset);
            }

            return offset;
        }
示例#2
0
        /// <summary>
        /// Processes a method call instruction.
        /// </summary>
        /// <param name="ctx">The transformation context.</param>
        private void HandleInvokeInstruction(Context ctx)
        {
            ICallingConvention cc = Architecture.GetCallingConvention(ctx.InvokeTarget.Signature.CallingConvention);

            Debug.Assert(null != cc, @"Failed to retrieve the calling convention.");
            cc.Expand(ctx);
        }
示例#3
0
 public FunctionCall(Label function, Variable result = null,
                     IList <Variable> args           = null, ICallingConvention callingConvention = null)
 {
     Function          = function;
     Arguments         = args ?? new List <Variable>();
     Result            = result;
     CallingConvention = callingConvention;
 }
示例#4
0
        /// <summary>
        /// Retrieves a calling convention object for the requested calling convention.
        /// </summary>
        /// <returns>
        /// An instance of <see cref="ICallingConvention"/>.
        /// </returns>
        public override ICallingConvention GetCallingConvention()
        {
            if (callingConvention == null)
            {
                callingConvention = new DefaultCallingConvention(this);
            }

            return(callingConvention);
        }
示例#5
0
 /// <summary>
 /// Sorts all local variables by their size requirements.
 /// </summary>
 /// <param name="locals">Holds all local variables to sort..</param>
 /// <param name="cc">The calling convention used to determine size and alignment requirements.</param>
 private static void OrderVariables(List <StackOperand> locals, ICallingConvention cc)
 {
     /* Sort the list by stack size requirements - this moves equally sized operands closer together,
      * in the hope that this reduces padding on the stack to enforce HW alignment requirements.
      */
     locals.Sort(delegate(StackOperand op1, StackOperand op2) {
         int size1, size2, alignment;
         cc.GetStackRequirements(op1, out size1, out alignment);
         cc.GetStackRequirements(op2, out size2, out alignment);
         return(size2 - size1);
     });
 }
示例#6
0
        /// <summary>
        /// Lays out all parameters of the method.
        /// </summary>
        /// <param name="compiler">The method compiler providing the parameters.</param>
        /// <param name="cc">The calling convention used to invoke the method, which controls parameter layout.</param>
        private void LayoutParameters(IMethodCompiler compiler, ICallingConvention cc)
        {
            List <StackOperand> paramOps = new List <StackOperand> ();

            for (int i = 0; i < compiler.Method.Parameters.Count; i++)
            {
                paramOps.Add((StackOperand)compiler.GetParameterOperand(i));
            }

            LayoutVariables(paramOps, cc, cc.OffsetOfFirstParameter, -1);

            if (TRACING.TraceInfo)
            {
                LogOperands(paramOps);
            }
        }
示例#7
0
        /// <summary>
        /// Setups the specified compiler.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        public void Setup(IMethodCompiler compiler)
        {
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }

            methodCompiler    = compiler;
            InstructionSet    = compiler.InstructionSet;
            basicBlocks       = compiler.BasicBlocks;
            architecture      = compiler.Architecture;
            typeModule        = compiler.Method.Module;
            typeSystem        = compiler.TypeSystem;
            typeLayout        = compiler.TypeLayout;
            callingConvention = architecture.GetCallingConvention();

            architecture.GetTypeRequirements(BuiltInSigType.IntPtr, out nativePointerSize, out nativePointerAlignment);
        }
示例#8
0
        /// <summary>
        /// Runs the specified method compiler.
        /// </summary>
        public void Run()
        {
            // Allocate a list of locals
            List <StackOperand> locals = new List <StackOperand> ();

            // Retrieve the calling convention of the method
            ICallingConvention cc = Architecture.GetCallingConvention(MethodCompiler.Method.Signature.CallingConvention);

            Debug.Assert(null != cc, "Failed to retrieve the calling convention of the method.");

            // Iterate all Blocks and collect locals From all Blocks
            foreach (BasicBlock block in BasicBlocks)
            {
                CollectLocalVariables(locals, block);
            }

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

            // Now we assign increasing stack offsets to each variable
            _localsSize = LayoutVariables(locals, cc, cc.OffsetOfFirstLocal, 1);
            if (TRACING.TraceInfo == true)
            {
                Trace.WriteLine(String.Format("Stack layout for method {0}", MethodCompiler.Method));
                LogOperands(locals);
            }

            // Layout parameters
            LayoutParameters(MethodCompiler, cc);

            // Create a prologue instruction
            Context prologueCtx = new Context(InstructionSet, FindBlock(-1)).InsertBefore();

            prologueCtx.SetInstruction(IR.Instruction.PrologueInstruction);
            prologueCtx.Other = _localsSize;
            prologueCtx.Label = -1;

            // Create an epilogue instruction
            Context epilogueCtx = new Context(InstructionSet, FindBlock(Int32.MaxValue));

            epilogueCtx.AppendInstruction(IR.Instruction.EpilogueInstruction);
            epilogueCtx.Other = _localsSize;
            epilogueCtx.Label = Int32.MaxValue;
        }
示例#9
0
        /// <summary>
        /// Visitation function for <see cref="IR.IIRVisitor.ReturnInstruction"/> instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IR.IIRVisitor.ReturnInstruction(Context ctx)
        {
            Operand op = ctx.Operand1;

            if (op != null)
            {
                ICallingConvention cc = Architecture.GetCallingConvention(MethodCompiler.Method.Signature.CallingConvention);
                cc.MoveReturnValue(ctx, op);
                ctx.AppendInstruction(CPUx86.Instruction.JmpInstruction);
                ctx.SetBranch(Int32.MaxValue);
            }


            else
            {
                ctx.SetInstruction(CPUx86.Instruction.JmpInstruction);
                ctx.SetBranch(Int32.MaxValue);
            }
        }
示例#10
0
        /// <summary>
        /// Performs a stack layout of all local variables in the list.
        /// </summary>
        /// <param name="locals">The enumerable holding all locals.</param>
        /// <param name="cc">The cc.</param>
        /// <param name="offsetOfFirst">Specifies the offset of the first stack operand in the list.</param>
        /// <param name="direction">The direction.</param>
        /// <returns></returns>
        private static int LayoutVariables(IEnumerable <StackOperand> locals, ICallingConvention cc, int offsetOfFirst, int direction)
        {
            int offset = offsetOfFirst;

            foreach (StackOperand lvo in locals)
            {
                // Does the offset fit the alignment requirement?
                int alignment;
                int size;
                int padding;
                int thisOffset;

                cc.GetStackRequirements(lvo, out size, out alignment);
                if (1 == direction)
                {
                    padding    = (offset % alignment);
                    offset    -= (padding + size);
                    thisOffset = offset;
                }
                else
                {
                    padding = (offset % alignment);
                    if (0 != padding)
                    {
                        padding = alignment - padding;
                    }

                    thisOffset = offset;
                    offset    += (padding + size);
                }

                lvo.Offset = new IntPtr(thisOffset);
            }

            return(offset);
        }
示例#11
0
 /// <summary>
 /// Sorts all local variables by their size requirements.
 /// </summary>
 /// <param name="locals">Holds all local variables to sort..</param>
 /// <param name="callingConvention">The calling convention used to determine size and alignment requirements.</param>
 private static void OrderVariables(List<Operand> locals, ICallingConvention callingConvention)
 {
     // Sort the list by stack size requirements - this moves equally sized operands closer together,
     // in the hope that this reduces padding on the stack to enforce HW alignment requirements.
     locals.Sort(delegate(Operand op1, Operand op2)
     {
         int size1, size2, alignment;
         callingConvention.GetStackRequirements(op1, out size1, out alignment);
         callingConvention.GetStackRequirements(op2, out size2, out alignment);
         return size2 - size1;
     });
 }
        /// <summary>
        /// Setups the specified compiler.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        public void Setup(IMethodCompiler compiler)
        {
            if (compiler == null)
                throw new ArgumentNullException(@"compiler");

            methodCompiler = compiler;
            instructionSet = compiler.InstructionSet;
            basicBlocks = compiler.BasicBlocks;
            architecture = compiler.Architecture;
            typeModule = compiler.Method.Module;
            typeSystem = compiler.TypeSystem;
            typeLayout = compiler.TypeLayout;
            callingConvention = architecture.GetCallingConvention();

            architecture.GetTypeRequirements(BuiltInSigType.IntPtr, out nativePointerSize, out nativePointerAlignment);
        }
示例#13
0
        /// <summary>
        /// Performs a stack layout of all local variables in the list.
        /// </summary>
        /// <param name="locals">The enumerable holding all locals.</param>
        /// <param name="cc">The cc.</param>
        /// <param name="offsetOfFirst">Specifies the offset of the first stack operand in the list.</param>
        /// <param name="direction">The direction.</param>
        /// <returns></returns>
        private static int LayoutVariables(IEnumerable<StackOperand> locals, ICallingConvention cc, int offsetOfFirst, int direction)
        {
            int offset = offsetOfFirst;

            foreach (StackOperand lvo in locals)
            {
                // Does the offset fit the alignment requirement?
                int alignment;
                int size;
                int padding;
                int thisOffset;

                cc.GetStackRequirements(lvo, out size, out alignment);
                if (1 == direction)
                {
                    padding = (offset % alignment);
                    offset -= (padding + size);
                    thisOffset = offset;
                }
                else
                {
                    padding = (offset % alignment);
                    if (0 != padding)
                        padding = alignment - padding;

                    thisOffset = offset;
                    offset += (padding + size);
                }

                lvo.Offset = new IntPtr(thisOffset);
            }

            return offset;
        }
        /// <summary>
        /// Lays out all parameters of the method.
        /// </summary>
        /// <param name="compiler">The method compiler providing the parameters.</param>
        /// <param name="cc">The calling convention used to invoke the method, which controls parameter layout.</param>
        private void LayoutParameters(IMethodCompiler compiler, ICallingConvention cc)
        {
            List<StackOperand> paramOps = new List<StackOperand>();

            int offset = 0;
            if (compiler.Method.Signature.HasThis || compiler.Method.Signature.HasExplicitThis)
                ++offset;
            for (int i = 0; i < compiler.Method.Parameters.Count + offset; ++i)
                paramOps.Add((StackOperand)compiler.GetParameterOperand(i));

            /*if (compiler.Method.Signature.HasThis || compiler.Method.Signature.HasExplicitThis)
                LayoutVariables(paramOps, cc, cc.OffsetOfFirstParameter + 4, -1);
            else*/
                LayoutVariables(paramOps, cc, cc.OffsetOfFirstParameter, -1);

            if (TRACING.TraceInfo)
                LogOperands(paramOps);
        }
示例#15
0
 public Context(ICallingConvention callingConvention)
 {
     CallingConvention = callingConvention;
     Registers         = new RegisterContainer(callingConvention.GetRegisters());
     VariableAccounter = new VariableAccounter();
 }
示例#16
0
        /// <summary>
        /// Lays out all parameters of the method.
        /// </summary>
        /// <param name="compiler">The method compiler providing the parameters.</param>
        /// <param name="cc">The calling convention used to invoke the method, which controls parameter layout.</param>
        private void LayoutParameters(IMethodCompiler compiler, ICallingConvention cc)
        {
            List<StackOperand> paramOps = new List<StackOperand> ();

            for (int i = 0; i < compiler.Method.Parameters.Count; i++)
                paramOps.Add ((StackOperand)compiler.GetParameterOperand (i));

            LayoutVariables (paramOps, cc, cc.OffsetOfFirstParameter, -1);

            if (TRACING.TraceInfo)
                LogOperands (paramOps);
        }
示例#17
0
        /// <summary>
        /// Retrieves a calling convention object for the requested calling convention.
        /// </summary>
        /// <returns>
        /// An instance of <see cref="ICallingConvention"/>.
        /// </returns>
        public override ICallingConvention GetCallingConvention()
        {
            // TODO
            if (callingConvention == null)
                callingConvention = null; // new DefaultCallingConvention(this);

            return callingConvention;
        }
示例#18
0
        /// <summary>
        /// Retrieves a calling convention object for the requested calling convention.
        /// </summary>
        /// <param name="typeLayout">The type layout.</param>
        /// <returns>
        /// An instance of <see cref="ICallingConvention"/>.
        /// </returns>
        public override ICallingConvention GetCallingConvention(ITypeLayout typeLayout)
        {
            if (callingConvention == null)
                callingConvention = new DefaultCallingConvention(this, typeLayout);

            return callingConvention;
        }