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