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 Return(this FuncBuilder f, IntExpression expr) { using (f.OpenScope("return")) { var emitter = CodeGenerator.Emitter; var resultStorage = f.Declare.Int("result"); var exprResult = expr.EvaluateTo(resultStorage); var exprRegOrByte = exprResult.ToRegisterOrByte(f.Scratch0); if (exprRegOrByte.IsRegister) { emitter.EmitRegisterMoveIfDifferent(Register.R0, exprRegOrByte.Register); } else { emitter.Emit(Format3OpCode.MOV, Register.R0, exprRegOrByte.Byte); } BranchLogic.UnconditionalBranchTo(f.TheExitLabel); } }