1 /////////////////////////////////////////////////////////////////////////
2 // $Id: data_xfer16.cc,v 1.63 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 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RXIw(bxInstruction_c
*i
)
35 BX_WRITE_16BIT_REG(i
->opcodeReg(), i
->Iw());
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_RXAX(bxInstruction_c
*i
)
41 AX
= BX_READ_16BIT_REG(i
->opcodeReg());
42 BX_WRITE_16BIT_REG(i
->opcodeReg(), temp16
);
45 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwGwM(bxInstruction_c
*i
)
47 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
49 write_virtual_word(i
->seg(), eaddr
, BX_READ_16BIT_REG(i
->nnn()));
52 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GwEwR(bxInstruction_c
*i
)
54 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
57 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GwEwM(bxInstruction_c
*i
)
59 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
61 Bit16u val16
= read_virtual_word(i
->seg(), eaddr
);
62 BX_WRITE_16BIT_REG(i
->nnn(), val16
);
65 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwSwR(bxInstruction_c
*i
)
67 /* Illegal to use nonexisting segments */
69 BX_INFO(("MOV_EwSw: using of nonexisting segment register %d", i
->nnn()));
70 exception(BX_UD_EXCEPTION
, 0, 0);
73 Bit16u seg_reg
= BX_CPU_THIS_PTR sregs
[i
->nnn()].selector
.value
;
76 BX_WRITE_32BIT_REGZ(i
->rm(), seg_reg
);
79 BX_WRITE_16BIT_REG(i
->rm(), seg_reg
);
83 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwSwM(bxInstruction_c
*i
)
85 /* Illegal to use nonexisting segments */
87 BX_INFO(("MOV_EwSw: using of nonexisting segment register %d", i
->nnn()));
88 exception(BX_UD_EXCEPTION
, 0, 0);
91 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
93 Bit16u seg_reg
= BX_CPU_THIS_PTR sregs
[i
->nnn()].selector
.value
;
94 write_virtual_word(i
->seg(), eaddr
, seg_reg
);
97 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_SwEw(bxInstruction_c
*i
)
101 /* Attempt to load CS or nonexisting segment register */
102 if (i
->nnn() >= 6 || i
->nnn() == BX_SEG_REG_CS
) {
103 BX_INFO(("MOV_EwSw: can't use this segment register %d", i
->nnn()));
104 exception(BX_UD_EXCEPTION
, 0, 0);
108 op2_16
= BX_READ_16BIT_REG(i
->rm());
111 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
112 /* pointer, segment address pair */
113 op2_16
= read_virtual_word(i
->seg(), eaddr
);
116 load_seg_reg(&BX_CPU_THIS_PTR sregs
[i
->nnn()], op2_16
);
118 if (i
->nnn() == BX_SEG_REG_SS
) {
119 // MOV SS inhibits interrupts, debug exceptions and single-step
120 // trap exceptions until the execution boundary following the
121 // next instruction is reached.
122 // Same code as POP_SS()
123 BX_CPU_THIS_PTR inhibit_mask
|= BX_INHIBIT_INTERRUPTS
| BX_INHIBIT_DEBUG
;
124 BX_CPU_THIS_PTR async_event
= 1;
128 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LEA_GwM(bxInstruction_c
*i
)
130 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
132 BX_WRITE_16BIT_REG(i
->nnn(), (Bit16u
) eaddr
);
135 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_AXOd(bxInstruction_c
*i
)
137 AX
= read_virtual_word_32(i
->seg(), i
->Id());
140 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_OdAX(bxInstruction_c
*i
)
142 write_virtual_word_32(i
->seg(), i
->Id(), AX
);
145 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwIwM(bxInstruction_c
*i
)
147 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
149 write_virtual_word(i
->seg(), eaddr
, i
->Iw());
152 #if BX_CPU_LEVEL >= 3
153 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GwEbM(bxInstruction_c
*i
)
155 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
157 Bit8u op2_8
= read_virtual_byte(i
->seg(), eaddr
);
159 /* zero extend byte op2 into word op1 */
160 BX_WRITE_16BIT_REG(i
->nnn(), (Bit16u
) op2_8
);
163 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVZX_GwEbR(bxInstruction_c
*i
)
165 Bit8u op2_8
= BX_READ_8BIT_REGx(i
->rm(), i
->extend8bitL());
167 /* zero extend byte op2 into word op1 */
168 BX_WRITE_16BIT_REG(i
->nnn(), (Bit16u
) op2_8
);
171 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbM(bxInstruction_c
*i
)
173 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
175 Bit8u op2_8
= read_virtual_byte(i
->seg(), eaddr
);
177 /* sign extend byte op2 into word op1 */
178 BX_WRITE_16BIT_REG(i
->nnn(), (Bit8s
) op2_8
);
181 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbR(bxInstruction_c
*i
)
183 Bit8u op2_8
= BX_READ_8BIT_REGx(i
->rm(),i
->extend8bitL());
185 /* sign extend byte op2 into word op1 */
186 BX_WRITE_16BIT_REG(i
->nnn(), (Bit8s
) op2_8
);
190 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwM(bxInstruction_c
*i
)
192 Bit16u op1_16
, op2_16
;
194 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
196 op1_16
= read_RMW_virtual_word(i
->seg(), eaddr
);
197 op2_16
= BX_READ_16BIT_REG(i
->nnn());
199 write_RMW_virtual_word(op2_16
);
200 BX_WRITE_16BIT_REG(i
->nnn(), op1_16
);
203 void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwR(bxInstruction_c
*i
)
205 Bit16u op1_16
, op2_16
;
208 // Note for mortals: the instruction to trigger this is "xchgw %bx,%bx"
209 if (bx_dbg
.magic_break_enabled
&& (i
->nnn() == 3) && (i
->rm() == 3))
211 BX_CPU_THIS_PTR magic_break
= 1;
216 op1_16
= BX_READ_16BIT_REG(i
->rm());
217 op2_16
= BX_READ_16BIT_REG(i
->nnn());
219 BX_WRITE_16BIT_REG(i
->nnn(), op1_16
);
220 BX_WRITE_16BIT_REG(i
->rm(), op2_16
);
223 // Note: CMOV accesses a memory source operand (read), regardless
224 // of whether condition is true or not. Thus, exceptions may
225 // occur even if the MOV does not take place.
227 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVO_GwEwR(bxInstruction_c
*i
)
229 #if BX_CPU_LEVEL >= 6
231 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
233 BX_INFO(("CMOVO_GwEw: --enable-cpu-level=6 required"));
234 exception(BX_UD_EXCEPTION
, 0, 0);
238 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNO_GwEwR(bxInstruction_c
*i
)
240 #if BX_CPU_LEVEL >= 6
242 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
244 BX_INFO(("CMOVNO_GwEw: --enable-cpu-level=6 required"));
245 exception(BX_UD_EXCEPTION
, 0, 0);
249 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVB_GwEwR(bxInstruction_c
*i
)
251 #if BX_CPU_LEVEL >= 6
253 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
255 BX_INFO(("CMOVB_GwEw: --enable-cpu-level=6 required"));
256 exception(BX_UD_EXCEPTION
, 0, 0);
260 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNB_GwEwR(bxInstruction_c
*i
)
262 #if BX_CPU_LEVEL >= 6
264 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
266 BX_INFO(("CMOVNB_GwEw: --enable-cpu-level=6 required"));
267 exception(BX_UD_EXCEPTION
, 0, 0);
271 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVZ_GwEwR(bxInstruction_c
*i
)
273 #if BX_CPU_LEVEL >= 6
275 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
277 BX_INFO(("CMOVZ_GwEw: --enable-cpu-level=6 required"));
278 exception(BX_UD_EXCEPTION
, 0, 0);
282 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNZ_GwEwR(bxInstruction_c
*i
)
284 #if BX_CPU_LEVEL >= 6
286 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
288 BX_INFO(("CMOVNZ_GwEw: --enable-cpu-level=6 required"));
289 exception(BX_UD_EXCEPTION
, 0, 0);
293 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVBE_GwEwR(bxInstruction_c
*i
)
295 #if BX_CPU_LEVEL >= 6
296 if (get_CF() || get_ZF())
297 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
299 BX_INFO(("CMOVBE_GwEw: --enable-cpu-level=6 required"));
300 exception(BX_UD_EXCEPTION
, 0, 0);
304 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNBE_GwEwR(bxInstruction_c
*i
)
306 #if BX_CPU_LEVEL >= 6
307 if (! (get_CF() || get_ZF()))
308 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
310 BX_INFO(("CMOVNBE_GwEw: --enable-cpu-level=6 required"));
311 exception(BX_UD_EXCEPTION
, 0, 0);
315 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVS_GwEwR(bxInstruction_c
*i
)
317 #if BX_CPU_LEVEL >= 6
319 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
321 BX_INFO(("CMOVS_GwEw: --enable-cpu-level=6 required"));
322 exception(BX_UD_EXCEPTION
, 0, 0);
326 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNS_GwEwR(bxInstruction_c
*i
)
328 #if BX_CPU_LEVEL >= 6
330 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
332 BX_INFO(("CMOVNS_GwEw: --enable-cpu-level=6 required"));
333 exception(BX_UD_EXCEPTION
, 0, 0);
337 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVP_GwEwR(bxInstruction_c
*i
)
339 #if BX_CPU_LEVEL >= 6
341 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
343 BX_INFO(("CMOVP_GwEw: --enable-cpu-level=6 required"));
344 exception(BX_UD_EXCEPTION
, 0, 0);
348 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNP_GwEwR(bxInstruction_c
*i
)
350 #if BX_CPU_LEVEL >= 6
352 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
354 BX_INFO(("CMOVNP_GwEw: --enable-cpu-level=6 required"));
355 exception(BX_UD_EXCEPTION
, 0, 0);
359 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVL_GwEwR(bxInstruction_c
*i
)
361 #if BX_CPU_LEVEL >= 6
362 if (getB_SF() != getB_OF())
363 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
365 BX_INFO(("CMOVL_GwEw: --enable-cpu-level=6 required"));
366 exception(BX_UD_EXCEPTION
, 0, 0);
370 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNL_GwEwR(bxInstruction_c
*i
)
372 #if BX_CPU_LEVEL >= 6
373 if (getB_SF() == getB_OF())
374 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
376 BX_INFO(("CMOVNL_GwEw: --enable-cpu-level=6 required"));
377 exception(BX_UD_EXCEPTION
, 0, 0);
381 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVLE_GwEwR(bxInstruction_c
*i
)
383 #if BX_CPU_LEVEL >= 6
384 if (get_ZF() || (getB_SF() != getB_OF()))
385 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
387 BX_INFO(("CMOVLE_GwEw: --enable-cpu-level=6 required"));
388 exception(BX_UD_EXCEPTION
, 0, 0);
392 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNLE_GwEwR(bxInstruction_c
*i
)
394 #if BX_CPU_LEVEL >= 6
395 if (! get_ZF() && (getB_SF() == getB_OF()))
396 BX_WRITE_16BIT_REG(i
->nnn(), BX_READ_16BIT_REG(i
->rm()));
398 BX_INFO(("CMOVNLE_GwEw: --enable-cpu-level=6 required"));
399 exception(BX_UD_EXCEPTION
, 0, 0);