private FuncBuilder(Namespace ns, FuncBuilderHints builderHints, ActionOnFuncBuilder action) { Instance=this; this.namespaceAndNextIndex=new NamespaceAndNextIndex(ns, 0); this.BuilderHints=builderHints; var pt=builderHints.PassTraits; this.Scratch0=pt.Scratch0; this.Scratch1=pt.Scratch1; var emitter=CodeGenerator.Emitter; var passTraits=BuilderHints.PassTraits; var preserveLr=passTraits.PreserveLinkRegister; var regsToPreserve=passTraits.RegisterMask&0xf0; emitter.EmitIfNecessary(Format14OpCode.PUSH, preserveLr, (byte)regsToPreserve); if(preserveLr) { StackPointer+=-4; } while(regsToPreserve!=0) { StackPointer+=-4; regsToPreserve&=(regsToPreserve-1); } this.EndOfVariableRegion=StackPointer; var avo=passTraits.AllocatedVariableOffset; emitter.EmitIfNecessary(Format13OpCode.ADDSP, avo); StackPointer+=avo; this.TheExitLabel=DeclareLabel("leave"); action(this); TheExitLabel.Mark(); StackPointer+=-avo; emitter.EmitIfNecessary(Format13OpCode.ADDSP, -avo); regsToPreserve=passTraits.RegisterMask&0xf0; emitter.EmitIfNecessary(Format14OpCode.POP, false, (byte)regsToPreserve); Register bxRegister; if(passTraits.PreserveLinkRegister) { bxRegister=new LowRegister(1); emitter.EmitIfNecessary(Format14OpCode.POP, false, 1<<1); } else { bxRegister=Register.LR; } emitter.Emit(Format5OpCode.BX, null, bxRegister); if(inflightUtterances.Count>0) { var allUtterances=""; foreach(string utterance in inflightUtterances.Values) { if(allUtterances.Length>0) { allUtterances+=","; } allUtterances+=utterance; } throw new Exception(allUtterances); } }
public Namespace(Namespace inner, int index, string humanReadable) { this.Inner=inner; this.Index=index; this.humanReadable=humanReadable; if(inner==null) { this.Depth=0; this.cachedHashCode=index; } else { this.Depth=inner.Depth+1; this.cachedHashCode=(inner.cachedHashCode*397)^index; } }
private AllocatorStats Recurse(Namespace ns) { var result=(AllocatorStats)memoizedInfo[ns]; if(result!=null) { return result; } var innerStats=ns.Inner==null ? new AllocatorStats(initialRegisterMask, 0) : Recurse(ns.Inner); var variableNames=(ArrayList)nsToLiveVariables[ns]; if(variableNames==null) { result=innerStats; } else { var rast=new RegisterAndStackAllocator(innerStats, variableNames.Count, (int)nsToNumRegisters[ns]); foreach(TerminalName variableName in variableNames) { var newRepresentation=rast.AllocateRepresentation(variableName); variableNameToRepresentation.Add(variableName, newRepresentation); } result=rast.MakeNewStats(); } memoizedInfo.Add(ns, result); return result; }
private Hashtable EmitStaticFunctions(out bool runAgain) { runAgain=false; var hintsForNextTime=new Hashtable(); //Hashtable<string,FuncBuilderHints> for(var i=0; i<funcDefinitions.Count; ++i) { emitter.AlignToWord(); var definition=(FuncDefinition)funcDefinitions[i]; var declaration=definition.Declaration; var name=declaration.Name; var fbHints=(FuncBuilderHints)GeneratorHints.FuncNameToFuncBuilderHints[name] ?? new FuncBuilderHints(); var ns=new Namespace(this.TopNamespace, i, name); declaration.EntryPoint.Mark(); bool fbRunAgain; var newFbHints=FuncBuilder.EmitFunction(ns, fbHints, definition.Body, out fbRunAgain); hintsForNextTime.Add(name, newFbHints); runAgain|=fbRunAgain; } return hintsForNextTime; }
public NamespaceAndNextIndex Nest(string newName) { var inner=new Namespace(Namespace, NextIndex, newName); return new NamespaceAndNextIndex(inner, 0); }
public NamespaceAndNextIndex(Namespace ns, int nextIndex) { this.Namespace=ns; this.NextIndex=nextIndex; }
public static FuncBuilderHints EmitFunction(Namespace ns, FuncBuilderHints fbHints, ActionOnFuncBuilder action, out bool runAgain) { try { //HACK var emitter=CodeGenerator.Emitter; emitter.RegistersWritten=0; var fb=new FuncBuilder(ns, fbHints, action); var rw=emitter.RegistersWritten; var scratch0Used=(rw&(1<<fb.Scratch0.Index))!=0; var scratch1Used=(rw&(1<<fb.Scratch1.Index))!=0; return fb.RunOptimizer(scratch0Used, scratch1Used, out runAgain); } finally { Instance=null; } }
public TerminalName(Namespace ns, string name) { this.Namespace=ns; this.name=name; }