Пример #1
0
 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;
     }
 }
Пример #2
0
        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);
            }
        }