public void CGenFloat(CGenState state) {
// 1. Load Left to ST0. Now the float stack should only contain one element.
//
// memory stack:
// +-----+
// | |
// | ... | <- %esp
// +-----+
//
// float stack:
// +-----+
// | Left | <- %st(0)
// +-----+
//
var ret = this.Left.CGenValue(state);
if (ret != Reg.ST0) {
throw new InvalidOperationException();
}
// 2. Pop from float stack, push into memory stack. Now the float stack should be empty.
//
// memory stack:
// +-----+
// | |
// | ... |
// | Left | <- %esp has decreased by 4
// +-----+
//
// float stack:
// +-----+ empty
//
Int32 stack_size = state.CGenPushFloatP();
// 3. Load Right to ST0. Now the float stack should only contain one element.
//
// memory stack:
// +-----+
// | |
// | ... |
// | Left | <- %esp
// +-----+
//
// float stack:
// +-----+
// | Right | <- %st(0)
// +-----+
//
ret = this.Right.CGenValue(state);
if (ret != Reg.ST0) {
throw new InvalidOperationException();
}
// 4. Pop double from memory stack, push into float stack. Now both Left and Right are in float stack.
//
// memory stack:
// +-----+
// | |
// | ... | <- %esp
// +-----+
//
// float stack:
// +-----+
// | Right | <- %st(1)
// +-----+
// | Left | <- %st(0)
// +-----+
//
state.CGenPopFloat(stack_size);
// 5. Perform operation. FPU would pop both operands and push answer back in.
//
// memory stack:
// +-----+
// | |
// | ... | <- %esp
// +-----+
//
// float stack:
// +-----+
// | ans | <- %st(0)
// +-----+
//
OperateFloat(state);
}