- update sector count before calling write completion function (SF patch #2144692)
[bochs-mirror.git] / cpu / stack64.cc
blob2f5dc4061dcfa7edc2d6faa91ce4693366de8f9d
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: stack64.cc,v 1.42 2008/08/08 09:22:49 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
33 #if BX_SUPPORT_X86_64
35 void BX_CPP_AttrRegparmN(1) BX_CPU_C::POP_EqM(bxInstruction_c *i)
37 BX_CPU_THIS_PTR speculative_rsp = 1;
38 BX_CPU_THIS_PTR prev_rsp = RSP;
40 Bit64u val64 = pop_64();
42 // Note: there is one little weirdism here. It is possible to use
43 // RSP in the modrm addressing. If used, the value of RSP after the
44 // pop is used to calculate the address.
45 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
47 write_virtual_qword_64(i->seg(), eaddr, val64);
49 BX_CPU_THIS_PTR speculative_rsp = 0;
52 void BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH_RRX(bxInstruction_c *i)
54 push_64(BX_READ_64BIT_REG(i->opcodeReg()));
57 void BX_CPP_AttrRegparmN(1) BX_CPU_C::POP_RRX(bxInstruction_c *i)
59 BX_WRITE_64BIT_REG(i->opcodeReg(), pop_64());
62 void BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH64_FS(bxInstruction_c *i)
64 push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
67 void BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH64_GS(bxInstruction_c *i)
69 push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
72 void BX_CPP_AttrRegparmN(1) BX_CPU_C::POP64_FS(bxInstruction_c *i)
74 // this way is faster and RSP safe
75 Bit64u fs = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
76 load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
77 RSP += 8;
80 void BX_CPP_AttrRegparmN(1) BX_CPU_C::POP64_GS(bxInstruction_c *i)
82 // this way is faster and RSP safe
83 Bit64u gs = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
84 load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
85 RSP += 8;
88 void BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH64_Id(bxInstruction_c *i)
90 Bit64u imm64 = (Bit32s) i->Id();
91 push_64(imm64);
94 void BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH_EqM(bxInstruction_c *i)
96 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
98 Bit64u op1_64 = read_virtual_qword_64(i->seg(), eaddr);
100 push_64(op1_64);
103 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
105 Bit8u level = i->Ib2();
106 level &= 0x1F;
108 BX_CPU_THIS_PTR speculative_rsp = 1;
109 BX_CPU_THIS_PTR prev_rsp = RSP;
111 push_64(RBP);
113 Bit64u frame_ptr64 = RSP;
115 if (level > 0) {
116 /* do level-1 times */
117 while (--level) {
118 RBP -= 8;
119 Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, RBP);
120 RSP -= 8;
121 write_virtual_qword_64(BX_SEG_REG_SS, RSP, temp64);
122 } /* while (--level) */
124 /* push(frame pointer) */
125 RSP -= 8;
126 write_virtual_qword_64(BX_SEG_REG_SS, RSP, frame_ptr64);
127 } /* if (level > 0) ... */
129 RSP -= i->Iw();
131 // ENTER finishes with memory write check on the final stack pointer
132 // the memory is touched but no write actually occurs
133 // emulate it by doing RMW read access from SS:RSP
134 read_RMW_virtual_qword_64(BX_SEG_REG_SS, RSP);
136 RBP = frame_ptr64;
138 BX_CPU_THIS_PTR speculative_rsp = 0;
141 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE64(bxInstruction_c *i)
143 // restore frame pointer
144 Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, RBP);
145 RSP = RBP + 8;
146 RBP = temp64;
149 #endif /* if BX_SUPPORT_X86_64 */