Exemplo n.º 1
0
        public override void BranchIf(bool sense, Label target)
        {
            var f=FuncBuilder.Instance;
              var emitter=CodeGenerator.Emitter;
              var declarer=f.Declare;
              using(f.OpenScope("compare")) {
            var lhsTemp=declarer.Int("lhs");
            var rhsTemp=declarer.Int("rhs");

            var lhsResult=lhs.EvaluateTo(lhsTemp);
            var rhsResult=rhs.EvaluateTo(rhsTemp);

            var lhsReg=lhsResult.ToRegister(f.Scratch0);
            var rhsRegOrByte=rhsResult.ToRegisterOrByte(f.Scratch1);
            if(rhsRegOrByte.IsRegister) {
              emitter.Emit(Format4OpCode.CMP, lhsReg, rhsRegOrByte.Register);
            } else {
              emitter.Emit(Format3OpCode.CMP, lhsReg, rhsRegOrByte.Byte);
            }

            var instructionToUse=sense ? branchOpCode : inverseOpCode;
            var address=target.GetLabelAddressBestEffort();
            emitter.Emit(instructionToUse, address);
              }
        }
Exemplo n.º 2
0
 public Static(int declarationIndex, Label storageLabel, int[] initialData)
 {
     this.DeclarationIndex=declarationIndex;
       if(initialData.Length==1 && initialData[0]==0) {
     initialData=OneZero;
       }
       this.StorageLabel=storageLabel;
       this.InitialData=initialData;
 }
Exemplo n.º 3
0
 public override void BranchIf(bool sense, Label target)
 {
     if(!sense) {
     //if you want lhs||rhs to be false, then you will succeed if lhs is false and rhs is false
     Invert().BranchIf(true, target);
       } else {
     //if you want lhs||rhs to be true, then you will succeed if lhs is true or rhs is true
     lhs.BranchIf(true, target);
     rhs.BranchIf(true, target);
       }
 }
Exemplo n.º 4
0
 public static void UnconditionalBranchTo(Label target)
 {
     var emitter=CodeGenerator.Emitter;
       var targetAddress=target.GetLabelAddressBestEffort();
       var caddr=emitter.CurrentAddress;
       //branch to next instruction or branch to self cause this instruction to be elided
       //why: in phase N, a needless branch will look like a branch to the next instruction,
       // but in phase N+1 it will look like a branch to self
       if(targetAddress==caddr || targetAddress==caddr+2) {
     Debug.Print("<branch to next instruction removed>");
       } else {
     emitter.Emit(Format18OpCode.B, targetAddress);
       }
 }
Exemplo n.º 5
0
 public override void BranchIf(bool sense, Label target)
 {
     var f=FuncBuilder.Instance;
       if(!sense) {
     //if you want lhs&&rhs to be false, then you will succeed if lhs is false or rhs is false
     lhs.BranchIf(false, target);
     rhs.BranchIf(false, target);
       } else {
     //but if you want lhs&&rhs to be true, then you will succeed if lhs is true and rhs is true
     var fail=f.DeclareLabel("fail");
     lhs.BranchIf(false, fail);
     rhs.BranchIf(true, target);
     fail.Mark();
       }
 }
Exemplo n.º 6
0
 public abstract void BranchIf(bool sense, Label target);
Exemplo n.º 7
0
 public AddressOf(Label label, bool wantThumbAdjustment)
 {
     this.label=label;
       this.wantThumbAdjustment=wantThumbAdjustment;
 }
Exemplo n.º 8
0
 public FuncDeclaration(string name)
 {
     this.Name=name;
       this.EntryPoint=CodeGenerator.Instance.DeclareStaticLabel(name);
 }
Exemplo n.º 9
0
 public void BindStaticVariableToNewRepresentation(IReference variable, string name, int[] initialData)
 {
     var terminalName=CreateTerminalName(name);
       var label=new Label(terminalName);
       var representation=new Static(staticVariableToInfo.Count, label, initialData);
       staticVariableToInfo.CheckedAdd(variable, new StaticVariableInfo(terminalName, representation));
 }
Exemplo n.º 10
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);
              }
        }