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(); }
/// <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); } }