- compilation fixes for MSVC toolkit 2003
[bochs-mirror.git] / cpu / data_xfer32.cc
blob9ced6469a3d61eaab36fdaeab6e98060d7716f81
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: data_xfer32.cc,v 1.61 2008/09/06 21:18:08 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==0
34 // Make life easier for merging cpu64 and cpu32 code.
35 #define RAX EAX
36 #endif
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_ERXEAX(bxInstruction_c *i)
40 #if BX_SUPPORT_X86_64
41 if (i->opcodeReg() == 0) // 'xchg eax, eax' is NOP even in 64-bit mode
42 return;
43 #endif
45 Bit32u temp32 = EAX;
46 RAX = BX_READ_32BIT_REG(i->opcodeReg());
47 BX_WRITE_32BIT_REGZ(i->opcodeReg(), temp32);
50 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_ERXId(bxInstruction_c *i)
52 BX_WRITE_32BIT_REGZ(i->opcodeReg(), i->Id());
55 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EdGdM(bxInstruction_c *i)
57 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
59 write_virtual_dword(i->seg(), eaddr, BX_READ_32BIT_REG(i->nnn()));
62 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GdEdR(bxInstruction_c *i)
64 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
67 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32_GdEdM(bxInstruction_c *i)
69 Bit32u eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
71 Bit32u val32 = read_virtual_dword_32(i->seg(), eaddr);
72 BX_WRITE_32BIT_REGZ(i->nnn(), val32);
75 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LEA_GdM(bxInstruction_c *i)
77 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
79 BX_WRITE_32BIT_REGZ(i->nnn(), eaddr);
82 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EAXOd(bxInstruction_c *i)
84 RAX = read_virtual_dword_32(i->seg(), i->Id());
87 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_OdEAX(bxInstruction_c *i)
89 write_virtual_dword_32(i->seg(), i->Id(), EAX);
92 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EdIdM(bxInstruction_c *i)
94 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
96 write_virtual_dword(i->seg(), eaddr, i->Id());
99 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GdEbM(bxInstruction_c *i)
101 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
103 Bit8u op2_8 = read_virtual_byte(i->seg(), eaddr);
105 /* zero extend byte op2 into dword op1 */
106 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit32u) op2_8);
109 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GdEbR(bxInstruction_c *i)
111 Bit8u op2_8 = BX_READ_8BIT_REGx(i->rm(), i->extend8bitL());
113 /* zero extend byte op2 into dword op1 */
114 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit32u) op2_8);
117 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GdEwM(bxInstruction_c *i)
119 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
121 Bit16u op2_16 = read_virtual_word(i->seg(), eaddr);
123 /* zero extend word op2 into dword op1 */
124 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit32u) op2_16);
127 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GdEwR(bxInstruction_c *i)
129 Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
131 /* zero extend word op2 into dword op1 */
132 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit32u) op2_16);
135 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GdEbM(bxInstruction_c *i)
137 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
139 Bit8u op2_8 = read_virtual_byte(i->seg(), eaddr);
141 /* sign extend byte op2 into dword op1 */
142 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit8s) op2_8);
145 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GdEbR(bxInstruction_c *i)
147 Bit8u op2_8 = BX_READ_8BIT_REGx(i->rm(), i->extend8bitL());
149 /* sign extend byte op2 into dword op1 */
150 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit8s) op2_8);
153 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GdEwM(bxInstruction_c *i)
155 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
157 Bit16u op2_16 = read_virtual_word(i->seg(), eaddr);
159 /* sign extend word op2 into dword op1 */
160 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit16s) op2_16);
163 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GdEwR(bxInstruction_c *i)
165 Bit16u op2_16 = BX_READ_16BIT_REG(i->rm());
167 /* sign extend word op2 into dword op1 */
168 BX_WRITE_32BIT_REGZ(i->nnn(), (Bit16s) op2_16);
171 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EdGdM(bxInstruction_c *i)
173 Bit32u op2_32, op1_32;
175 bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
177 op1_32 = read_RMW_virtual_dword(i->seg(), eaddr);
178 op2_32 = BX_READ_32BIT_REG(i->nnn());
179 write_RMW_virtual_dword(op2_32);
181 BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
184 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EdGdR(bxInstruction_c *i)
186 Bit32u op1_32 = BX_READ_32BIT_REG(i->rm());
187 Bit32u op2_32 = BX_READ_32BIT_REG(i->nnn());
189 BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
190 BX_WRITE_32BIT_REGZ(i->rm(), op2_32);
193 // Note: CMOV accesses a memory source operand (read), regardless
194 // of whether condition is true or not. Thus, exceptions may
195 // occur even if the MOV does not take place.
197 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVO_GdEdR(bxInstruction_c *i)
199 #if BX_CPU_LEVEL >= 6
200 if (get_OF())
201 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
203 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
204 #else
205 BX_INFO(("CMOVO_GdEd: --enable-cpu-level=6 required"));
206 exception(BX_UD_EXCEPTION, 0, 0);
207 #endif
210 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNO_GdEdR(bxInstruction_c *i)
212 #if BX_CPU_LEVEL >= 6
213 if (!get_OF())
214 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
216 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
217 #else
218 BX_INFO(("CMOVNO_GdEd: --enable-cpu-level=6 required"));
219 exception(BX_UD_EXCEPTION, 0, 0);
220 #endif
223 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVB_GdEdR(bxInstruction_c *i)
225 #if BX_CPU_LEVEL >= 6
226 if (get_CF())
227 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
229 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
230 #else
231 BX_INFO(("CMOVB_GdEd: --enable-cpu-level=6 required"));
232 exception(BX_UD_EXCEPTION, 0, 0);
233 #endif
236 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNB_GdEdR(bxInstruction_c *i)
238 #if BX_CPU_LEVEL >= 6
239 if (!get_CF())
240 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
242 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
243 #else
244 BX_INFO(("CMOVNB_GdEd: --enable-cpu-level=6 required"));
245 exception(BX_UD_EXCEPTION, 0, 0);
246 #endif
249 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVZ_GdEdR(bxInstruction_c *i)
251 #if BX_CPU_LEVEL >= 6
252 if (get_ZF())
253 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
255 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
256 #else
257 BX_INFO(("CMOVZ_GdEd: --enable-cpu-level=6 required"));
258 exception(BX_UD_EXCEPTION, 0, 0);
259 #endif
262 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNZ_GdEdR(bxInstruction_c *i)
264 #if BX_CPU_LEVEL >= 6
265 if (!get_ZF())
266 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
268 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
269 #else
270 BX_INFO(("CMOVNZ_GdEd: --enable-cpu-level=6 required"));
271 exception(BX_UD_EXCEPTION, 0, 0);
272 #endif
275 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVBE_GdEdR(bxInstruction_c *i)
277 #if BX_CPU_LEVEL >= 6
278 if (get_CF() || get_ZF())
279 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
281 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
282 #else
283 BX_INFO(("CMOVBE_GdEd: --enable-cpu-level=6 required"));
284 exception(BX_UD_EXCEPTION, 0, 0);
285 #endif
288 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNBE_GdEdR(bxInstruction_c *i)
290 #if BX_CPU_LEVEL >= 6
291 if (! (get_CF() || get_ZF()))
292 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
294 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
295 #else
296 BX_INFO(("CMOVNBE_GdEd: --enable-cpu-level=6 required"));
297 exception(BX_UD_EXCEPTION, 0, 0);
298 #endif
301 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVS_GdEdR(bxInstruction_c *i)
303 #if BX_CPU_LEVEL >= 6
304 if (get_SF())
305 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
307 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
308 #else
309 BX_INFO(("CMOVS_GdEd: --enable-cpu-level=6 required"));
310 exception(BX_UD_EXCEPTION, 0, 0);
311 #endif
314 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNS_GdEdR(bxInstruction_c *i)
316 #if BX_CPU_LEVEL >= 6
317 if (!get_SF())
318 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
320 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
321 #else
322 BX_INFO(("CMOVNS_GdEd: --enable-cpu-level=6 required"));
323 exception(BX_UD_EXCEPTION, 0, 0);
324 #endif
327 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVP_GdEdR(bxInstruction_c *i)
329 #if BX_CPU_LEVEL >= 6
330 if (get_PF())
331 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
333 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
334 #else
335 BX_INFO(("CMOVP_GdEd: --enable-cpu-level=6 required"));
336 exception(BX_UD_EXCEPTION, 0, 0);
337 #endif
340 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNP_GdEdR(bxInstruction_c *i)
342 #if BX_CPU_LEVEL >= 6
343 if (!get_PF())
344 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
346 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
347 #else
348 BX_INFO(("CMOVNP_GdEd: --enable-cpu-level=6 required"));
349 exception(BX_UD_EXCEPTION, 0, 0);
350 #endif
353 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVL_GdEdR(bxInstruction_c *i)
355 #if BX_CPU_LEVEL >= 6
356 if (getB_SF() != getB_OF())
357 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
359 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
360 #else
361 BX_INFO(("CMOVL_GdEd: --enable-cpu-level=6 required"));
362 exception(BX_UD_EXCEPTION, 0, 0);
363 #endif
366 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNL_GdEdR(bxInstruction_c *i)
368 #if BX_CPU_LEVEL >= 6
369 if (getB_SF() == getB_OF())
370 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
372 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
373 #else
374 BX_INFO(("CMOVNL_GdEd: --enable-cpu-level=6 required"));
375 exception(BX_UD_EXCEPTION, 0, 0);
376 #endif
379 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVLE_GdEdR(bxInstruction_c *i)
381 #if BX_CPU_LEVEL >= 6
382 if (get_ZF() || (getB_SF() != getB_OF()))
383 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
385 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
386 #else
387 BX_INFO(("CMOVLE_GdEd: --enable-cpu-level=6 required"));
388 exception(BX_UD_EXCEPTION, 0, 0);
389 #endif
392 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNLE_GdEdR(bxInstruction_c *i)
394 #if BX_CPU_LEVEL >= 6
395 if (! get_ZF() && (getB_SF() == getB_OF()))
396 BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
398 BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
399 #else
400 BX_INFO(("CMOVNLE_GdEd: --enable-cpu-level=6 required"));
401 exception(BX_UD_EXCEPTION, 0, 0);
402 #endif