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