Exemplo n.º 1
0
        public Reg CGenDouble(Env env, CGenState state) {
            Reg ret;

            // 1. Load lhs to ST0. Now the float stack should only contain one element.
            //
            // memory stack:
            // +-----+
            // |     |
            // | ... | <- %esp
            // +-----+
            //
            // float stack:
            // +-----+
            // | lhs | <- %st(0)
            // +-----+
            // 
            ret = lhs.CGenValue(env, 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:
            // +-----+
            // |     |
            // | ... |
            // | lhs | <- %esp has decreased by 8
            // +-----+
            //
            // float stack:
            // +-----+    empty
            // 
            Int32 stack_size = state.CGenPushDoubleP();

            // 3. Load rhs to ST0. Now the float stack should only contain one element.
            //
            // memory stack:
            // +-----+
            // |     |
            // | ... |
            // | lhs | <- %esp
            // +-----+
            //
            // float stack:
            // +-----+
            // | rhs | <- %st(0)
            // +-----+
            // 
            ret = rhs.CGenValue(env, state);
            if (ret != Reg.ST0) {
                throw new InvalidOperationException();
            }

            // 4. Pop double from memory stack, push into float stack. Now both lhs and rhs are in float stack.
            //
            // memory stack:
            // +-----+
            // |     |
            // | ... | <- %esp
            // +-----+
            //
            // float stack:
            // +-----+
            // | rhs | <- %st(1)
            // +-----+
            // | lhs | <- %st(0)
            // +-----+
            // 
            state.CGenPopDouble(stack_size);

            // 5. Perform operation. FPU would pop both operands and push answer back in.
            //
            // memory stack:
            // +-----+
            // |     |
            // | ... | <- %esp
            // +-----+
            //
            // float stack:
            // +-----+
            // | ans | <- %st(0)
            // +-----+
            // 
            OperateDouble(state);

            return Reg.ST0;
        }
Exemplo n.º 2
0
        /// <summary>
        /// 1. %st(0) = left, %st(1) = right, stack unchanged
        /// 2. OperateDouble
        /// </summary>
        public void CGenDouble(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 8
            // +-----+
            //
            // float stack:
            // +-----+    empty
            //
            Int32 stack_size = state.CGenPushDoubleP();

            // 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.CGenPopDouble(stack_size);

            // 5. Perform operation. FPU would pop both operands and push answer back in.
            //
            // memory stack:
            // +-----+
            // |     |
            // | ... | <- %esp
            // +-----+
            //
            // float stack:
            // +-----+
            // | ans | <- %st(0)
            // +-----+
            //
            OperateDouble(state);
        }