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