This is a BIOS emulator, porting from SciTech for u-boot, mainly for
[platform/kernel/u-boot.git] / drivers / bios_emulator / x86emu / prim_ops.c
1 /****************************************************************************
2 *
3 *                       Realmode X86 Emulator Library
4 *
5 *               Copyright (C) 1991-2004 SciTech Software, Inc.
6 *                    Copyright (C) David Mosberger-Tang
7 *                      Copyright (C) 1999 Egbert Eich
8 *
9 *  ========================================================================
10 *
11 *  Permission to use, copy, modify, distribute, and sell this software and
12 *  its documentation for any purpose is hereby granted without fee,
13 *  provided that the above copyright notice appear in all copies and that
14 *  both that copyright notice and this permission notice appear in
15 *  supporting documentation, and that the name of the authors not be used
16 *  in advertising or publicity pertaining to distribution of the software
17 *  without specific, written prior permission.  The authors makes no
18 *  representations about the suitability of this software for any purpose.
19 *  It is provided "as is" without express or implied warranty.
20 *
21 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 *  PERFORMANCE OF THIS SOFTWARE.
28 *
29 *  ========================================================================
30 *
31 * Language:     ANSI C
32 * Environment:  Any
33 * Developer:    Kendall Bennett
34 *
35 * Description:  This file contains the code to implement the primitive
36 *               machine operations used by the emulation code in ops.c
37 *
38 * Carry Chain Calculation
39 *
40 * This represents a somewhat expensive calculation which is
41 * apparently required to emulate the setting of the OF343364 and AF flag.
42 * The latter is not so important, but the former is.  The overflow
43 * flag is the XOR of the top two bits of the carry chain for an
44 * addition (similar for subtraction).  Since we do not want to
45 * simulate the addition in a bitwise manner, we try to calculate the
46 * carry chain given the two operands and the result.
47 *
48 * So, given the following table, which represents the addition of two
49 * bits, we can derive a formula for the carry chain.
50 *
51 * a   b   cin   r     cout
52 * 0   0   0     0     0
53 * 0   0   1     1     0
54 * 0   1   0     1     0
55 * 0   1   1     0     1
56 * 1   0   0     1     0
57 * 1   0   1     0     1
58 * 1   1   0     0     1
59 * 1   1   1     1     1
60 *
61 * Construction of table for cout:
62 *
63 * ab
64 * r  \  00   01   11  10
65 * |------------------
66 * 0  |   0    1    1   1
67 * 1  |   0    0    1   0
68 *
69 * By inspection, one gets:  cc = ab +  r'(a + b)
70 *
71 * That represents alot of operations, but NO CHOICE....
72 *
73 * Borrow Chain Calculation.
74 *
75 * The following table represents the subtraction of two bits, from
76 * which we can derive a formula for the borrow chain.
77 *
78 * a   b   bin   r     bout
79 * 0   0   0     0     0
80 * 0   0   1     1     1
81 * 0   1   0     1     1
82 * 0   1   1     0     1
83 * 1   0   0     1     0
84 * 1   0   1     0     0
85 * 1   1   0     0     0
86 * 1   1   1     1     1
87 *
88 * Construction of table for cout:
89 *
90 * ab
91 * r  \  00   01   11  10
92 * |------------------
93 * 0  |   0    1    0   0
94 * 1  |   1    1    1   0
95 *
96 * By inspection, one gets:  bc = a'b +  r(a' + b)
97 *
98 ****************************************************************************/
99
100 #define PRIM_OPS_NO_REDEFINE_ASM
101 #include "x86emu/x86emui.h"
102
103 /*------------------------- Global Variables ------------------------------*/
104
105 static u32 x86emu_parity_tab[8] =
106 {
107     0x96696996,
108     0x69969669,
109     0x69969669,
110     0x96696996,
111     0x69969669,
112     0x96696996,
113     0x96696996,
114     0x69969669,
115 };
116
117 #define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
118 #define XOR2(x)     (((x) ^ ((x)>>1)) & 0x1)
119 /*----------------------------- Implementation ----------------------------*/
120 int abs(int v)
121 {
122         return (v>0)?v:-v;
123 }
124
125 /*----------------------------- Implementation ----------------------------*/
126
127
128 /*--------- Side effects helper functions -------*/
129
130 /****************************************************************************
131 REMARKS:
132 implements side efects for byte operations that don't overflow
133 ****************************************************************************/
134
135 static void set_parity_flag(u32 res)
136 {
137     CONDITIONAL_SET_FLAG(PARITY(res & 0xFF), F_PF);
138 }
139
140 static void set_szp_flags_8(u8 res)
141 {
142     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
143     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
144     set_parity_flag(res);
145 }
146
147 static void set_szp_flags_16(u16 res)
148 {
149     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
150     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
151     set_parity_flag(res);
152 }
153
154 static void set_szp_flags_32(u32 res)
155 {
156     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
157     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
158     set_parity_flag(res);
159 }
160
161 static void no_carry_byte_side_eff(u8 res)
162 {
163     CLEAR_FLAG(F_OF);
164     CLEAR_FLAG(F_CF);
165     CLEAR_FLAG(F_AF);
166     set_szp_flags_8(res);
167 }
168
169 static void no_carry_word_side_eff(u16 res)
170 {
171     CLEAR_FLAG(F_OF);
172     CLEAR_FLAG(F_CF);
173     CLEAR_FLAG(F_AF);
174     set_szp_flags_16(res);
175 }
176
177 static void no_carry_long_side_eff(u32 res)
178 {
179     CLEAR_FLAG(F_OF);
180     CLEAR_FLAG(F_CF);
181     CLEAR_FLAG(F_AF);
182     set_szp_flags_32(res);
183 }
184
185 static void calc_carry_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
186 {
187     u32 cc;
188
189     cc = (s & d) | ((~res) & (s | d));
190     CONDITIONAL_SET_FLAG(XOR2(cc >> (bits - 2)), F_OF);
191     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
192     if (set_carry) {
193         CONDITIONAL_SET_FLAG(res & (1 << bits), F_CF);
194     }
195 }
196
197 static void calc_borrow_chain(int bits, u32 d, u32 s, u32 res, int set_carry)
198 {
199     u32 bc;
200
201     bc = (res & (~d | s)) | (~d & s);
202     CONDITIONAL_SET_FLAG(XOR2(bc >> (bits - 2)), F_OF);
203     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
204     if (set_carry) {
205         CONDITIONAL_SET_FLAG(bc & (1 << (bits - 1)), F_CF);
206     }
207 }
208
209 /****************************************************************************
210 REMARKS:
211 Implements the AAA instruction and side effects.
212 ****************************************************************************/
213 u16 aaa_word(u16 d)
214 {
215     u16 res;
216     if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
217         d += 0x6;
218         d += 0x100;
219         SET_FLAG(F_AF);
220         SET_FLAG(F_CF);
221     } else {
222         CLEAR_FLAG(F_CF);
223         CLEAR_FLAG(F_AF);
224     }
225     res = (u16)(d & 0xFF0F);
226     set_szp_flags_16(res);
227     return res;
228 }
229
230 /****************************************************************************
231 REMARKS:
232 Implements the AAA instruction and side effects.
233 ****************************************************************************/
234 u16 aas_word(u16 d)
235 {
236     u16 res;
237     if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
238         d -= 0x6;
239         d -= 0x100;
240         SET_FLAG(F_AF);
241         SET_FLAG(F_CF);
242     } else {
243         CLEAR_FLAG(F_CF);
244         CLEAR_FLAG(F_AF);
245     }
246     res = (u16)(d & 0xFF0F);
247     set_szp_flags_16(res);
248     return res;
249 }
250
251 /****************************************************************************
252 REMARKS:
253 Implements the AAD instruction and side effects.
254 ****************************************************************************/
255 u16 aad_word(u16 d)
256 {
257     u16 l;
258     u8 hb, lb;
259
260     hb = (u8)((d >> 8) & 0xff);
261     lb = (u8)((d & 0xff));
262     l = (u16)((lb + 10 * hb) & 0xFF);
263
264     no_carry_byte_side_eff(l & 0xFF);
265     return l;
266 }
267
268 /****************************************************************************
269 REMARKS:
270 Implements the AAM instruction and side effects.
271 ****************************************************************************/
272 u16 aam_word(u8 d)
273 {
274     u16 h, l;
275
276     h = (u16)(d / 10);
277     l = (u16)(d % 10);
278     l |= (u16)(h << 8);
279
280     no_carry_byte_side_eff(l & 0xFF);
281     return l;
282 }
283
284 /****************************************************************************
285 REMARKS:
286 Implements the ADC instruction and side effects.
287 ****************************************************************************/
288 u8 adc_byte(u8 d, u8 s)
289 {
290     u32 res;   /* all operands in native machine order */
291
292     res = d + s;
293     if (ACCESS_FLAG(F_CF)) res++;
294
295     set_szp_flags_8(res);
296     calc_carry_chain(8,s,d,res,1);
297
298     return (u8)res;
299 }
300
301 /****************************************************************************
302 REMARKS:
303 Implements the ADC instruction and side effects.
304 ****************************************************************************/
305 u16 adc_word(u16 d, u16 s)
306 {
307     u32 res;   /* all operands in native machine order */
308
309     res = d + s;
310     if (ACCESS_FLAG(F_CF))
311         res++;
312
313     set_szp_flags_16((u16)res);
314     calc_carry_chain(16,s,d,res,1);
315
316     return (u16)res;
317 }
318
319 /****************************************************************************
320 REMARKS:
321 Implements the ADC instruction and side effects.
322 ****************************************************************************/
323 u32 adc_long(u32 d, u32 s)
324 {
325     u32 lo;    /* all operands in native machine order */
326     u32 hi;
327     u32 res;
328
329     lo = (d & 0xFFFF) + (s & 0xFFFF);
330     res = d + s;
331
332     if (ACCESS_FLAG(F_CF)) {
333         lo++;
334         res++;
335     }
336
337     hi = (lo >> 16) + (d >> 16) + (s >> 16);
338
339     set_szp_flags_32(res);
340     calc_carry_chain(32,s,d,res,0);
341
342     CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
343
344     return res;
345 }
346
347 /****************************************************************************
348 REMARKS:
349 Implements the ADD instruction and side effects.
350 ****************************************************************************/
351 u8 add_byte(u8 d, u8 s)
352 {
353     u32 res;   /* all operands in native machine order */
354
355     res = d + s;
356     set_szp_flags_8((u8)res);
357     calc_carry_chain(8,s,d,res,1);
358
359     return (u8)res;
360 }
361
362 /****************************************************************************
363 REMARKS:
364 Implements the ADD instruction and side effects.
365 ****************************************************************************/
366 u16 add_word(u16 d, u16 s)
367 {
368     u32 res;   /* all operands in native machine order */
369
370     res = d + s;
371     set_szp_flags_16((u16)res);
372     calc_carry_chain(16,s,d,res,1);
373
374     return (u16)res;
375 }
376
377 /****************************************************************************
378 REMARKS:
379 Implements the ADD instruction and side effects.
380 ****************************************************************************/
381 u32 add_long(u32 d, u32 s)
382 {
383     u32 res;
384
385     res = d + s;
386     set_szp_flags_32(res);
387     calc_carry_chain(32,s,d,res,0);
388
389     CONDITIONAL_SET_FLAG(res < d || res < s, F_CF);
390
391     return res;
392 }
393
394 /****************************************************************************
395 REMARKS:
396 Implements the AND instruction and side effects.
397 ****************************************************************************/
398 u8 and_byte(u8 d, u8 s)
399 {
400     u8 res;    /* all operands in native machine order */
401
402     res = d & s;
403
404     no_carry_byte_side_eff(res);
405     return res;
406 }
407
408 /****************************************************************************
409 REMARKS:
410 Implements the AND instruction and side effects.
411 ****************************************************************************/
412 u16 and_word(u16 d, u16 s)
413 {
414     u16 res;   /* all operands in native machine order */
415
416     res = d & s;
417
418     no_carry_word_side_eff(res);
419     return res;
420 }
421
422 /****************************************************************************
423 REMARKS:
424 Implements the AND instruction and side effects.
425 ****************************************************************************/
426 u32 and_long(u32 d, u32 s)
427 {
428     u32 res;   /* all operands in native machine order */
429
430     res = d & s;
431     no_carry_long_side_eff(res);
432     return res;
433 }
434
435 /****************************************************************************
436 REMARKS:
437 Implements the CMP instruction and side effects.
438 ****************************************************************************/
439 u8 cmp_byte(u8 d, u8 s)
440 {
441     u32 res;   /* all operands in native machine order */
442
443     res = d - s;
444     set_szp_flags_8((u8)res);
445     calc_borrow_chain(8, d, s, res, 1);
446
447     return d;
448 }
449
450 /****************************************************************************
451 REMARKS:
452 Implements the CMP instruction and side effects.
453 ****************************************************************************/
454 u16 cmp_word(u16 d, u16 s)
455 {
456     u32 res;   /* all operands in native machine order */
457
458     res = d - s;
459     set_szp_flags_16((u16)res);
460     calc_borrow_chain(16, d, s, res, 1);
461
462     return d;
463 }
464
465 /****************************************************************************
466 REMARKS:
467 Implements the CMP instruction and side effects.
468 ****************************************************************************/
469 u32 cmp_long(u32 d, u32 s)
470 {
471     u32 res;   /* all operands in native machine order */
472
473     res = d - s;
474     set_szp_flags_32(res);
475     calc_borrow_chain(32, d, s, res, 1);
476
477     return d;
478 }
479
480 /****************************************************************************
481 REMARKS:
482 Implements the DAA instruction and side effects.
483 ****************************************************************************/
484 u8 daa_byte(u8 d)
485 {
486     u32 res = d;
487     if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
488         res += 6;
489         SET_FLAG(F_AF);
490     }
491     if (res > 0x9F || ACCESS_FLAG(F_CF)) {
492         res += 0x60;
493         SET_FLAG(F_CF);
494     }
495     set_szp_flags_8((u8)res);
496     return (u8)res;
497 }
498
499 /****************************************************************************
500 REMARKS:
501 Implements the DAS instruction and side effects.
502 ****************************************************************************/
503 u8 das_byte(u8 d)
504 {
505     if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
506         d -= 6;
507         SET_FLAG(F_AF);
508     }
509     if (d > 0x9F || ACCESS_FLAG(F_CF)) {
510         d -= 0x60;
511         SET_FLAG(F_CF);
512     }
513     set_szp_flags_8(d);
514     return d;
515 }
516
517 /****************************************************************************
518 REMARKS:
519 Implements the DEC instruction and side effects.
520 ****************************************************************************/
521 u8 dec_byte(u8 d)
522 {
523     u32 res;   /* all operands in native machine order */
524
525     res = d - 1;
526     set_szp_flags_8((u8)res);
527     calc_borrow_chain(8, d, 1, res, 0);
528
529     return (u8)res;
530 }
531
532 /****************************************************************************
533 REMARKS:
534 Implements the DEC instruction and side effects.
535 ****************************************************************************/
536 u16 dec_word(u16 d)
537 {
538     u32 res;   /* all operands in native machine order */
539
540     res = d - 1;
541     set_szp_flags_16((u16)res);
542     calc_borrow_chain(16, d, 1, res, 0);
543
544     return (u16)res;
545 }
546
547 /****************************************************************************
548 REMARKS:
549 Implements the DEC instruction and side effects.
550 ****************************************************************************/
551 u32 dec_long(u32 d)
552 {
553     u32 res;   /* all operands in native machine order */
554
555     res = d - 1;
556
557     set_szp_flags_32(res);
558     calc_borrow_chain(32, d, 1, res, 0);
559
560     return res;
561 }
562
563 /****************************************************************************
564 REMARKS:
565 Implements the INC instruction and side effects.
566 ****************************************************************************/
567 u8 inc_byte(u8 d)
568 {
569     u32 res;   /* all operands in native machine order */
570
571     res = d + 1;
572     set_szp_flags_8((u8)res);
573     calc_carry_chain(8, d, 1, res, 0);
574
575     return (u8)res;
576 }
577
578 /****************************************************************************
579 REMARKS:
580 Implements the INC instruction and side effects.
581 ****************************************************************************/
582 u16 inc_word(u16 d)
583 {
584     u32 res;   /* all operands in native machine order */
585
586     res = d + 1;
587     set_szp_flags_16((u16)res);
588     calc_carry_chain(16, d, 1, res, 0);
589
590     return (u16)res;
591 }
592
593 /****************************************************************************
594 REMARKS:
595 Implements the INC instruction and side effects.
596 ****************************************************************************/
597 u32 inc_long(u32 d)
598 {
599     u32 res;   /* all operands in native machine order */
600
601     res = d + 1;
602     set_szp_flags_32(res);
603     calc_carry_chain(32, d, 1, res, 0);
604
605     return res;
606 }
607
608 /****************************************************************************
609 REMARKS:
610 Implements the OR instruction and side effects.
611 ****************************************************************************/
612 u8 or_byte(u8 d, u8 s)
613 {
614     u8 res;    /* all operands in native machine order */
615
616     res = d | s;
617     no_carry_byte_side_eff(res);
618
619     return res;
620 }
621
622 /****************************************************************************
623 REMARKS:
624 Implements the OR instruction and side effects.
625 ****************************************************************************/
626 u16 or_word(u16 d, u16 s)
627 {
628     u16 res;   /* all operands in native machine order */
629
630     res = d | s;
631     no_carry_word_side_eff(res);
632     return res;
633 }
634
635 /****************************************************************************
636 REMARKS:
637 Implements the OR instruction and side effects.
638 ****************************************************************************/
639 u32 or_long(u32 d, u32 s)
640 {
641     u32 res;   /* all operands in native machine order */
642
643     res = d | s;
644     no_carry_long_side_eff(res);
645     return res;
646 }
647
648 /****************************************************************************
649 REMARKS:
650 Implements the OR instruction and side effects.
651 ****************************************************************************/
652 u8 neg_byte(u8 s)
653 {
654     u8 res;
655
656     CONDITIONAL_SET_FLAG(s != 0, F_CF);
657     res = (u8)-s;
658     set_szp_flags_8(res);
659     calc_borrow_chain(8, 0, s, res, 0);
660
661     return res;
662 }
663
664 /****************************************************************************
665 REMARKS:
666 Implements the OR instruction and side effects.
667 ****************************************************************************/
668 u16 neg_word(u16 s)
669 {
670     u16 res;
671
672     CONDITIONAL_SET_FLAG(s != 0, F_CF);
673     res = (u16)-s;
674     set_szp_flags_16((u16)res);
675     calc_borrow_chain(16, 0, s, res, 0);
676
677     return res;
678 }
679
680 /****************************************************************************
681 REMARKS:
682 Implements the OR instruction and side effects.
683 ****************************************************************************/
684 u32 neg_long(u32 s)
685 {
686     u32 res;
687
688     CONDITIONAL_SET_FLAG(s != 0, F_CF);
689     res = (u32)-s;
690     set_szp_flags_32(res);
691     calc_borrow_chain(32, 0, s, res, 0);
692
693     return res;
694 }
695
696 /****************************************************************************
697 REMARKS:
698 Implements the NOT instruction and side effects.
699 ****************************************************************************/
700 u8 not_byte(u8 s)
701 {
702     return ~s;
703 }
704
705 /****************************************************************************
706 REMARKS:
707 Implements the NOT instruction and side effects.
708 ****************************************************************************/
709 u16 not_word(u16 s)
710 {
711     return ~s;
712 }
713
714 /****************************************************************************
715 REMARKS:
716 Implements the NOT instruction and side effects.
717 ****************************************************************************/
718 u32 not_long(u32 s)
719 {
720     return ~s;
721 }
722
723 /****************************************************************************
724 REMARKS:
725 Implements the RCL instruction and side effects.
726 ****************************************************************************/
727 u8 rcl_byte(u8 d, u8 s)
728 {
729     unsigned int res, cnt, mask, cf;
730
731     /* s is the rotate distance.  It varies from 0 - 8. */
732     /* have
733
734        CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
735
736        want to rotate through the carry by "s" bits.  We could
737        loop, but that's inefficient.  So the width is 9,
738        and we split into three parts:
739
740        The new carry flag   (was B_n)
741        the stuff in B_n-1 .. B_0
742        the stuff in B_7 .. B_n+1
743
744        The new rotate is done mod 9, and given this,
745        for a rotation of n bits (mod 9) the new carry flag is
746        then located n bits from the MSB.  The low part is
747        then shifted up cnt bits, and the high part is or'd
748        in.  Using CAPS for new values, and lowercase for the
749        original values, this can be expressed as:
750
751        IF n > 0
752        1) CF <-  b_(8-n)
753        2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
754        3) B_(n-1) <- cf
755        4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
756      */
757     res = d;
758     if ((cnt = s % 9) != 0) {
759         /* extract the new CARRY FLAG. */
760         /* CF <-  b_(8-n)             */
761         cf = (d >> (8 - cnt)) & 0x1;
762
763         /* get the low stuff which rotated
764            into the range B_7 .. B_cnt */
765         /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
766         /* note that the right hand side done by the mask */
767         res = (d << cnt) & 0xff;
768
769         /* now the high stuff which rotated around
770            into the positions B_cnt-2 .. B_0 */
771         /* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
772         /* shift it downward, 7-(n-2) = 9-n positions.
773            and mask off the result before or'ing in.
774          */
775         mask = (1 << (cnt - 1)) - 1;
776         res |= (d >> (9 - cnt)) & mask;
777
778         /* if the carry flag was set, or it in.  */
779         if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
780             /*  B_(n-1) <- cf */
781             res |= 1 << (cnt - 1);
782         }
783         /* set the new carry flag, based on the variable "cf" */
784         CONDITIONAL_SET_FLAG(cf, F_CF);
785         /* OVERFLOW is set *IFF* cnt==1, then it is the
786            xor of CF and the most significant bit.  Blecck. */
787         /* parenthesized this expression since it appears to
788            be causing OF to be misset */
789         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
790                              F_OF);
791
792     }
793     return (u8)res;
794 }
795
796 /****************************************************************************
797 REMARKS:
798 Implements the RCL instruction and side effects.
799 ****************************************************************************/
800 u16 rcl_word(u16 d, u8 s)
801 {
802     unsigned int res, cnt, mask, cf;
803
804     res = d;
805     if ((cnt = s % 17) != 0) {
806         cf = (d >> (16 - cnt)) & 0x1;
807         res = (d << cnt) & 0xffff;
808         mask = (1 << (cnt - 1)) - 1;
809         res |= (d >> (17 - cnt)) & mask;
810         if (ACCESS_FLAG(F_CF)) {
811             res |= 1 << (cnt - 1);
812         }
813         CONDITIONAL_SET_FLAG(cf, F_CF);
814         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
815                              F_OF);
816     }
817     return (u16)res;
818 }
819
820 /****************************************************************************
821 REMARKS:
822 Implements the RCL instruction and side effects.
823 ****************************************************************************/
824 u32 rcl_long(u32 d, u8 s)
825 {
826     u32 res, cnt, mask, cf;
827
828     res = d;
829     if ((cnt = s % 33) != 0) {
830         cf = (d >> (32 - cnt)) & 0x1;
831         res = (d << cnt) & 0xffffffff;
832         mask = (1 << (cnt - 1)) - 1;
833         res |= (d >> (33 - cnt)) & mask;
834         if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
835             res |= 1 << (cnt - 1);
836         }
837         CONDITIONAL_SET_FLAG(cf, F_CF);
838         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
839                              F_OF);
840     }
841     return res;
842 }
843
844 /****************************************************************************
845 REMARKS:
846 Implements the RCR instruction and side effects.
847 ****************************************************************************/
848 u8 rcr_byte(u8 d, u8 s)
849 {
850     u32 res, cnt;
851     u32 mask, cf, ocf = 0;
852
853     /* rotate right through carry */
854     /*
855        s is the rotate distance.  It varies from 0 - 8.
856        d is the byte object rotated.
857
858        have
859
860        CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
861
862        The new rotate is done mod 9, and given this,
863        for a rotation of n bits (mod 9) the new carry flag is
864        then located n bits from the LSB.  The low part is
865        then shifted up cnt bits, and the high part is or'd
866        in.  Using CAPS for new values, and lowercase for the
867        original values, this can be expressed as:
868
869        IF n > 0
870        1) CF <-  b_(n-1)
871        2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
872        3) B_(8-n) <- cf
873        4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0)
874      */
875     res = d;
876     if ((cnt = s % 9) != 0) {
877         /* extract the new CARRY FLAG. */
878         /* CF <-  b_(n-1)              */
879         if (cnt == 1) {
880             cf = d & 0x1;
881             /* note hackery here.  Access_flag(..) evaluates to either
882                0 if flag not set
883                non-zero if flag is set.
884                doing access_flag(..) != 0 casts that into either
885                0..1 in any representation of the flags register
886                (i.e. packed bit array or unpacked.)
887              */
888             ocf = ACCESS_FLAG(F_CF) != 0;
889         } else
890             cf = (d >> (cnt - 1)) & 0x1;
891
892         /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
893         /* note that the right hand side done by the mask
894            This is effectively done by shifting the
895            object to the right.  The result must be masked,
896            in case the object came in and was treated
897            as a negative number.  Needed??? */
898
899         mask = (1 << (8 - cnt)) - 1;
900         res = (d >> cnt) & mask;
901
902         /* now the high stuff which rotated around
903            into the positions B_cnt-2 .. B_0 */
904         /* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
905         /* shift it downward, 7-(n-2) = 9-n positions.
906            and mask off the result before or'ing in.
907          */
908         res |= (d << (9 - cnt));
909
910         /* if the carry flag was set, or it in.  */
911         if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
912             /*  B_(8-n) <- cf */
913             res |= 1 << (8 - cnt);
914         }
915         /* set the new carry flag, based on the variable "cf" */
916         CONDITIONAL_SET_FLAG(cf, F_CF);
917         /* OVERFLOW is set *IFF* cnt==1, then it is the
918            xor of CF and the most significant bit.  Blecck. */
919         /* parenthesized... */
920         if (cnt == 1) {
921             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
922                                  F_OF);
923         }
924     }
925     return (u8)res;
926 }
927
928 /****************************************************************************
929 REMARKS:
930 Implements the RCR instruction and side effects.
931 ****************************************************************************/
932 u16 rcr_word(u16 d, u8 s)
933 {
934     u32 res, cnt;
935     u32 mask, cf, ocf = 0;
936
937     /* rotate right through carry */
938     res = d;
939     if ((cnt = s % 17) != 0) {
940         if (cnt == 1) {
941             cf = d & 0x1;
942             ocf = ACCESS_FLAG(F_CF) != 0;
943         } else
944             cf = (d >> (cnt - 1)) & 0x1;
945         mask = (1 << (16 - cnt)) - 1;
946         res = (d >> cnt) & mask;
947         res |= (d << (17 - cnt));
948         if (ACCESS_FLAG(F_CF)) {
949             res |= 1 << (16 - cnt);
950         }
951         CONDITIONAL_SET_FLAG(cf, F_CF);
952         if (cnt == 1) {
953             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
954                                  F_OF);
955         }
956     }
957     return (u16)res;
958 }
959
960 /****************************************************************************
961 REMARKS:
962 Implements the RCR instruction and side effects.
963 ****************************************************************************/
964 u32 rcr_long(u32 d, u8 s)
965 {
966     u32 res, cnt;
967     u32 mask, cf, ocf = 0;
968
969     /* rotate right through carry */
970     res = d;
971     if ((cnt = s % 33) != 0) {
972         if (cnt == 1) {
973             cf = d & 0x1;
974             ocf = ACCESS_FLAG(F_CF) != 0;
975         } else
976             cf = (d >> (cnt - 1)) & 0x1;
977         mask = (1 << (32 - cnt)) - 1;
978         res = (d >> cnt) & mask;
979         if (cnt != 1)
980             res |= (d << (33 - cnt));
981         if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
982             res |= 1 << (32 - cnt);
983         }
984         CONDITIONAL_SET_FLAG(cf, F_CF);
985         if (cnt == 1) {
986             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
987                                  F_OF);
988         }
989     }
990     return res;
991 }
992
993 /****************************************************************************
994 REMARKS:
995 Implements the ROL instruction and side effects.
996 ****************************************************************************/
997 u8 rol_byte(u8 d, u8 s)
998 {
999     unsigned int res, cnt, mask;
1000
1001     /* rotate left */
1002     /*
1003        s is the rotate distance.  It varies from 0 - 8.
1004        d is the byte object rotated.
1005
1006        have
1007
1008        CF  B_7 ... B_0
1009
1010        The new rotate is done mod 8.
1011        Much simpler than the "rcl" or "rcr" operations.
1012
1013        IF n > 0
1014        1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0)
1015        2) B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n)
1016      */
1017     res = d;
1018     if ((cnt = s % 8) != 0) {
1019         /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
1020         res = (d << cnt);
1021
1022         /* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
1023         mask = (1 << cnt) - 1;
1024         res |= (d >> (8 - cnt)) & mask;
1025
1026         /* set the new carry flag, Note that it is the low order
1027            bit of the result!!!                               */
1028         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1029         /* OVERFLOW is set *IFF* s==1, then it is the
1030            xor of CF and the most significant bit.  Blecck. */
1031         CONDITIONAL_SET_FLAG(s == 1 &&
1032                              XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1033                              F_OF);
1034     } if (s != 0) {
1035         /* set the new carry flag, Note that it is the low order
1036            bit of the result!!!                               */
1037         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1038     }
1039     return (u8)res;
1040 }
1041
1042 /****************************************************************************
1043 REMARKS:
1044 Implements the ROL instruction and side effects.
1045 ****************************************************************************/
1046 u16 rol_word(u16 d, u8 s)
1047 {
1048     unsigned int res, cnt, mask;
1049
1050     res = d;
1051     if ((cnt = s % 16) != 0) {
1052         res = (d << cnt);
1053         mask = (1 << cnt) - 1;
1054         res |= (d >> (16 - cnt)) & mask;
1055         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1056         CONDITIONAL_SET_FLAG(s == 1 &&
1057                              XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1058                              F_OF);
1059     } if (s != 0) {
1060         /* set the new carry flag, Note that it is the low order
1061            bit of the result!!!                               */
1062         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1063     }
1064     return (u16)res;
1065 }
1066
1067 /****************************************************************************
1068 REMARKS:
1069 Implements the ROL instruction and side effects.
1070 ****************************************************************************/
1071 u32 rol_long(u32 d, u8 s)
1072 {
1073     u32 res, cnt, mask;
1074
1075     res = d;
1076     if ((cnt = s % 32) != 0) {
1077         res = (d << cnt);
1078         mask = (1 << cnt) - 1;
1079         res |= (d >> (32 - cnt)) & mask;
1080         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1081         CONDITIONAL_SET_FLAG(s == 1 &&
1082                              XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1083                              F_OF);
1084     } if (s != 0) {
1085         /* set the new carry flag, Note that it is the low order
1086            bit of the result!!!                               */
1087         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1088     }
1089     return res;
1090 }
1091
1092 /****************************************************************************
1093 REMARKS:
1094 Implements the ROR instruction and side effects.
1095 ****************************************************************************/
1096 u8 ror_byte(u8 d, u8 s)
1097 {
1098     unsigned int res, cnt, mask;
1099
1100     /* rotate right */
1101     /*
1102        s is the rotate distance.  It varies from 0 - 8.
1103        d is the byte object rotated.
1104
1105        have
1106
1107        B_7 ... B_0
1108
1109        The rotate is done mod 8.
1110
1111        IF n > 0
1112        1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
1113        2) B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0)
1114      */
1115     res = d;
1116     if ((cnt = s % 8) != 0) {           /* not a typo, do nada if cnt==0 */
1117         /* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
1118         res = (d << (8 - cnt));
1119
1120         /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
1121         mask = (1 << (8 - cnt)) - 1;
1122         res |= (d >> (cnt)) & mask;
1123
1124         /* set the new carry flag, Note that it is the low order
1125            bit of the result!!!                               */
1126         CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1127         /* OVERFLOW is set *IFF* s==1, then it is the
1128            xor of the two most significant bits.  Blecck. */
1129         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1130     } else if (s != 0) {
1131         /* set the new carry flag, Note that it is the low order
1132            bit of the result!!!                               */
1133         CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1134     }
1135     return (u8)res;
1136 }
1137
1138 /****************************************************************************
1139 REMARKS:
1140 Implements the ROR instruction and side effects.
1141 ****************************************************************************/
1142 u16 ror_word(u16 d, u8 s)
1143 {
1144     unsigned int res, cnt, mask;
1145
1146     res = d;
1147     if ((cnt = s % 16) != 0) {
1148         res = (d << (16 - cnt));
1149         mask = (1 << (16 - cnt)) - 1;
1150         res |= (d >> (cnt)) & mask;
1151         CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1152         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1153     } else if (s != 0) {
1154         /* set the new carry flag, Note that it is the low order
1155            bit of the result!!!                               */
1156         CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1157     }
1158     return (u16)res;
1159 }
1160
1161 /****************************************************************************
1162 REMARKS:
1163 Implements the ROR instruction and side effects.
1164 ****************************************************************************/
1165 u32 ror_long(u32 d, u8 s)
1166 {
1167     u32 res, cnt, mask;
1168
1169     res = d;
1170     if ((cnt = s % 32) != 0) {
1171         res = (d << (32 - cnt));
1172         mask = (1 << (32 - cnt)) - 1;
1173         res |= (d >> (cnt)) & mask;
1174         CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1175         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1176     } else if (s != 0) {
1177         /* set the new carry flag, Note that it is the low order
1178            bit of the result!!!                               */
1179         CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1180     }
1181     return res;
1182 }
1183
1184 /****************************************************************************
1185 REMARKS:
1186 Implements the SHL instruction and side effects.
1187 ****************************************************************************/
1188 u8 shl_byte(u8 d, u8 s)
1189 {
1190     unsigned int cnt, res, cf;
1191
1192     if (s < 8) {
1193         cnt = s % 8;
1194
1195         /* last bit shifted out goes into carry flag */
1196         if (cnt > 0) {
1197             res = d << cnt;
1198             cf = d & (1 << (8 - cnt));
1199             CONDITIONAL_SET_FLAG(cf, F_CF);
1200             set_szp_flags_8((u8)res);
1201         } else {
1202             res = (u8) d;
1203         }
1204
1205         if (cnt == 1) {
1206             /* Needs simplification. */
1207             CONDITIONAL_SET_FLAG(
1208                                     (((res & 0x80) == 0x80) ^
1209                                      (ACCESS_FLAG(F_CF) != 0)),
1210             /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1211                                     F_OF);
1212         } else {
1213             CLEAR_FLAG(F_OF);
1214         }
1215     } else {
1216         res = 0;
1217         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1218         CLEAR_FLAG(F_OF);
1219         CLEAR_FLAG(F_SF);
1220         SET_FLAG(F_PF);
1221         SET_FLAG(F_ZF);
1222     }
1223     return (u8)res;
1224 }
1225
1226 /****************************************************************************
1227 REMARKS:
1228 Implements the SHL instruction and side effects.
1229 ****************************************************************************/
1230 u16 shl_word(u16 d, u8 s)
1231 {
1232     unsigned int cnt, res, cf;
1233
1234     if (s < 16) {
1235         cnt = s % 16;
1236         if (cnt > 0) {
1237             res = d << cnt;
1238             cf = d & (1 << (16 - cnt));
1239             CONDITIONAL_SET_FLAG(cf, F_CF);
1240             set_szp_flags_16((u16)res);
1241         } else {
1242             res = (u16) d;
1243         }
1244
1245         if (cnt == 1) {
1246             CONDITIONAL_SET_FLAG(
1247                                     (((res & 0x8000) == 0x8000) ^
1248                                      (ACCESS_FLAG(F_CF) != 0)),
1249                                     F_OF);
1250         } else {
1251             CLEAR_FLAG(F_OF);
1252         }
1253     } else {
1254         res = 0;
1255         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1256         CLEAR_FLAG(F_OF);
1257         CLEAR_FLAG(F_SF);
1258         SET_FLAG(F_PF);
1259         SET_FLAG(F_ZF);
1260     }
1261     return (u16)res;
1262 }
1263
1264 /****************************************************************************
1265 REMARKS:
1266 Implements the SHL instruction and side effects.
1267 ****************************************************************************/
1268 u32 shl_long(u32 d, u8 s)
1269 {
1270     unsigned int cnt, res, cf;
1271
1272     if (s < 32) {
1273         cnt = s % 32;
1274         if (cnt > 0) {
1275             res = d << cnt;
1276             cf = d & (1 << (32 - cnt));
1277             CONDITIONAL_SET_FLAG(cf, F_CF);
1278             set_szp_flags_32((u32)res);
1279         } else {
1280             res = d;
1281         }
1282         if (cnt == 1) {
1283             CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1284                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
1285         } else {
1286             CLEAR_FLAG(F_OF);
1287         }
1288     } else {
1289         res = 0;
1290         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1291         CLEAR_FLAG(F_OF);
1292         CLEAR_FLAG(F_SF);
1293         SET_FLAG(F_PF);
1294         SET_FLAG(F_ZF);
1295     }
1296     return res;
1297 }
1298
1299 /****************************************************************************
1300 REMARKS:
1301 Implements the SHR instruction and side effects.
1302 ****************************************************************************/
1303 u8 shr_byte(u8 d, u8 s)
1304 {
1305     unsigned int cnt, res, cf;
1306
1307     if (s < 8) {
1308         cnt = s % 8;
1309         if (cnt > 0) {
1310             cf = d & (1 << (cnt - 1));
1311             res = d >> cnt;
1312             CONDITIONAL_SET_FLAG(cf, F_CF);
1313             set_szp_flags_8((u8)res);
1314         } else {
1315             res = (u8) d;
1316         }
1317
1318         if (cnt == 1) {
1319             CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1320         } else {
1321             CLEAR_FLAG(F_OF);
1322         }
1323     } else {
1324         res = 0;
1325         CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1326         CLEAR_FLAG(F_OF);
1327         CLEAR_FLAG(F_SF);
1328         SET_FLAG(F_PF);
1329         SET_FLAG(F_ZF);
1330     }
1331     return (u8)res;
1332 }
1333
1334 /****************************************************************************
1335 REMARKS:
1336 Implements the SHR instruction and side effects.
1337 ****************************************************************************/
1338 u16 shr_word(u16 d, u8 s)
1339 {
1340     unsigned int cnt, res, cf;
1341
1342     if (s < 16) {
1343         cnt = s % 16;
1344         if (cnt > 0) {
1345             cf = d & (1 << (cnt - 1));
1346             res = d >> cnt;
1347             CONDITIONAL_SET_FLAG(cf, F_CF);
1348             set_szp_flags_16((u16)res);
1349         } else {
1350             res = d;
1351         }
1352
1353         if (cnt == 1) {
1354             CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1355         } else {
1356             CLEAR_FLAG(F_OF);
1357         }
1358     } else {
1359         res = 0;
1360         CLEAR_FLAG(F_CF);
1361         CLEAR_FLAG(F_OF);
1362         SET_FLAG(F_ZF);
1363         CLEAR_FLAG(F_SF);
1364         CLEAR_FLAG(F_PF);
1365     }
1366     return (u16)res;
1367 }
1368
1369 /****************************************************************************
1370 REMARKS:
1371 Implements the SHR instruction and side effects.
1372 ****************************************************************************/
1373 u32 shr_long(u32 d, u8 s)
1374 {
1375     unsigned int cnt, res, cf;
1376
1377     if (s < 32) {
1378         cnt = s % 32;
1379         if (cnt > 0) {
1380             cf = d & (1 << (cnt - 1));
1381             res = d >> cnt;
1382             CONDITIONAL_SET_FLAG(cf, F_CF);
1383             set_szp_flags_32((u32)res);
1384         } else {
1385             res = d;
1386         }
1387         if (cnt == 1) {
1388             CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1389         } else {
1390             CLEAR_FLAG(F_OF);
1391         }
1392     } else {
1393         res = 0;
1394         CLEAR_FLAG(F_CF);
1395         CLEAR_FLAG(F_OF);
1396         SET_FLAG(F_ZF);
1397         CLEAR_FLAG(F_SF);
1398         CLEAR_FLAG(F_PF);
1399     }
1400     return res;
1401 }
1402
1403 /****************************************************************************
1404 REMARKS:
1405 Implements the SAR instruction and side effects.
1406 ****************************************************************************/
1407 u8 sar_byte(u8 d, u8 s)
1408 {
1409     unsigned int cnt, res, cf, mask, sf;
1410
1411     res = d;
1412     sf = d & 0x80;
1413     cnt = s % 8;
1414     if (cnt > 0 && cnt < 8) {
1415         mask = (1 << (8 - cnt)) - 1;
1416         cf = d & (1 << (cnt - 1));
1417         res = (d >> cnt) & mask;
1418         CONDITIONAL_SET_FLAG(cf, F_CF);
1419         if (sf) {
1420             res |= ~mask;
1421         }
1422         set_szp_flags_8((u8)res);
1423     } else if (cnt >= 8) {
1424         if (sf) {
1425             res = 0xff;
1426             SET_FLAG(F_CF);
1427             CLEAR_FLAG(F_ZF);
1428             SET_FLAG(F_SF);
1429             SET_FLAG(F_PF);
1430         } else {
1431             res = 0;
1432             CLEAR_FLAG(F_CF);
1433             SET_FLAG(F_ZF);
1434             CLEAR_FLAG(F_SF);
1435             CLEAR_FLAG(F_PF);
1436         }
1437     }
1438     return (u8)res;
1439 }
1440
1441 /****************************************************************************
1442 REMARKS:
1443 Implements the SAR instruction and side effects.
1444 ****************************************************************************/
1445 u16 sar_word(u16 d, u8 s)
1446 {
1447     unsigned int cnt, res, cf, mask, sf;
1448
1449     sf = d & 0x8000;
1450     cnt = s % 16;
1451     res = d;
1452     if (cnt > 0 && cnt < 16) {
1453         mask = (1 << (16 - cnt)) - 1;
1454         cf = d & (1 << (cnt - 1));
1455         res = (d >> cnt) & mask;
1456         CONDITIONAL_SET_FLAG(cf, F_CF);
1457         if (sf) {
1458             res |= ~mask;
1459         }
1460         set_szp_flags_16((u16)res);
1461     } else if (cnt >= 16) {
1462         if (sf) {
1463             res = 0xffff;
1464             SET_FLAG(F_CF);
1465             CLEAR_FLAG(F_ZF);
1466             SET_FLAG(F_SF);
1467             SET_FLAG(F_PF);
1468         } else {
1469             res = 0;
1470             CLEAR_FLAG(F_CF);
1471             SET_FLAG(F_ZF);
1472             CLEAR_FLAG(F_SF);
1473             CLEAR_FLAG(F_PF);
1474         }
1475     }
1476     return (u16)res;
1477 }
1478
1479 /****************************************************************************
1480 REMARKS:
1481 Implements the SAR instruction and side effects.
1482 ****************************************************************************/
1483 u32 sar_long(u32 d, u8 s)
1484 {
1485     u32 cnt, res, cf, mask, sf;
1486
1487     sf = d & 0x80000000;
1488     cnt = s % 32;
1489     res = d;
1490     if (cnt > 0 && cnt < 32) {
1491         mask = (1 << (32 - cnt)) - 1;
1492         cf = d & (1 << (cnt - 1));
1493         res = (d >> cnt) & mask;
1494         CONDITIONAL_SET_FLAG(cf, F_CF);
1495         if (sf) {
1496             res |= ~mask;
1497         }
1498         set_szp_flags_32(res);
1499     } else if (cnt >= 32) {
1500         if (sf) {
1501             res = 0xffffffff;
1502             SET_FLAG(F_CF);
1503             CLEAR_FLAG(F_ZF);
1504             SET_FLAG(F_SF);
1505             SET_FLAG(F_PF);
1506         } else {
1507             res = 0;
1508             CLEAR_FLAG(F_CF);
1509             SET_FLAG(F_ZF);
1510             CLEAR_FLAG(F_SF);
1511             CLEAR_FLAG(F_PF);
1512         }
1513     }
1514     return res;
1515 }
1516
1517 /****************************************************************************
1518 REMARKS:
1519 Implements the SHLD instruction and side effects.
1520 ****************************************************************************/
1521 u16 shld_word (u16 d, u16 fill, u8 s)
1522 {
1523     unsigned int cnt, res, cf;
1524
1525     if (s < 16) {
1526         cnt = s % 16;
1527         if (cnt > 0) {
1528             res = (d << cnt) | (fill >> (16-cnt));
1529             cf = d & (1 << (16 - cnt));
1530             CONDITIONAL_SET_FLAG(cf, F_CF);
1531             set_szp_flags_16((u16)res);
1532         } else {
1533             res = d;
1534         }
1535         if (cnt == 1) {
1536             CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1537                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
1538         } else {
1539             CLEAR_FLAG(F_OF);
1540         }
1541     } else {
1542         res = 0;
1543         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1544         CLEAR_FLAG(F_OF);
1545         CLEAR_FLAG(F_SF);
1546         SET_FLAG(F_PF);
1547         SET_FLAG(F_ZF);
1548     }
1549     return (u16)res;
1550 }
1551
1552 /****************************************************************************
1553 REMARKS:
1554 Implements the SHLD instruction and side effects.
1555 ****************************************************************************/
1556 u32 shld_long (u32 d, u32 fill, u8 s)
1557 {
1558     unsigned int cnt, res, cf;
1559
1560     if (s < 32) {
1561         cnt = s % 32;
1562         if (cnt > 0) {
1563             res = (d << cnt) | (fill >> (32-cnt));
1564             cf = d & (1 << (32 - cnt));
1565             CONDITIONAL_SET_FLAG(cf, F_CF);
1566             set_szp_flags_32((u32)res);
1567         } else {
1568             res = d;
1569         }
1570         if (cnt == 1) {
1571             CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1572                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
1573         } else {
1574             CLEAR_FLAG(F_OF);
1575         }
1576     } else {
1577         res = 0;
1578         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1579         CLEAR_FLAG(F_OF);
1580         CLEAR_FLAG(F_SF);
1581         SET_FLAG(F_PF);
1582         SET_FLAG(F_ZF);
1583     }
1584     return res;
1585 }
1586
1587 /****************************************************************************
1588 REMARKS:
1589 Implements the SHRD instruction and side effects.
1590 ****************************************************************************/
1591 u16 shrd_word (u16 d, u16 fill, u8 s)
1592 {
1593     unsigned int cnt, res, cf;
1594
1595     if (s < 16) {
1596         cnt = s % 16;
1597         if (cnt > 0) {
1598             cf = d & (1 << (cnt - 1));
1599             res = (d >> cnt) | (fill << (16 - cnt));
1600             CONDITIONAL_SET_FLAG(cf, F_CF);
1601             set_szp_flags_16((u16)res);
1602         } else {
1603             res = d;
1604         }
1605
1606         if (cnt == 1) {
1607             CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1608         } else {
1609             CLEAR_FLAG(F_OF);
1610         }
1611     } else {
1612         res = 0;
1613         CLEAR_FLAG(F_CF);
1614         CLEAR_FLAG(F_OF);
1615         SET_FLAG(F_ZF);
1616         CLEAR_FLAG(F_SF);
1617         CLEAR_FLAG(F_PF);
1618     }
1619     return (u16)res;
1620 }
1621
1622 /****************************************************************************
1623 REMARKS:
1624 Implements the SHRD instruction and side effects.
1625 ****************************************************************************/
1626 u32 shrd_long (u32 d, u32 fill, u8 s)
1627 {
1628     unsigned int cnt, res, cf;
1629
1630     if (s < 32) {
1631         cnt = s % 32;
1632         if (cnt > 0) {
1633             cf = d & (1 << (cnt - 1));
1634             res = (d >> cnt) | (fill << (32 - cnt));
1635             CONDITIONAL_SET_FLAG(cf, F_CF);
1636             set_szp_flags_32((u32)res);
1637         } else {
1638             res = d;
1639         }
1640         if (cnt == 1) {
1641             CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1642         } else {
1643             CLEAR_FLAG(F_OF);
1644         }
1645     } else {
1646         res = 0;
1647         CLEAR_FLAG(F_CF);
1648         CLEAR_FLAG(F_OF);
1649         SET_FLAG(F_ZF);
1650         CLEAR_FLAG(F_SF);
1651         CLEAR_FLAG(F_PF);
1652     }
1653     return res;
1654 }
1655
1656 /****************************************************************************
1657 REMARKS:
1658 Implements the SBB instruction and side effects.
1659 ****************************************************************************/
1660 u8 sbb_byte(u8 d, u8 s)
1661 {
1662     u32 res;   /* all operands in native machine order */
1663     u32 bc;
1664
1665     if (ACCESS_FLAG(F_CF))
1666         res = d - s - 1;
1667     else
1668         res = d - s;
1669     set_szp_flags_8((u8)res);
1670
1671     /* calculate the borrow chain.  See note at top */
1672     bc = (res & (~d | s)) | (~d & s);
1673     CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1674     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1675     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1676     return (u8)res;
1677 }
1678
1679 /****************************************************************************
1680 REMARKS:
1681 Implements the SBB instruction and side effects.
1682 ****************************************************************************/
1683 u16 sbb_word(u16 d, u16 s)
1684 {
1685     u32 res;   /* all operands in native machine order */
1686     u32 bc;
1687
1688     if (ACCESS_FLAG(F_CF))
1689         res = d - s - 1;
1690     else
1691         res = d - s;
1692     set_szp_flags_16((u16)res);
1693
1694     /* calculate the borrow chain.  See note at top */
1695     bc = (res & (~d | s)) | (~d & s);
1696     CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1697     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1698     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1699     return (u16)res;
1700 }
1701
1702 /****************************************************************************
1703 REMARKS:
1704 Implements the SBB instruction and side effects.
1705 ****************************************************************************/
1706 u32 sbb_long(u32 d, u32 s)
1707 {
1708     u32 res;   /* all operands in native machine order */
1709     u32 bc;
1710
1711     if (ACCESS_FLAG(F_CF))
1712         res = d - s - 1;
1713     else
1714         res = d - s;
1715
1716     set_szp_flags_32(res);
1717
1718     /* calculate the borrow chain.  See note at top */
1719     bc = (res & (~d | s)) | (~d & s);
1720     CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1721     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1722     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1723     return res;
1724 }
1725
1726 /****************************************************************************
1727 REMARKS:
1728 Implements the SUB instruction and side effects.
1729 ****************************************************************************/
1730 u8 sub_byte(u8 d, u8 s)
1731 {
1732     u32 res;   /* all operands in native machine order */
1733     u32 bc;
1734
1735     res = d - s;
1736     set_szp_flags_8((u8)res);
1737
1738     /* calculate the borrow chain.  See note at top */
1739     bc = (res & (~d | s)) | (~d & s);
1740     CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1741     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1742     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1743     return (u8)res;
1744 }
1745
1746 /****************************************************************************
1747 REMARKS:
1748 Implements the SUB instruction and side effects.
1749 ****************************************************************************/
1750 u16 sub_word(u16 d, u16 s)
1751 {
1752     u32 res;   /* all operands in native machine order */
1753     u32 bc;
1754
1755     res = d - s;
1756     set_szp_flags_16((u16)res);
1757
1758     /* calculate the borrow chain.  See note at top */
1759     bc = (res & (~d | s)) | (~d & s);
1760     CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1761     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1762     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1763     return (u16)res;
1764 }
1765
1766 /****************************************************************************
1767 REMARKS:
1768 Implements the SUB instruction and side effects.
1769 ****************************************************************************/
1770 u32 sub_long(u32 d, u32 s)
1771 {
1772     u32 res;   /* all operands in native machine order */
1773     u32 bc;
1774
1775     res = d - s;
1776     set_szp_flags_32(res);
1777
1778     /* calculate the borrow chain.  See note at top */
1779     bc = (res & (~d | s)) | (~d & s);
1780     CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1781     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1782     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1783     return res;
1784 }
1785
1786 /****************************************************************************
1787 REMARKS:
1788 Implements the TEST instruction and side effects.
1789 ****************************************************************************/
1790 void test_byte(u8 d, u8 s)
1791 {
1792     u32 res;   /* all operands in native machine order */
1793
1794     res = d & s;
1795
1796     CLEAR_FLAG(F_OF);
1797     set_szp_flags_8((u8)res);
1798     /* AF == dont care */
1799     CLEAR_FLAG(F_CF);
1800 }
1801
1802 /****************************************************************************
1803 REMARKS:
1804 Implements the TEST instruction and side effects.
1805 ****************************************************************************/
1806 void test_word(u16 d, u16 s)
1807 {
1808     u32 res;   /* all operands in native machine order */
1809
1810     res = d & s;
1811
1812     CLEAR_FLAG(F_OF);
1813     set_szp_flags_16((u16)res);
1814     /* AF == dont care */
1815     CLEAR_FLAG(F_CF);
1816 }
1817
1818 /****************************************************************************
1819 REMARKS:
1820 Implements the TEST instruction and side effects.
1821 ****************************************************************************/
1822 void test_long(u32 d, u32 s)
1823 {
1824     u32 res;   /* all operands in native machine order */
1825
1826     res = d & s;
1827
1828     CLEAR_FLAG(F_OF);
1829     set_szp_flags_32(res);
1830     /* AF == dont care */
1831     CLEAR_FLAG(F_CF);
1832 }
1833
1834 /****************************************************************************
1835 REMARKS:
1836 Implements the XOR instruction and side effects.
1837 ****************************************************************************/
1838 u8 xor_byte(u8 d, u8 s)
1839 {
1840     u8 res;    /* all operands in native machine order */
1841
1842     res = d ^ s;
1843     no_carry_byte_side_eff(res);
1844     return res;
1845 }
1846
1847 /****************************************************************************
1848 REMARKS:
1849 Implements the XOR instruction and side effects.
1850 ****************************************************************************/
1851 u16 xor_word(u16 d, u16 s)
1852 {
1853     u16 res;   /* all operands in native machine order */
1854
1855     res = d ^ s;
1856     no_carry_word_side_eff(res);
1857     return res;
1858 }
1859
1860 /****************************************************************************
1861 REMARKS:
1862 Implements the XOR instruction and side effects.
1863 ****************************************************************************/
1864 u32 xor_long(u32 d, u32 s)
1865 {
1866     u32 res;   /* all operands in native machine order */
1867
1868     res = d ^ s;
1869     no_carry_long_side_eff(res);
1870     return res;
1871 }
1872
1873 /****************************************************************************
1874 REMARKS:
1875 Implements the IMUL instruction and side effects.
1876 ****************************************************************************/
1877 void imul_byte(u8 s)
1878 {
1879     s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
1880
1881     M.x86.R_AX = res;
1882     if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
1883         ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
1884         CLEAR_FLAG(F_CF);
1885         CLEAR_FLAG(F_OF);
1886     } else {
1887         SET_FLAG(F_CF);
1888         SET_FLAG(F_OF);
1889     }
1890 }
1891
1892 /****************************************************************************
1893 REMARKS:
1894 Implements the IMUL instruction and side effects.
1895 ****************************************************************************/
1896 void imul_word(u16 s)
1897 {
1898     s32 res = (s16)M.x86.R_AX * (s16)s;
1899
1900     M.x86.R_AX = (u16)res;
1901     M.x86.R_DX = (u16)(res >> 16);
1902     if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) ||
1903         ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) {
1904         CLEAR_FLAG(F_CF);
1905         CLEAR_FLAG(F_OF);
1906     } else {
1907         SET_FLAG(F_CF);
1908         SET_FLAG(F_OF);
1909     }
1910 }
1911
1912 /****************************************************************************
1913 REMARKS:
1914 Implements the IMUL instruction and side effects.
1915 ****************************************************************************/
1916 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
1917 {
1918 #ifdef  __HAS_LONG_LONG__
1919     s64 res = (s32)d * (s32)s;
1920
1921     *res_lo = (u32)res;
1922     *res_hi = (u32)(res >> 32);
1923 #else
1924     u32 d_lo,d_hi,d_sign;
1925     u32 s_lo,s_hi,s_sign;
1926     u32 rlo_lo,rlo_hi,rhi_lo;
1927
1928     if ((d_sign = d & 0x80000000) != 0)
1929         d = -d;
1930     d_lo = d & 0xFFFF;
1931     d_hi = d >> 16;
1932     if ((s_sign = s & 0x80000000) != 0)
1933         s = -s;
1934     s_lo = s & 0xFFFF;
1935     s_hi = s >> 16;
1936     rlo_lo = d_lo * s_lo;
1937     rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
1938     rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
1939     *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
1940     *res_hi = rhi_lo;
1941     if (d_sign != s_sign) {
1942         d = ~*res_lo;
1943         s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
1944         *res_lo = ~*res_lo+1;
1945         *res_hi = ~*res_hi+(s >> 16);
1946         }
1947 #endif
1948 }
1949
1950 /****************************************************************************
1951 REMARKS:
1952 Implements the IMUL instruction and side effects.
1953 ****************************************************************************/
1954 void imul_long(u32 s)
1955 {
1956     imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
1957     if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) ||
1958         ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) {
1959         CLEAR_FLAG(F_CF);
1960         CLEAR_FLAG(F_OF);
1961     } else {
1962         SET_FLAG(F_CF);
1963         SET_FLAG(F_OF);
1964     }
1965 }
1966
1967 /****************************************************************************
1968 REMARKS:
1969 Implements the MUL instruction and side effects.
1970 ****************************************************************************/
1971 void mul_byte(u8 s)
1972 {
1973     u16 res = (u16)(M.x86.R_AL * s);
1974
1975     M.x86.R_AX = res;
1976     if (M.x86.R_AH == 0) {
1977         CLEAR_FLAG(F_CF);
1978         CLEAR_FLAG(F_OF);
1979     } else {
1980         SET_FLAG(F_CF);
1981         SET_FLAG(F_OF);
1982     }
1983 }
1984
1985 /****************************************************************************
1986 REMARKS:
1987 Implements the MUL instruction and side effects.
1988 ****************************************************************************/
1989 void mul_word(u16 s)
1990 {
1991     u32 res = M.x86.R_AX * s;
1992
1993     M.x86.R_AX = (u16)res;
1994     M.x86.R_DX = (u16)(res >> 16);
1995     if (M.x86.R_DX == 0) {
1996         CLEAR_FLAG(F_CF);
1997         CLEAR_FLAG(F_OF);
1998     } else {
1999         SET_FLAG(F_CF);
2000         SET_FLAG(F_OF);
2001     }
2002 }
2003
2004 /****************************************************************************
2005 REMARKS:
2006 Implements the MUL instruction and side effects.
2007 ****************************************************************************/
2008 void mul_long(u32 s)
2009 {
2010 #ifdef  __HAS_LONG_LONG__
2011     u64 res = (u32)M.x86.R_EAX * (u32)s;
2012
2013     M.x86.R_EAX = (u32)res;
2014     M.x86.R_EDX = (u32)(res >> 32);
2015 #else
2016     u32 a,a_lo,a_hi;
2017     u32 s_lo,s_hi;
2018     u32 rlo_lo,rlo_hi,rhi_lo;
2019
2020     a = M.x86.R_EAX;
2021     a_lo = a & 0xFFFF;
2022     a_hi = a >> 16;
2023     s_lo = s & 0xFFFF;
2024     s_hi = s >> 16;
2025     rlo_lo = a_lo * s_lo;
2026     rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2027     rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2028     M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2029     M.x86.R_EDX = rhi_lo;
2030 #endif
2031     if (M.x86.R_EDX == 0) {
2032         CLEAR_FLAG(F_CF);
2033         CLEAR_FLAG(F_OF);
2034     } else {
2035         SET_FLAG(F_CF);
2036         SET_FLAG(F_OF);
2037     }
2038 }
2039
2040 /****************************************************************************
2041 REMARKS:
2042 Implements the IDIV instruction and side effects.
2043 ****************************************************************************/
2044 void idiv_byte(u8 s)
2045 {
2046     s32 dvd, div, mod;
2047
2048     dvd = (s16)M.x86.R_AX;
2049     if (s == 0) {
2050         x86emu_intr_raise(0);
2051         return;
2052     }
2053     div = dvd / (s8)s;
2054     mod = dvd % (s8)s;
2055     if (abs(div) > 0x7f) {
2056         x86emu_intr_raise(0);
2057         return;
2058     }
2059     M.x86.R_AL = (s8) div;
2060     M.x86.R_AH = (s8) mod;
2061 }
2062
2063 /****************************************************************************
2064 REMARKS:
2065 Implements the IDIV instruction and side effects.
2066 ****************************************************************************/
2067 void idiv_word(u16 s)
2068 {
2069     s32 dvd, div, mod;
2070
2071     dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2072     if (s == 0) {
2073         x86emu_intr_raise(0);
2074         return;
2075     }
2076     div = dvd / (s16)s;
2077     mod = dvd % (s16)s;
2078     if (abs(div) > 0x7fff) {
2079         x86emu_intr_raise(0);
2080         return;
2081     }
2082     CLEAR_FLAG(F_CF);
2083     CLEAR_FLAG(F_SF);
2084     CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2085     set_parity_flag(mod);
2086
2087     M.x86.R_AX = (u16)div;
2088     M.x86.R_DX = (u16)mod;
2089 }
2090
2091 /****************************************************************************
2092 REMARKS:
2093 Implements the IDIV instruction and side effects.
2094 ****************************************************************************/
2095 void idiv_long(u32 s)
2096 {
2097 #ifdef  __HAS_LONG_LONG__
2098     s64 dvd, div, mod;
2099
2100     dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2101     if (s == 0) {
2102         x86emu_intr_raise(0);
2103         return;
2104     }
2105     div = dvd / (s32)s;
2106     mod = dvd % (s32)s;
2107     if (abs(div) > 0x7fffffff) {
2108         x86emu_intr_raise(0);
2109         return;
2110     }
2111 #else
2112     s32 div = 0, mod;
2113     s32 h_dvd = M.x86.R_EDX;
2114     u32 l_dvd = M.x86.R_EAX;
2115     u32 abs_s = s & 0x7FFFFFFF;
2116     u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2117     u32 h_s = abs_s >> 1;
2118     u32 l_s = abs_s << 31;
2119     int counter = 31;
2120     int carry;
2121
2122     if (s == 0) {
2123         x86emu_intr_raise(0);
2124         return;
2125     }
2126     do {
2127         div <<= 1;
2128         carry = (l_dvd >= l_s) ? 0 : 1;
2129
2130         if (abs_h_dvd < (h_s + carry)) {
2131             h_s >>= 1;
2132             l_s = abs_s << (--counter);
2133             continue;
2134         } else {
2135             abs_h_dvd -= (h_s + carry);
2136             l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2137                 : (l_dvd - l_s);
2138             h_s >>= 1;
2139             l_s = abs_s << (--counter);
2140             div |= 1;
2141             continue;
2142         }
2143
2144     } while (counter > -1);
2145     /* overflow */
2146     if (abs_h_dvd || (l_dvd > abs_s)) {
2147         x86emu_intr_raise(0);
2148         return;
2149     }
2150     /* sign */
2151     div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2152     mod = l_dvd;
2153
2154 #endif
2155     CLEAR_FLAG(F_CF);
2156     CLEAR_FLAG(F_AF);
2157     CLEAR_FLAG(F_SF);
2158     SET_FLAG(F_ZF);
2159     set_parity_flag(mod);
2160
2161     M.x86.R_EAX = (u32)div;
2162     M.x86.R_EDX = (u32)mod;
2163 }
2164
2165 /****************************************************************************
2166 REMARKS:
2167 Implements the DIV instruction and side effects.
2168 ****************************************************************************/
2169 void div_byte(u8 s)
2170 {
2171     u32 dvd, div, mod;
2172
2173     dvd = M.x86.R_AX;
2174     if (s == 0) {
2175         x86emu_intr_raise(0);
2176         return;
2177     }
2178     div = dvd / (u8)s;
2179     mod = dvd % (u8)s;
2180     if (abs(div) > 0xff) {
2181         x86emu_intr_raise(0);
2182         return;
2183     }
2184     M.x86.R_AL = (u8)div;
2185     M.x86.R_AH = (u8)mod;
2186 }
2187
2188 /****************************************************************************
2189 REMARKS:
2190 Implements the DIV instruction and side effects.
2191 ****************************************************************************/
2192 void div_word(u16 s)
2193 {
2194     u32 dvd, div, mod;
2195
2196     dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2197     if (s == 0) {
2198         x86emu_intr_raise(0);
2199         return;
2200     }
2201     div = dvd / (u16)s;
2202     mod = dvd % (u16)s;
2203     if (abs(div) > 0xffff) {
2204         x86emu_intr_raise(0);
2205         return;
2206     }
2207     CLEAR_FLAG(F_CF);
2208     CLEAR_FLAG(F_SF);
2209     CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2210     set_parity_flag(mod);
2211
2212     M.x86.R_AX = (u16)div;
2213     M.x86.R_DX = (u16)mod;
2214 }
2215
2216 /****************************************************************************
2217 REMARKS:
2218 Implements the DIV instruction and side effects.
2219 ****************************************************************************/
2220 void div_long(u32 s)
2221 {
2222 #ifdef  __HAS_LONG_LONG__
2223     u64 dvd, div, mod;
2224
2225     dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2226     if (s == 0) {
2227         x86emu_intr_raise(0);
2228         return;
2229     }
2230     div = dvd / (u32)s;
2231     mod = dvd % (u32)s;
2232     if (abs(div) > 0xffffffff) {
2233         x86emu_intr_raise(0);
2234         return;
2235     }
2236 #else
2237     s32 div = 0, mod;
2238     s32 h_dvd = M.x86.R_EDX;
2239     u32 l_dvd = M.x86.R_EAX;
2240
2241     u32 h_s = s;
2242     u32 l_s = 0;
2243     int counter = 32;
2244     int carry;
2245
2246     if (s == 0) {
2247         x86emu_intr_raise(0);
2248         return;
2249     }
2250     do {
2251         div <<= 1;
2252         carry = (l_dvd >= l_s) ? 0 : 1;
2253
2254         if (h_dvd < (h_s + carry)) {
2255             h_s >>= 1;
2256             l_s = s << (--counter);
2257             continue;
2258         } else {
2259             h_dvd -= (h_s + carry);
2260             l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2261                 : (l_dvd - l_s);
2262             h_s >>= 1;
2263             l_s = s << (--counter);
2264             div |= 1;
2265             continue;
2266         }
2267
2268     } while (counter > -1);
2269     /* overflow */
2270     if (h_dvd || (l_dvd > s)) {
2271         x86emu_intr_raise(0);
2272         return;
2273     }
2274     mod = l_dvd;
2275 #endif
2276     CLEAR_FLAG(F_CF);
2277     CLEAR_FLAG(F_AF);
2278     CLEAR_FLAG(F_SF);
2279     SET_FLAG(F_ZF);
2280     set_parity_flag(mod);
2281
2282     M.x86.R_EAX = (u32)div;
2283     M.x86.R_EDX = (u32)mod;
2284 }
2285
2286 /****************************************************************************
2287 REMARKS:
2288 Implements the IN string instruction and side effects.
2289 ****************************************************************************/
2290
2291 static void single_in(int size)
2292 {
2293     if(size == 1)
2294         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));
2295     else if (size == 2)
2296         store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));
2297     else
2298         store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));
2299 }
2300
2301 void ins(int size)
2302 {
2303     int inc = size;
2304
2305     if (ACCESS_FLAG(F_DF)) {
2306         inc = -size;
2307     }
2308     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2309         /* dont care whether REPE or REPNE */
2310         /* in until CX is ZERO. */
2311         u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2312                      M.x86.R_ECX : M.x86.R_CX);
2313
2314         while (count--) {
2315           single_in(size);
2316           M.x86.R_DI += inc;
2317           }
2318         M.x86.R_CX = 0;
2319         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2320             M.x86.R_ECX = 0;
2321         }
2322         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2323     } else {
2324         single_in(size);
2325         M.x86.R_DI += inc;
2326     }
2327 }
2328
2329 /****************************************************************************
2330 REMARKS:
2331 Implements the OUT string instruction and side effects.
2332 ****************************************************************************/
2333
2334 static void single_out(int size)
2335 {
2336      if(size == 1)
2337        (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2338      else if (size == 2)
2339        (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2340      else
2341        (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2342 }
2343
2344 void outs(int size)
2345 {
2346     int inc = size;
2347
2348     if (ACCESS_FLAG(F_DF)) {
2349         inc = -size;
2350     }
2351     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2352         /* dont care whether REPE or REPNE */
2353         /* out until CX is ZERO. */
2354         u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2355                      M.x86.R_ECX : M.x86.R_CX);
2356         while (count--) {
2357           single_out(size);
2358           M.x86.R_SI += inc;
2359           }
2360         M.x86.R_CX = 0;
2361         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2362             M.x86.R_ECX = 0;
2363         }
2364         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2365     } else {
2366         single_out(size);
2367         M.x86.R_SI += inc;
2368     }
2369 }
2370
2371 /****************************************************************************
2372 PARAMETERS:
2373 addr    - Address to fetch word from
2374
2375 REMARKS:
2376 Fetches a word from emulator memory using an absolute address.
2377 ****************************************************************************/
2378 u16 mem_access_word(int addr)
2379 {
2380 DB( if (CHECK_MEM_ACCESS())
2381       x86emu_check_mem_access(addr);)
2382     return (*sys_rdw)(addr);
2383 }
2384
2385 /****************************************************************************
2386 REMARKS:
2387 Pushes a word onto the stack.
2388
2389 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2390 ****************************************************************************/
2391 void push_word(u16 w)
2392 {
2393 DB( if (CHECK_SP_ACCESS())
2394       x86emu_check_sp_access();)
2395     M.x86.R_SP -= 2;
2396     (*sys_wrw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);
2397 }
2398
2399 /****************************************************************************
2400 REMARKS:
2401 Pushes a long onto the stack.
2402
2403 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2404 ****************************************************************************/
2405 void push_long(u32 w)
2406 {
2407 DB( if (CHECK_SP_ACCESS())
2408       x86emu_check_sp_access();)
2409     M.x86.R_SP -= 4;
2410     (*sys_wrl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);
2411 }
2412
2413 /****************************************************************************
2414 REMARKS:
2415 Pops a word from the stack.
2416
2417 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2418 ****************************************************************************/
2419 u16 pop_word(void)
2420 {
2421     u16 res;
2422
2423 DB( if (CHECK_SP_ACCESS())
2424       x86emu_check_sp_access();)
2425     res = (*sys_rdw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);
2426     M.x86.R_SP += 2;
2427     return res;
2428 }
2429
2430 /****************************************************************************
2431 REMARKS:
2432 Pops a long from the stack.
2433
2434 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2435 ****************************************************************************/
2436 u32 pop_long(void)
2437 {
2438     u32 res;
2439
2440 DB( if (CHECK_SP_ACCESS())
2441       x86emu_check_sp_access();)
2442     res = (*sys_rdl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);
2443     M.x86.R_SP += 4;
2444     return res;
2445 }
2446