- added instructions how to update the online documentation
[bochs-mirror.git] / cpu / shift32.cc
blobe4d0b84fafb5563d0d178ed43353f0a6f50a9dbc
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift32.cc,v 1.47 2008/09/19 19:18:57 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 void BX_CPP_AttrRegparmN(1) BX_CPU_C::SHLD_EdGdM(bxInstruction_c *i)
35 Bit32u op1_32, op2_32, result_32;
36 unsigned count;
37 unsigned of, cf;
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
45 count = i->Ib();
46 else // 0x1a5
47 count = CL;
49 count &= 0x1f; // use only 5 LSB's
50 if (!count) return;
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;
68 unsigned count;
69 unsigned of, cf;
71 if (i->b1() == 0xa4) // 0x1a4
72 count = i->Ib();
73 else // 0x1a5
74 count = CL;
76 count &= 0x1f; // use only 5 LSB's
77 if (!count) return;
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;
96 unsigned count;
97 unsigned cf, of;
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
105 count = i->Ib();
106 else // 0x1ad
107 count = CL;
109 count &= 0x1f; // use only 5 LSB's
110 if (!count) return;
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;
128 unsigned count;
129 unsigned cf, of;
131 if (i->b1() == 0xac) // 0x1ac
132 count = i->Ib();
133 else // 0x1ad
134 count = CL;
136 count &= 0x1f; // use only 5 LSB's
137 if (!count) return;
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;
156 unsigned count;
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);
163 if (i->b1() == 0xd3)
164 count = CL;
165 else // 0xc1 or 0xd1
166 count = i->Ib();
168 count &= 0x1f;
169 if (! count) return;
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;
184 unsigned count;
185 unsigned bit0, bit31;
187 if (i->b1() == 0xd3)
188 count = CL;
189 else // 0xc1 or 0xd1
190 count = i->Ib();
192 count &= 0x1f;
193 if (! count) return;
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;
208 unsigned count;
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);
216 if (i->b1() == 0xd3)
217 count = CL;
218 else // 0xc1 or 0xd1
219 count = i->Ib();
221 count &= 0x1f;
222 if (! count) return;
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;
237 unsigned count;
238 unsigned bit31, bit30;
240 if (i->b1() == 0xd3)
241 count = CL;
242 else // 0xc1 or 0xd1
243 count = i->Ib();
245 count &= 0x1f;
246 if (! count) return;
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;
261 unsigned count;
262 unsigned cf, of;
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);
269 if (i->b1() == 0xd3)
270 count = CL;
271 else // 0xc1 or 0xd1
272 count = i->Ib();
274 count &= 0x1f;
275 if (!count) return;
277 if (count==1) {
278 result_32 = (op1_32 << 1) | getB_CF();
280 else {
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;
295 unsigned count;
296 unsigned cf, of;
298 if (i->b1() == 0xd3)
299 count = CL;
300 else // 0xc1 or 0xd1
301 count = i->Ib();
303 count &= 0x1f;
304 if (!count) return;
306 op1_32 = BX_READ_32BIT_REG(i->rm());
308 if (count==1) {
309 result_32 = (op1_32 << 1) | getB_CF();
311 else {
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;
326 unsigned count;
327 unsigned cf, of;
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);
334 if (i->b1() == 0xd3)
335 count = CL;
336 else // 0xc1 or 0xd1
337 count = i->Ib();
339 count &= 0x1f;
340 if (!count) return;
342 if (count==1) {
343 result_32 = (op1_32 >> 1) | (getB_CF() << 31);
345 else {
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;
360 unsigned count;
361 unsigned cf, of;
363 if (i->b1() == 0xd3)
364 count = CL;
365 else // 0xc1 or 0xd1
366 count = i->Ib();
368 count &= 0x1f;
369 if (!count) return;
371 op1_32 = BX_READ_32BIT_REG(i->rm());
373 if (count==1) {
374 result_32 = (op1_32 >> 1) | (getB_CF() << 31);
376 else {
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;
391 unsigned count;
392 unsigned cf, of;
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);
399 if (i->b1() == 0xd3)
400 count = CL;
401 else // 0xc1 or 0xd1
402 count = i->Ib();
404 count &= 0x1f;
405 if (!count) return;
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;
421 unsigned count;
422 unsigned cf, of;
424 if (i->b1() == 0xd3)
425 count = CL;
426 else // 0xc1 or 0xd1
427 count = i->Ib();
429 count &= 0x1f;
430 if (!count) return;
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;
448 unsigned count;
449 unsigned of, cf;
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);
456 if (i->b1() == 0xd3)
457 count = CL;
458 else // 0xc1 or 0xd1
459 count = i->Ib();
461 count &= 0x1f;
462 if (!count) return;
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;
480 unsigned count;
481 unsigned of, cf;
483 if (i->b1() == 0xd3)
484 count = CL;
485 else // 0xc1 or 0xd1
486 count = i->Ib();
488 count &= 0x1f;
489 if (!count) return;
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;
507 unsigned count;
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);
514 if (i->b1() == 0xd3)
515 count = CL;
516 else // 0xc1 or 0xd1
517 count = i->Ib();
519 count &= 0x1f;
520 if (!count) return;
522 /* count < 32, since only lower 5 bits used */
523 if (op1_32 & 0x80000000) {
524 result_32 = (op1_32 >> count) | (0xffffffff << (32 - count));
526 else {
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;
540 unsigned count;
542 if (i->b1() == 0xd3)
543 count = CL;
544 else // 0xc1 or 0xd1
545 count = i->Ib();
547 count &= 0x1f;
548 if (!count) return;
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));
556 else {
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 */