1 /////////////////////////////////////////////////////////////////////////
2 // $Id: data_xfer32.cc,v 1.61 2008/09/06 21:18:08 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
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
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.
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_ERXEAX(bxInstruction_c
*i
)
41 if (i
->opcodeReg() == 0) // 'xchg eax, eax' is NOP even in 64-bit mode
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
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
205 BX_INFO(("CMOVO_GdEd: --enable-cpu-level=6 required"));
206 exception(BX_UD_EXCEPTION
, 0, 0);
210 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNO_GdEdR(bxInstruction_c
*i
)
212 #if BX_CPU_LEVEL >= 6
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
218 BX_INFO(("CMOVNO_GdEd: --enable-cpu-level=6 required"));
219 exception(BX_UD_EXCEPTION
, 0, 0);
223 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVB_GdEdR(bxInstruction_c
*i
)
225 #if BX_CPU_LEVEL >= 6
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
231 BX_INFO(("CMOVB_GdEd: --enable-cpu-level=6 required"));
232 exception(BX_UD_EXCEPTION
, 0, 0);
236 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNB_GdEdR(bxInstruction_c
*i
)
238 #if BX_CPU_LEVEL >= 6
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
244 BX_INFO(("CMOVNB_GdEd: --enable-cpu-level=6 required"));
245 exception(BX_UD_EXCEPTION
, 0, 0);
249 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVZ_GdEdR(bxInstruction_c
*i
)
251 #if BX_CPU_LEVEL >= 6
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
257 BX_INFO(("CMOVZ_GdEd: --enable-cpu-level=6 required"));
258 exception(BX_UD_EXCEPTION
, 0, 0);
262 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNZ_GdEdR(bxInstruction_c
*i
)
264 #if BX_CPU_LEVEL >= 6
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
270 BX_INFO(("CMOVNZ_GdEd: --enable-cpu-level=6 required"));
271 exception(BX_UD_EXCEPTION
, 0, 0);
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
283 BX_INFO(("CMOVBE_GdEd: --enable-cpu-level=6 required"));
284 exception(BX_UD_EXCEPTION
, 0, 0);
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
296 BX_INFO(("CMOVNBE_GdEd: --enable-cpu-level=6 required"));
297 exception(BX_UD_EXCEPTION
, 0, 0);
301 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVS_GdEdR(bxInstruction_c
*i
)
303 #if BX_CPU_LEVEL >= 6
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
309 BX_INFO(("CMOVS_GdEd: --enable-cpu-level=6 required"));
310 exception(BX_UD_EXCEPTION
, 0, 0);
314 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNS_GdEdR(bxInstruction_c
*i
)
316 #if BX_CPU_LEVEL >= 6
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
322 BX_INFO(("CMOVNS_GdEd: --enable-cpu-level=6 required"));
323 exception(BX_UD_EXCEPTION
, 0, 0);
327 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVP_GdEdR(bxInstruction_c
*i
)
329 #if BX_CPU_LEVEL >= 6
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
335 BX_INFO(("CMOVP_GdEd: --enable-cpu-level=6 required"));
336 exception(BX_UD_EXCEPTION
, 0, 0);
340 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNP_GdEdR(bxInstruction_c
*i
)
342 #if BX_CPU_LEVEL >= 6
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
348 BX_INFO(("CMOVNP_GdEd: --enable-cpu-level=6 required"));
349 exception(BX_UD_EXCEPTION
, 0, 0);
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
361 BX_INFO(("CMOVL_GdEd: --enable-cpu-level=6 required"));
362 exception(BX_UD_EXCEPTION
, 0, 0);
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
374 BX_INFO(("CMOVNL_GdEd: --enable-cpu-level=6 required"));
375 exception(BX_UD_EXCEPTION
, 0, 0);
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
387 BX_INFO(("CMOVLE_GdEd: --enable-cpu-level=6 required"));
388 exception(BX_UD_EXCEPTION
, 0, 0);
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
400 BX_INFO(("CMOVNLE_GdEd: --enable-cpu-level=6 required"));
401 exception(BX_UD_EXCEPTION
, 0, 0);