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 FuncDeclaration Function(string name, ActionOnFuncBuilder body=null) { var result=new FuncDeclaration(name); if(body!=null) { result.Define(body); } return result; }
public FuncDeclaration Function(string name, ActionOnFuncBuilder body = null) { var result = new FuncDeclaration(name); if (body != null) { result.Define(body); } return(result); }
public void Define(ActionOnFuncBuilder body) { CodeGenerator.Instance.AddFuncDefinition(new FuncDefinition(this, body)); }
public FuncDefinition(FuncDeclaration declaration, ActionOnFuncBuilder body) { this.Declaration=declaration; this.Body=body; }
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); } }
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 FuncDefinition(FuncDeclaration declaration, ActionOnFuncBuilder body) { this.Declaration = declaration; this.Body = body; }