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); } }
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; }
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); } }
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); } }
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(); } }
public abstract void BranchIf(bool sense, Label target);
public AddressOf(Label label, bool wantThumbAdjustment) { this.label=label; this.wantThumbAdjustment=wantThumbAdjustment; }
public FuncDeclaration(string name) { this.Name=name; this.EntryPoint=CodeGenerator.Instance.DeclareStaticLabel(name); }
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)); }
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); } }