예제 #1
0
        private Argument_v1 ParseReturn()
        {
            string w = GetNextWord();

            if (w == "void")
            {
                return(null);
            }
            Console.WriteLine(w);
            RegisterStorage reg;

            if (arch.TryGetRegister(w, out reg))
            {
                return(new Argument_v1(
                           reg.Name,
                           null,
                           new Register_v1(reg.Name),
                           true));
            }
            if (w.Contains("_"))
            {
                return(ParseRegisterSequenceWithUnderscore(w));
            }
            throw new NotImplementedException();
        }
예제 #2
0
        /// <summary>
        /// Computes the trashed registers for all the procedures in the
        /// SCC group.
        /// </summary>
        /// <remarks>
        /// To deal with recursive functions -- including deeply nested
        /// mutually recursive functions, we first compute what registers
        /// are trashed when recursion is disregarded. If there are no
        /// recursive calls, we are done and leave early.
        /// If there are recursive calls, we make one unwarranted but
        /// highly likely assumption: for each involved procedure,
        /// the stack pointer will have the same value in the exit block
        /// after traversing both non-recursive and recursive paths
        /// of the program.
        /// </remarks>
        public void Compute()
        {
            CreateState();
            this.propagateToCallers = false;

            Block block;

            while (worklist.GetWorkItem(out block))
            {
                arch = block.Procedure.Architecture;
                ProcessBlock(block);
            }

            if (!selfRecursiveCalls)
            {
                return;
            }

            // We make a big, but very reasonable assumption here: if a procedure
            // has a recursive branch and a non-recursive branch, the stack pointer
            // will have the same value at the point where the branches join.
            // It certainly possible for an assembly language programmer to construct
            // a program where procedures deliberately put the stack in imbalance
            // after calling a procedure, but using such a procedure is very difficult
            // to do as you must somehow understand how the procedure changes the
            // stack pointers depending on ... anything!
            // It seems safe to assume that all branches leading to the exit block
            // have the same stack pointer value.

            var savedSps = CollectStackPointers(flow, arch.StackRegister);
            //$REVIEW: Ew. This hardwires a dependency on x87 in common code.
            // We need a general mechanism for dealing with "stack pointers"
            // that abstracts over platform integer stack pointers and the
            // x87 FPU stack pointer.
            var savedTops = new Dictionary <Procedure, int?>();

            if (arch.TryGetRegister("Top", out var top))
            {
                savedTops = CollectStackPointers(flow, top);
            }

            CreateState();

            ApplyStackPointers(savedSps, flow);
            ApplyStackPointers(savedTops, flow);

            BypassRegisterOffsets(savedSps, arch.StackRegister);

            this.propagateToCallers = true;
            while (worklist.GetWorkItem(out block))
            {
                ProcessBlock(block);
            }
        }