private void CGenPrepareIntegralOperands(CGenState state) {
// 1. Load Left to EAX.
//
// regs:
// %eax = Left
//
// stack:
// +-----+
// | ... | <- %esp
// +-----+
//
if (this.Left.CGenValue(state) != Reg.EAX) {
throw new InvalidOperationException();
}
// 2. Push Left to stack.
//
// regs:
// %eax = Left
//
// stack:
// +-----+
// | ... |
// +-----+
// | Left | <- %esp has decreased by 4
// +-----+
//
Int32 stack_size = state.CGenPushLong(Reg.EAX);
// 3. Load Right to EAX.
//
// regs:
// %eax = Right
//
// stack:
// +-----+
// | ... |
// +-----+
// | Left | <- %esp
// +-----+
//
if (this.Right.CGenValue(state) != Reg.EAX) {
throw new InvalidOperationException();
}
// 4. Move Right into EBX. Pop Left from stack, into EAX.
//
// regs:
// %eax = Left
// %ebx = Right
//
// stack:
// +-----+
// | ... | <- %esp has moved back.
// +-----+
//
state.MOVL(Reg.EAX, Reg.EBX);
state.CGenPopLong(stack_size, Reg.EAX);
}