1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift32.cc,v 1.47 2008/09/19 19:18:57 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::SHLD_EdGdM(bxInstruction_c
*i
)
35 Bit32u op1_32
, op2_32
, result_32
;
39 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
41 /* pointer, segment address pair */
42 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
44 if (i
->b1() == 0xa4) // 0x1a4
49 count
&= 0x1f; // use only 5 LSB's
52 op2_32
= BX_READ_32BIT_REG(i
->nnn());
54 result_32
= (op1_32
<< count
) | (op2_32
>> (32 - count
));
56 write_RMW_virtual_dword(result_32
);
58 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
60 cf
= (op1_32
>> (32 - count
)) & 0x1;
61 of
= cf
^ (result_32
>> 31); // of = cf ^ result31
62 SET_FLAGS_OxxxxC(of
, cf
);
65 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EdGdR(bxInstruction_c
*i
)
67 Bit32u op1_32
, op2_32
, result_32
;
71 if (i
->b1() == 0xa4) // 0x1a4
76 count
&= 0x1f; // use only 5 LSB's
79 op1_32
= BX_READ_32BIT_REG(i
->rm());
80 op2_32
= BX_READ_32BIT_REG(i
->nnn());
82 result_32
= (op1_32
<< count
) | (op2_32
>> (32 - count
));
84 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
86 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
88 cf
= (op1_32
>> (32 - count
)) & 0x1;
89 of
= cf
^ (result_32
>> 31); // of = cf ^ result31
90 SET_FLAGS_OxxxxC(of
, cf
);
93 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EdGdM(bxInstruction_c
*i
)
95 Bit32u op1_32
, op2_32
, result_32
;
99 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
101 /* pointer, segment address pair */
102 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
104 if (i
->b1() == 0xac) // 0x1ac
109 count
&= 0x1f; // use only 5 LSB's
112 op2_32
= BX_READ_32BIT_REG(i
->nnn());
114 result_32
= (op2_32
<< (32 - count
)) | (op1_32
>> count
);
116 write_RMW_virtual_dword(result_32
);
118 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
120 cf
= (op1_32
>> (count
- 1)) & 0x1;
121 of
= ((result_32
<< 1) ^ result_32
) >> 31; // of = result30 ^ result31
122 SET_FLAGS_OxxxxC(of
, cf
);
125 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EdGdR(bxInstruction_c
*i
)
127 Bit32u op1_32
, op2_32
, result_32
;
131 if (i
->b1() == 0xac) // 0x1ac
136 count
&= 0x1f; // use only 5 LSB's
139 op1_32
= BX_READ_32BIT_REG(i
->rm());
140 op2_32
= BX_READ_32BIT_REG(i
->nnn());
142 result_32
= (op2_32
<< (32 - count
)) | (op1_32
>> count
);
144 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
146 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
148 cf
= (op1_32
>> (count
- 1)) & 0x1;
149 of
= ((result_32
<< 1) ^ result_32
) >> 31; // of = result30 ^ result31
150 SET_FLAGS_OxxxxC(of
, cf
);
153 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EdM(bxInstruction_c
*i
)
155 Bit32u op1_32
, result_32
;
158 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
160 /* pointer, segment address pair */
161 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
171 result_32
= (op1_32
<< count
) | (op1_32
>> (32 - count
));
173 write_RMW_virtual_dword(result_32
);
175 unsigned bit0
= (result_32
& 0x1);
176 unsigned bit31
= (result_32
>> 31);
177 // of = cf ^ result31
178 SET_FLAGS_OxxxxC(bit0
^ bit31
, bit0
);
181 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EdR(bxInstruction_c
*i
)
183 Bit32u op1_32
, result_32
;
185 unsigned bit0
, bit31
;
195 op1_32
= BX_READ_32BIT_REG(i
->rm());
196 result_32
= (op1_32
<< count
) | (op1_32
>> (32 - count
));
197 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
199 bit0
= (result_32
& 0x1);
200 bit31
= (result_32
>> 31);
201 // of = cf ^ result31
202 SET_FLAGS_OxxxxC(bit0
^ bit31
, bit0
);
205 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EdM(bxInstruction_c
*i
)
207 Bit32u op1_32
, result_32
;
209 unsigned bit31
, bit30
;
211 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
213 /* pointer, segment address pair */
214 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
224 result_32
= (op1_32
>> count
) | (op1_32
<< (32 - count
));
226 write_RMW_virtual_dword(result_32
);
228 bit31
= (result_32
>> 31) & 1;
229 bit30
= (result_32
>> 30) & 1;
230 // of = result30 ^ result31
231 SET_FLAGS_OxxxxC(bit30
^ bit31
, bit31
);
234 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EdR(bxInstruction_c
*i
)
236 Bit32u op1_32
, result_32
;
238 unsigned bit31
, bit30
;
248 op1_32
= BX_READ_32BIT_REG(i
->rm());
249 result_32
= (op1_32
>> count
) | (op1_32
<< (32 - count
));
250 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
252 bit31
= (result_32
>> 31) & 1;
253 bit30
= (result_32
>> 30) & 1;
254 // of = result30 ^ result31
255 SET_FLAGS_OxxxxC(bit30
^ bit31
, bit31
);
258 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EdM(bxInstruction_c
*i
)
260 Bit32u op1_32
, result_32
;
264 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
266 /* pointer, segment address pair */
267 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
278 result_32
= (op1_32
<< 1) | getB_CF();
281 result_32
= (op1_32
<< count
) | (getB_CF() << (count
- 1)) |
282 (op1_32
>> (33 - count
));
285 write_RMW_virtual_dword(result_32
);
287 cf
= (op1_32
>> (32 - count
)) & 0x1;
288 of
= cf
^ (result_32
>> 31); // of = cf ^ result31
289 SET_FLAGS_OxxxxC(of
, cf
);
292 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EdR(bxInstruction_c
*i
)
294 Bit32u op1_32
, result_32
;
306 op1_32
= BX_READ_32BIT_REG(i
->rm());
309 result_32
= (op1_32
<< 1) | getB_CF();
312 result_32
= (op1_32
<< count
) | (getB_CF() << (count
- 1)) |
313 (op1_32
>> (33 - count
));
316 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
318 cf
= (op1_32
>> (32 - count
)) & 0x1;
319 of
= cf
^ (result_32
>> 31); // of = cf ^ result31
320 SET_FLAGS_OxxxxC(of
, cf
);
323 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EdM(bxInstruction_c
*i
)
325 Bit32u op1_32
, result_32
;
329 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
331 /* pointer, segment address pair */
332 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
343 result_32
= (op1_32
>> 1) | (getB_CF() << 31);
346 result_32
= (op1_32
>> count
) | (getB_CF() << (32 - count
)) |
347 (op1_32
<< (33 - count
));
350 write_RMW_virtual_dword(result_32
);
352 cf
= (op1_32
>> (count
- 1)) & 0x1;
353 of
= ((result_32
<< 1) ^ result_32
) >> 31; // of = result30 ^ result31
354 SET_FLAGS_OxxxxC(of
, cf
);
357 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EdR(bxInstruction_c
*i
)
359 Bit32u op1_32
, result_32
;
371 op1_32
= BX_READ_32BIT_REG(i
->rm());
374 result_32
= (op1_32
>> 1) | (getB_CF() << 31);
377 result_32
= (op1_32
>> count
) | (getB_CF() << (32 - count
)) |
378 (op1_32
<< (33 - count
));
381 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
383 cf
= (op1_32
>> (count
- 1)) & 0x1;
384 of
= ((result_32
<< 1) ^ result_32
) >> 31; // of = result30 ^ result31
385 SET_FLAGS_OxxxxC(of
, cf
);
388 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EdM(bxInstruction_c
*i
)
390 Bit32u op1_32
, result_32
;
394 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
396 /* pointer, segment address pair */
397 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
407 /* count < 32, since only lower 5 bits used */
408 result_32
= (op1_32
<< count
);
410 write_RMW_virtual_dword(result_32
);
412 cf
= (op1_32
>> (32 - count
)) & 0x1;
413 of
= cf
^ (result_32
>> 31);
414 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
415 SET_FLAGS_OxxxxC(of
, cf
);
418 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EdR(bxInstruction_c
*i
)
420 Bit32u op1_32
, result_32
;
432 op1_32
= BX_READ_32BIT_REG(i
->rm());
434 /* count < 32, since only lower 5 bits used */
435 result_32
= (op1_32
<< count
);
436 cf
= (op1_32
>> (32 - count
)) & 0x1;
437 of
= cf
^ (result_32
>> 31);
439 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
441 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
442 SET_FLAGS_OxxxxC(of
, cf
);
445 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EdM(bxInstruction_c
*i
)
447 Bit32u op1_32
, result_32
;
451 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
453 /* pointer, segment address pair */
454 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
464 result_32
= (op1_32
>> count
);
466 write_RMW_virtual_dword(result_32
);
468 cf
= (op1_32
>> (count
- 1)) & 0x1;
469 // note, that of == result31 if count == 1 and
470 // of == 0 if count >= 2
471 of
= ((result_32
<< 1) ^ result_32
) >> 31;
473 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
474 SET_FLAGS_OxxxxC(of
, cf
);
477 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EdR(bxInstruction_c
*i
)
479 Bit32u op1_32
, result_32
;
491 op1_32
= BX_READ_32BIT_REG(i
->rm());
492 result_32
= (op1_32
>> count
);
493 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
495 cf
= (op1_32
>> (count
- 1)) & 0x1;
496 // note, that of == result31 if count == 1 and
497 // of == 0 if count >= 2
498 of
= ((result_32
<< 1) ^ result_32
) >> 31;
500 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
501 SET_FLAGS_OxxxxC(of
, cf
);
504 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EdM(bxInstruction_c
*i
)
506 Bit32u op1_32
, result_32
;
509 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
511 /* pointer, segment address pair */
512 op1_32
= read_RMW_virtual_dword(i
->seg(), eaddr
);
522 /* count < 32, since only lower 5 bits used */
523 if (op1_32
& 0x80000000) {
524 result_32
= (op1_32
>> count
) | (0xffffffff << (32 - count
));
527 result_32
= (op1_32
>> count
);
530 write_RMW_virtual_dword(result_32
);
532 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
533 set_CF((op1_32
>> (count
- 1)) & 1);
534 clear_OF(); /* signed overflow cannot happen in SAR instruction */
537 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EdR(bxInstruction_c
*i
)
539 Bit32u op1_32
, result_32
;
550 op1_32
= BX_READ_32BIT_REG(i
->rm());
552 /* count < 32, since only lower 5 bits used */
553 if (op1_32
& 0x80000000) {
554 result_32
= (op1_32
>> count
) | (0xffffffff << (32 - count
));
557 result_32
= (op1_32
>> count
);
560 BX_WRITE_32BIT_REGZ(i
->rm(), result_32
);
562 SET_FLAGS_OSZAPC_LOGIC_32(result_32
); /* handle SF, ZF and AF flags */
563 set_CF((op1_32
>> (count
- 1)) & 1);
564 clear_OF(); /* signed overflow cannot happen in SAR instruction */