1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift64.cc,v 1.38 2008/08/08 09:22:48 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
35 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EqGqM(bxInstruction_c
*i
)
37 Bit64u op1_64
, op2_64
, result_64
;
41 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
43 /* pointer, segment address pair */
44 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
46 if (i
->b1() == 0xa4) // 0x1a4
51 count
&= 0x3f; // use only 6 LSB's
54 op2_64
= BX_READ_64BIT_REG(i
->nnn());
56 result_64
= (op1_64
<< count
) | (op2_64
>> (64 - count
));
58 write_RMW_virtual_qword(result_64
);
60 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
62 cf
= (op1_64
>> (64 - count
)) & 0x1;
63 of
= cf
^ (result_64
>> 63); // of = cf ^ result63
64 SET_FLAGS_OxxxxC(of
, cf
);
67 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EqGqR(bxInstruction_c
*i
)
69 Bit64u op1_64
, op2_64
, result_64
;
73 if (i
->b1() == 0xa4) // 0x1a4
78 count
&= 0x3f; // use only 6 LSB's
81 op1_64
= BX_READ_64BIT_REG(i
->rm());
82 op2_64
= BX_READ_64BIT_REG(i
->nnn());
84 result_64
= (op1_64
<< count
) | (op2_64
>> (64 - count
));
86 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
88 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
90 cf
= (op1_64
>> (64 - count
)) & 0x1;
91 of
= cf
^ (result_64
>> 63); // of = cf ^ result63
92 SET_FLAGS_OxxxxC(of
, cf
);
95 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EqGqM(bxInstruction_c
*i
)
97 Bit64u op1_64
, op2_64
, result_64
;
101 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
103 /* pointer, segment address pair */
104 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
106 if (i
->b1() == 0xac) // 0x1ac
111 count
&= 0x3f; // use only 6 LSB's
114 op2_64
= BX_READ_64BIT_REG(i
->nnn());
116 result_64
= (op2_64
<< (64 - count
)) | (op1_64
>> count
);
118 write_RMW_virtual_qword(result_64
);
120 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
122 cf
= (op1_64
>> (count
- 1)) & 0x1;
123 of
= ((result_64
<< 1) ^ result_64
) >> 63; // of = result62 ^ result63
124 SET_FLAGS_OxxxxC(of
, cf
);
127 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHRD_EqGqR(bxInstruction_c
*i
)
129 Bit64u op1_64
, op2_64
, result_64
;
133 if (i
->b1() == 0xac) // 0x1ac
138 count
&= 0x3f; // use only 6 LSB's
141 op1_64
= BX_READ_64BIT_REG(i
->rm());
142 op2_64
= BX_READ_64BIT_REG(i
->nnn());
144 result_64
= (op2_64
<< (64 - count
)) | (op1_64
>> count
);
146 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
148 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
150 cf
= (op1_64
>> (count
- 1)) & 0x1;
151 of
= ((result_64
<< 1) ^ result_64
) >> 63; // of = result62 ^ result63
152 SET_FLAGS_OxxxxC(of
, cf
);
155 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EqM(bxInstruction_c
*i
)
157 Bit64u op1_64
, result_64
;
159 unsigned bit0
, bit63
;
161 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
163 /* pointer, segment address pair */
164 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
174 result_64
= (op1_64
<< count
) | (op1_64
>> (64 - count
));
176 write_RMW_virtual_qword(result_64
);
178 bit0
= (result_64
& 0x1);
179 bit63
= (result_64
>> 63);
180 // of = cf ^ result63
181 SET_FLAGS_OxxxxC(bit0
^ bit63
, bit0
);
184 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROL_EqR(bxInstruction_c
*i
)
186 Bit64u op1_64
, result_64
;
188 unsigned bit0
, bit63
;
198 op1_64
= BX_READ_64BIT_REG(i
->rm());
199 result_64
= (op1_64
<< count
) | (op1_64
>> (64 - count
));
200 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
202 bit0
= (result_64
& 0x1);
203 bit63
= (result_64
>> 63);
204 // of = cf ^ result63
205 SET_FLAGS_OxxxxC(bit0
^ bit63
, bit0
);
208 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EqM(bxInstruction_c
*i
)
210 Bit64u op1_64
, result_64
;
212 unsigned bit62
, bit63
;
214 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
216 /* pointer, segment address pair */
217 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
227 result_64
= (op1_64
>> count
) | (op1_64
<< (64 - count
));
229 write_RMW_virtual_qword(result_64
);
231 bit63
= (result_64
>> 63) & 1;
232 bit62
= (result_64
>> 62) & 1;
233 // of = result62 ^ result63
234 SET_FLAGS_OxxxxC(bit62
^ bit63
, bit63
);
237 void BX_CPP_AttrRegparmN(1) BX_CPU_C::ROR_EqR(bxInstruction_c
*i
)
239 Bit64u op1_64
, result_64
;
241 unsigned bit62
, bit63
;
251 op1_64
= BX_READ_64BIT_REG(i
->rm());
252 result_64
= (op1_64
>> count
) | (op1_64
<< (64 - count
));
253 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
255 bit63
= (result_64
>> 63) & 1;
256 bit62
= (result_64
>> 62) & 1;
257 // of = result62 ^ result63
258 SET_FLAGS_OxxxxC(bit62
^ bit63
, bit63
);
261 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EqM(bxInstruction_c
*i
)
263 Bit64u op1_64
, result_64
;
267 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
269 /* pointer, segment address pair */
270 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
281 result_64
= (op1_64
<< 1) | getB_CF();
284 result_64
= (op1_64
<< count
) | (getB_CF() << (count
- 1)) |
285 (op1_64
>> (65 - count
));
288 write_RMW_virtual_qword(result_64
);
290 cf
= (op1_64
>> (64 - count
)) & 0x1;
291 of
= cf
^ (result_64
>> 63); // of = cf ^ result63
292 SET_FLAGS_OxxxxC(of
, cf
);
295 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCL_EqR(bxInstruction_c
*i
)
297 Bit64u op1_64
, result_64
;
309 op1_64
= BX_READ_64BIT_REG(i
->rm());
312 result_64
= (op1_64
<< 1) | getB_CF();
315 result_64
= (op1_64
<< count
) | (getB_CF() << (count
- 1)) |
316 (op1_64
>> (65 - count
));
319 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
321 cf
= (op1_64
>> (64 - count
)) & 0x1;
322 of
= cf
^ (result_64
>> 63); // of = cf ^ result63
323 SET_FLAGS_OxxxxC(of
, cf
);
326 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EqM(bxInstruction_c
*i
)
328 Bit64u op1_64
, result_64
;
332 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
334 /* pointer, segment address pair */
335 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
346 result_64
= (op1_64
>> 1) | (((Bit64u
) getB_CF()) << 63);
349 result_64
= (op1_64
>> count
) | (getB_CF() << (64 - count
)) |
350 (op1_64
<< (65 - count
));
353 write_RMW_virtual_qword(result_64
);
355 cf
= (op1_64
>> (count
- 1)) & 0x1;
356 of
= ((result_64
<< 1) ^ result_64
) >> 63;
357 SET_FLAGS_OxxxxC(of
, cf
);
360 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RCR_EqR(bxInstruction_c
*i
)
362 Bit64u op1_64
, result_64
;
374 op1_64
= BX_READ_64BIT_REG(i
->rm());
377 result_64
= (op1_64
>> 1) | (((Bit64u
) getB_CF()) << 63);
380 result_64
= (op1_64
>> count
) | (getB_CF() << (64 - count
)) |
381 (op1_64
<< (65 - count
));
384 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
386 cf
= (op1_64
>> (count
- 1)) & 0x1;
387 of
= ((result_64
<< 1) ^ result_64
) >> 63;
388 SET_FLAGS_OxxxxC(of
, cf
);
391 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EqM(bxInstruction_c
*i
)
393 Bit64u op1_64
, result_64
;
397 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
399 /* pointer, segment address pair */
400 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
410 /* count < 64, since only lower 6 bits used */
411 result_64
= (op1_64
<< count
);
412 cf
= (op1_64
>> (64 - count
)) & 0x1;
413 of
= cf
^ (result_64
>> 63);
415 write_RMW_virtual_qword(result_64
);
417 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
418 SET_FLAGS_OxxxxC(of
, cf
);
421 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHL_EqR(bxInstruction_c
*i
)
423 Bit64u op1_64
, result_64
;
435 op1_64
= BX_READ_64BIT_REG(i
->rm());
436 /* count < 64, since only lower 6 bits used */
437 result_64
= (op1_64
<< count
);
438 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
440 cf
= (op1_64
>> (64 - count
)) & 0x1;
441 of
= cf
^ (result_64
>> 63);
442 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
443 SET_FLAGS_OxxxxC(of
, cf
);
446 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EqM(bxInstruction_c
*i
)
448 Bit64u op1_64
, result_64
;
452 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
454 /* pointer, segment address pair */
455 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
465 result_64
= (op1_64
>> count
);
467 write_RMW_virtual_qword(result_64
);
469 cf
= (op1_64
>> (count
- 1)) & 0x1;
470 // note, that of == result63 if count == 1 and
471 // of == 0 if count >= 2
472 of
= ((result_64
<< 1) ^ result_64
) >> 63;
474 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
475 SET_FLAGS_OxxxxC(of
, cf
);
478 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHR_EqR(bxInstruction_c
*i
)
480 Bit64u op1_64
, result_64
;
492 op1_64
= BX_READ_64BIT_REG(i
->rm());
493 result_64
= (op1_64
>> count
);
494 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
496 cf
= (op1_64
>> (count
- 1)) & 0x1;
497 // note, that of == result63 if count == 1 and
498 // of == 0 if count >= 2
499 of
= ((result_64
<< 1) ^ result_64
) >> 63;
501 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
502 SET_FLAGS_OxxxxC(of
, cf
);
505 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EqM(bxInstruction_c
*i
)
507 Bit64u op1_64
, result_64
;
510 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
512 /* pointer, segment address pair */
513 op1_64
= read_RMW_virtual_qword_64(i
->seg(), eaddr
);
523 /* count < 64, since only lower 6 bits used */
524 if (op1_64
& BX_CONST64(0x8000000000000000)) {
525 result_64
= (op1_64
>> count
) | (BX_CONST64(0xffffffffffffffff) << (64 - count
));
528 result_64
= (op1_64
>> count
);
531 write_RMW_virtual_qword(result_64
);
533 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
534 set_CF((op1_64
>> (count
- 1)) & 1);
535 clear_OF(); /* signed overflow cannot happen in SAR instruction */
538 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SAR_EqR(bxInstruction_c
*i
)
540 Bit64u op1_64
, result_64
;
551 op1_64
= BX_READ_64BIT_REG(i
->rm());
553 /* count < 64, since only lower 6 bits used */
554 if (op1_64
& BX_CONST64(0x8000000000000000)) {
555 result_64
= (op1_64
>> count
) | (BX_CONST64(0xffffffffffffffff) << (64 - count
));
558 result_64
= (op1_64
>> count
);
561 BX_WRITE_64BIT_REG(i
->rm(), result_64
);
563 SET_FLAGS_OSZAPC_LOGIC_64(result_64
); /* handle SF, ZF and AF flags */
564 set_CF((op1_64
>> (count
- 1)) & 1);
565 clear_OF(); /* signed overflow cannot happen in SAR instruction */
568 #endif /* if BX_SUPPORT_X86_64 */