public override Reg CGenValue(CGenState state) { Int32 label_set = state.label_idx; state.label_idx++; Int32 label_finish = state.label_idx; state.label_idx++; Reg ret = this.Left.CGenValue(state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.JNZ(label_set); break; case Reg.ST0: state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.JNZ(label_set); break; default: throw new InvalidProgramException(); } ret = this.Right.CGenValue(state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.JNZ(label_set); break; case Reg.ST0: state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.JNZ(label_set); break; default: throw new InvalidProgramException(); } state.MOVL(0, Reg.EAX); state.JMP(label_finish); state.CGenLabel(label_set); state.MOVL(1, Reg.EAX); state.CGenLabel(label_finish); return(Reg.EAX); }
public override Reg CGenValue(CGenState state) { Reg ret = this.Expr.CGenValue(state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.SETE(Reg.AL); state.MOVZBL(Reg.AL, Reg.EAX); return(Reg.EAX); case Reg.ST0: /// Compare Expr with 0.0 /// < see cref = "BinaryComparisonOp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.SETE(Reg.AL); state.MOVZBL(Reg.AL, Reg.EAX); return(Reg.EAX); default: throw new InvalidProgramException(); } }
public void CGenTest(Env env, Reg ret, CGenState state) { // test cond switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); break; case Reg.ST0: /// Compare expr with 0.0 /// < see cref = "BinaryArithmeticComp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); break; default: throw new InvalidProgramException(); } }
// // test Cond // jz false ---+ // true_expr | // +------- jmp finish | // | false: <--------+ // | false_expr // +--> finish: // public override Reg CGenValue(CGenState state) { Int32 stack_size = state.StackSize; Reg ret = this.Cond.CGenValue(state); state.CGenForceStackSizeTo(stack_size); // test Cond switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); break; case Reg.ST0: /// Compare Expr with 0.0 /// < see cref = "BinaryComparisonOp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); break; default: throw new InvalidProgramException(); } Int32 false_label = state.RequestLabel(); Int32 finish_label = state.RequestLabel(); state.JZ(false_label); this.TrueExpr.CGenValue(state); state.JMP(finish_label); state.CGenLabel(false_label); ret = this.FalseExpr.CGenValue(state); state.CGenLabel(finish_label); return(ret); }
public void CGenTest(Reg ret, CGenState state) { // test Cond switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); break; case Reg.ST0: /// Compare Expr with 0.0 /// < see cref = "BinaryComparisonOp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); break; default: throw new InvalidProgramException(); } }
// // test cond // jz false ---+ // true_expr | // +------- jmp finish | // | false: <--------+ // | false_expr // +--> finish: // public override Reg CGenValue(Env env, CGenState state) { Int32 stack_size = state.StackSize; Reg ret = cond.CGenValue(env, state); state.CGenForceStackSizeTo(stack_size); // test cond switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); break; case Reg.ST0: /// Compare expr with 0.0 /// < see cref = "BinaryArithmeticComp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); break; default: throw new InvalidProgramException(); } Int32 false_label = state.RequestLabel(); Int32 finish_label = state.RequestLabel(); state.JZ(false_label); true_expr.CGenValue(env, state); state.JMP(finish_label); state.CGenLabel(false_label); ret = false_expr.CGenValue(env, state); state.CGenLabel(finish_label); return ret; }
public override Reg CGenValue(Env env, CGenState state) { Reg ret = expr.CGenValue(env, state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.SETE(Reg.AL); state.MOVZBL(Reg.AL, Reg.EAX); return Reg.EAX; case Reg.ST0: /// Compare expr with 0.0 /// < see cref = "BinaryArithmeticComp.OperateFloat(CGenState)" /> state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.SETE(Reg.AL); state.MOVZBL(Reg.AL, Reg.EAX); return Reg.EAX; default: throw new InvalidProgramException(); } }
public override Reg CGenValue(Env env, CGenState state) { Int32 label_set = state.label_idx; state.label_idx++; Int32 label_finish = state.label_idx; state.label_idx++; Reg ret = lhs.CGenValue(env, state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.JNZ(label_set); break; case Reg.ST0: state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.JNZ(label_set); break; default: throw new InvalidProgramException(); } ret = rhs.CGenValue(env, state); switch (ret) { case Reg.EAX: state.TESTL(Reg.EAX, Reg.EAX); state.JNZ(label_set); break; case Reg.ST0: state.FLDZ(); state.FUCOMIP(); state.FSTP(Reg.ST0); state.JNZ(label_set); break; default: throw new InvalidProgramException(); } state.MOVL(0, Reg.EAX); state.JMP(label_finish); state.CGenLabel(label_set); state.MOVL(1, Reg.EAX); state.CGenLabel(label_finish); return Reg.EAX; }