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