- compilation fixes for MSVC toolkit 2003
[bochs-mirror.git] / cpu / shift64.cc
bloba014cce80dd519ff2625dfadc1f5d366c8108fbd
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift64.cc,v 1.38 2008/08/08 09:22:48 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
35 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EqGqM(bxInstruction_c *i)
37 Bit64u op1_64, op2_64, result_64;
38 unsigned count;
39 unsigned cf, of;
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
47 count = i->Ib();
48 else // 0x1a5
49 count = CL;
51 count &= 0x3f; // use only 6 LSB's
52 if (!count) return;
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;
70 unsigned count;
71 unsigned cf, of;
73 if (i->b1() == 0xa4) // 0x1a4
74 count = i->Ib();
75 else // 0x1a5
76 count = CL;
78 count &= 0x3f; // use only 6 LSB's
79 if (!count) return;
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;
98 unsigned count;
99 unsigned cf, of;
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
107 count = i->Ib();
108 else // 0x1ad
109 count = CL;
111 count &= 0x3f; // use only 6 LSB's
112 if (!count) return;
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;
130 unsigned count;
131 unsigned cf, of;
133 if (i->b1() == 0xac) // 0x1ac
134 count = i->Ib();
135 else // 0x1ad
136 count = CL;
138 count &= 0x3f; // use only 6 LSB's
139 if (!count) return;
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;
158 unsigned count;
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);
166 if (i->b1() == 0xd3)
167 count = CL;
168 else // 0xc1 or 0xd1
169 count = i->Ib();
171 count &= 0x3f;
172 if (! count) return;
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;
187 unsigned count;
188 unsigned bit0, bit63;
190 if (i->b1() == 0xd3)
191 count = CL;
192 else // 0xc1 or 0xd1
193 count = i->Ib();
195 count &= 0x3f;
196 if (! count) return;
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;
211 unsigned count;
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);
219 if (i->b1() == 0xd3)
220 count = CL;
221 else // 0xc1 or 0xd1
222 count = i->Ib();
224 count &= 0x3f;
225 if (! count) return;
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;
240 unsigned count;
241 unsigned bit62, bit63;
243 if (i->b1() == 0xd3)
244 count = CL;
245 else // 0xc1 or 0xd1
246 count = i->Ib();
248 count &= 0x3f;
249 if (! count) return;
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;
264 unsigned count;
265 unsigned cf, of;
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);
272 if (i->b1() == 0xd3)
273 count = CL;
274 else // 0xc1 or 0xd1
275 count = i->Ib();
277 count &= 0x3f;
278 if (!count) return;
280 if (count==1) {
281 result_64 = (op1_64 << 1) | getB_CF();
283 else {
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;
298 unsigned count;
299 unsigned cf, of;
301 if (i->b1() == 0xd3)
302 count = CL;
303 else // 0xc1 or 0xd1
304 count = i->Ib();
306 count &= 0x3f;
307 if (!count) return;
309 op1_64 = BX_READ_64BIT_REG(i->rm());
311 if (count==1) {
312 result_64 = (op1_64 << 1) | getB_CF();
314 else {
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;
329 unsigned count;
330 unsigned of, cf;
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);
337 if (i->b1() == 0xd3)
338 count = CL;
339 else // 0xc1 or 0xd1
340 count = i->Ib();
342 count &= 0x3f;
343 if (!count) return;
345 if (count==1) {
346 result_64 = (op1_64 >> 1) | (((Bit64u) getB_CF()) << 63);
348 else {
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;
363 unsigned count;
364 unsigned of, cf;
366 if (i->b1() == 0xd3)
367 count = CL;
368 else // 0xc1 or 0xd1
369 count = i->Ib();
371 count &= 0x3f;
372 if (!count) return;
374 op1_64 = BX_READ_64BIT_REG(i->rm());
376 if (count==1) {
377 result_64 = (op1_64 >> 1) | (((Bit64u) getB_CF()) << 63);
379 else {
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;
394 unsigned count;
395 unsigned cf, of;
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);
402 if (i->b1() == 0xd3)
403 count = CL;
404 else // 0xc1 or 0xd1
405 count = i->Ib();
407 count &= 0x3f;
408 if (!count) return;
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;
424 unsigned count;
425 unsigned cf, of;
427 if (i->b1() == 0xd3)
428 count = CL;
429 else // 0xc1 or 0xd1
430 count = i->Ib();
432 count &= 0x3f;
433 if (!count) return;
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;
449 unsigned count;
450 unsigned cf, of;
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);
457 if (i->b1() == 0xd3)
458 count = CL;
459 else // 0xc1 or 0xd1
460 count = i->Ib();
462 count &= 0x3f;
463 if (!count) return;
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;
481 unsigned count;
482 unsigned cf, of;
484 if (i->b1() == 0xd3)
485 count = CL;
486 else // 0xc1 or 0xd1
487 count = i->Ib();
489 count &= 0x3f;
490 if (!count) return;
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;
508 unsigned count;
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);
515 if (i->b1() == 0xd3)
516 count = CL;
517 else // 0xc1 or 0xd1
518 count = i->Ib();
520 count &= 0x3f;
521 if (!count) return;
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));
527 else {
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;
541 unsigned count;
543 if (i->b1() == 0xd3)
544 count = CL;
545 else // 0xc1 or 0xd1
546 count = i->Ib();
548 count &= 0x3f;
549 if (!count) return;
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));
557 else {
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 */