d1d4be848c51d3ed7d52bd6e56c94df45c3174a1
[coreboot.git] / util / vgabios / x86emu / src / x86emu / prim_ops.c
1 /****************************************************************************
2 *
3 *                                               Realmode X86 Emulator Library
4 *
5 *               Copyright (C) 1996-1999 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 OF and AF flag.
42 * The latter is not so important, but the former is.  The overflow
43 * flag is the XOR of the top two bits of the carry chain for an
44 * addition (similar for subtraction).  Since we do not want to
45 * simulate the addition in a bitwise manner, we try to calculate the
46 * carry chain given the two operands and the result.
47 *
48 * So, given the following table, which represents the addition of two
49 * bits, we can derive a formula for the carry chain.
50 *
51 * a   b   cin   r     cout
52 * 0   0   0     0     0
53 * 0   0   1     1     0
54 * 0   1   0     1     0
55 * 0   1   1     0     1
56 * 1   0   0     1     0
57 * 1   0   1     0     1
58 * 1   1   0     0     1
59 * 1   1   1     1     1
60 *
61 * Construction of table for cout:
62 *
63 * ab
64 * r  \  00   01   11  10
65 * |------------------
66 * 0  |   0    1    1   1
67 * 1  |   0    0    1   0
68 *
69 * By inspection, one gets:  cc = ab +  r'(a + b)
70 *
71 * That represents alot of operations, but NO CHOICE....
72 *
73 * Borrow Chain Calculation.
74 *
75 * The following table represents the subtraction of two bits, from
76 * which we can derive a formula for the borrow chain.
77 *
78 * a   b   bin   r     bout
79 * 0   0   0     0     0
80 * 0   0   1     1     1
81 * 0   1   0     1     1
82 * 0   1   1     0     1
83 * 1   0   0     1     0
84 * 1   0   1     0     0
85 * 1   1   0     0     0
86 * 1   1   1     1     1
87 *
88 * Construction of table for cout:
89 *
90 * ab
91 * r  \  00   01   11  10
92 * |------------------
93 * 0  |   0    1    0   0
94 * 1  |   1    1    1   0
95 *
96 * By inspection, one gets:  bc = a'b +  r(a' + b)
97 *
98 ****************************************************************************/
99
100 #define PRIM_OPS_NO_REDEFINE_ASM
101 #include "x86emu/x86emui.h"
102
103 /*------------------------- Global Variables ------------------------------*/
104
105 #ifndef __HAVE_INLINE_ASSEMBLER__
106
107 static u32 x86emu_parity_tab[8] = {
108         0x96696996,
109         0x69969669,
110         0x69969669,
111         0x96696996,
112         0x69969669,
113         0x96696996,
114         0x96696996,
115         0x69969669,
116 };
117
118 #endif
119
120 #define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
121 #define XOR2(x)         (((x) ^ ((x)>>1)) & 0x1)
122
123 /*----------------------------- Implementation ----------------------------*/
124
125 #ifndef __HAVE_INLINE_ASSEMBLER__
126
127 /****************************************************************************
128 REMARKS:
129 Implements the AAA instruction and side effects.
130 ****************************************************************************/
131 u16 aaa_word(u16 d)
132 {
133         u16 res;
134         if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
135                 d += 0x6;
136                 d += 0x100;
137                 SET_FLAG(F_AF);
138                 SET_FLAG(F_CF);
139         } else {
140                 CLEAR_FLAG(F_CF);
141                 CLEAR_FLAG(F_AF);
142         }
143         res = (u16) (d & 0xFF0F);
144         CLEAR_FLAG(F_SF);
145         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
146         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
147         return res;
148 }
149
150 /****************************************************************************
151 REMARKS:
152 Implements the AAA instruction and side effects.
153 ****************************************************************************/
154 u16 aas_word(u16 d)
155 {
156         u16 res;
157         if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
158                 d -= 0x6;
159                 d -= 0x100;
160                 SET_FLAG(F_AF);
161                 SET_FLAG(F_CF);
162         } else {
163                 CLEAR_FLAG(F_CF);
164                 CLEAR_FLAG(F_AF);
165         }
166         res = (u16) (d & 0xFF0F);
167         CLEAR_FLAG(F_SF);
168         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
169         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
170         return res;
171 }
172
173 /****************************************************************************
174 REMARKS:
175 Implements the AAD instruction and side effects.
176 ****************************************************************************/
177 u16 aad_word(u16 d)
178 {
179         u16 l;
180         u8 hb, lb;
181
182         hb = (u8) ((d >> 8) & 0xff);
183         lb = (u8) ((d & 0xff));
184         l = (u16) ((lb + 10 * hb) & 0xFF);
185
186         CLEAR_FLAG(F_CF);
187         CLEAR_FLAG(F_AF);
188         CLEAR_FLAG(F_OF);
189         CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
190         CONDITIONAL_SET_FLAG(l == 0, F_ZF);
191         CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
192         return l;
193 }
194
195 /****************************************************************************
196 REMARKS:
197 Implements the AAM instruction and side effects.
198 ****************************************************************************/
199 u16 aam_word(u8 d)
200 {
201         u16 h, l;
202
203         h = (u16) (d / 10);
204         l = (u16) (d % 10);
205         l |= (u16) (h << 8);
206
207         CLEAR_FLAG(F_CF);
208         CLEAR_FLAG(F_AF);
209         CLEAR_FLAG(F_OF);
210         CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
211         CONDITIONAL_SET_FLAG(l == 0, F_ZF);
212         CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
213         return l;
214 }
215
216 /****************************************************************************
217 REMARKS:
218 Implements the ADC instruction and side effects.
219 ****************************************************************************/
220 u8 adc_byte(u8 d, u8 s)
221 {
222         register u32 res;       /* all operands in native machine order */
223         register u32 cc;
224
225         if (ACCESS_FLAG(F_CF))
226                 res = 1 + d + s;
227         else
228                 res = d + s;
229
230         CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
231         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
232         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
233         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
234
235         /* calculate the carry chain  SEE NOTE AT TOP. */
236         cc = (s & d) | ((~res) & (s | d));
237         CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
238         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
239         return (u8) res;
240 }
241
242 /****************************************************************************
243 REMARKS:
244 Implements the ADC instruction and side effects.
245 ****************************************************************************/
246 u16 adc_word(u16 d, u16 s)
247 {
248         register u32 res;       /* all operands in native machine order */
249         register u32 cc;
250
251         if (ACCESS_FLAG(F_CF))
252                 res = 1 + d + s;
253         else
254                 res = d + s;
255
256         CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
257         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
258         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
259         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
260
261         /* calculate the carry chain  SEE NOTE AT TOP. */
262         cc = (s & d) | ((~res) & (s | d));
263         CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
264         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
265         return (u16) res;
266 }
267
268 /****************************************************************************
269 REMARKS:
270 Implements the ADC instruction and side effects.
271 ****************************************************************************/
272 u32 adc_long(u32 d, u32 s)
273 {
274         register u32 lo;        /* all operands in native machine order */
275         register u32 hi;
276         register u32 res;
277         register u32 cc;
278
279         if (ACCESS_FLAG(F_CF)) {
280                 lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
281                 res = 1 + d + s;
282         } else {
283                 lo = (d & 0xFFFF) + (s & 0xFFFF);
284                 res = d + s;
285         }
286         hi = (lo >> 16) + (d >> 16) + (s >> 16);
287
288         CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
289         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
290         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
291         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
292
293         /* calculate the carry chain  SEE NOTE AT TOP. */
294         cc = (s & d) | ((~res) & (s | d));
295         CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
296         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
297         return res;
298 }
299
300 /****************************************************************************
301 REMARKS:
302 Implements the ADD instruction and side effects.
303 ****************************************************************************/
304 u8 add_byte(u8 d, u8 s)
305 {
306         register u32 res;       /* all operands in native machine order */
307         register u32 cc;
308
309         res = d + s;
310         CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
311         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
312         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
313         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
314
315         /* calculate the carry chain  SEE NOTE AT TOP. */
316         cc = (s & d) | ((~res) & (s | d));
317         CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
318         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
319         return (u8) res;
320 }
321
322 /****************************************************************************
323 REMARKS:
324 Implements the ADD instruction and side effects.
325 ****************************************************************************/
326 u16 add_word(u16 d, u16 s)
327 {
328         register u32 res;       /* all operands in native machine order */
329         register u32 cc;
330
331         res = d + s;
332         CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
333         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
334         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
335         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
336
337         /* calculate the carry chain  SEE NOTE AT TOP. */
338         cc = (s & d) | ((~res) & (s | d));
339         CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
340         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
341         return (u16) res;
342 }
343
344 /****************************************************************************
345 REMARKS:
346 Implements the ADD instruction and side effects.
347 ****************************************************************************/
348 u32 add_long(u32 d, u32 s)
349 {
350         register u32 lo;        /* all operands in native machine order */
351         register u32 hi;
352         register u32 res;
353         register u32 cc;
354
355         lo = (d & 0xFFFF) + (s & 0xFFFF);
356         res = d + s;
357         hi = (lo >> 16) + (d >> 16) + (s >> 16);
358
359         CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
360         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
361         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
362         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
363
364         /* calculate the carry chain  SEE NOTE AT TOP. */
365         cc = (s & d) | ((~res) & (s | d));
366         CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
367         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
368
369         return res;
370 }
371
372 /****************************************************************************
373 REMARKS:
374 Implements the AND instruction and side effects.
375 ****************************************************************************/
376 u8 and_byte(u8 d, u8 s)
377 {
378         register u8 res;        /* all operands in native machine order */
379
380         res = d & s;
381
382         /* set the flags  */
383         CLEAR_FLAG(F_OF);
384         CLEAR_FLAG(F_CF);
385         CLEAR_FLAG(F_AF);
386         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
387         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
388         CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
389         return res;
390 }
391
392 /****************************************************************************
393 REMARKS:
394 Implements the AND instruction and side effects.
395 ****************************************************************************/
396 u16 and_word(u16 d, u16 s)
397 {
398         register u16 res;       /* all operands in native machine order */
399
400         res = d & s;
401
402         /* set the flags  */
403         CLEAR_FLAG(F_OF);
404         CLEAR_FLAG(F_CF);
405         CLEAR_FLAG(F_AF);
406         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
407         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
408         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
409         return res;
410 }
411
412 /****************************************************************************
413 REMARKS:
414 Implements the AND instruction and side effects.
415 ****************************************************************************/
416 u32 and_long(u32 d, u32 s)
417 {
418         register u32 res;       /* all operands in native machine order */
419
420         res = d & s;
421
422         /* set the flags  */
423         CLEAR_FLAG(F_OF);
424         CLEAR_FLAG(F_CF);
425         CLEAR_FLAG(F_AF);
426         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
427         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
428         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
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         register u32 res;       /* all operands in native machine order */
439         register u32 bc;
440
441         res = d - s;
442         CLEAR_FLAG(F_CF);
443         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
444         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
445         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
446
447         /* calculate the borrow chain.  See note at top */
448         bc = (res & (~d | s)) | (~d & s);
449         CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
450         CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
451         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
452         return d;
453 }
454
455 /****************************************************************************
456 REMARKS:
457 Implements the CMP instruction and side effects.
458 ****************************************************************************/
459 u16 cmp_word(u16 d, u16 s)
460 {
461         register u32 res;       /* all operands in native machine order */
462         register u32 bc;
463
464         res = d - s;
465         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
466         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
467         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
468
469         /* calculate the borrow chain.  See note at top */
470         bc = (res & (~d | s)) | (~d & s);
471         CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
472         CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
473         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
474         return d;
475 }
476
477 /****************************************************************************
478 REMARKS:
479 Implements the CMP instruction and side effects.
480 ****************************************************************************/
481 u32 cmp_long(u32 d, u32 s)
482 {
483         register u32 res;       /* all operands in native machine order */
484         register u32 bc;
485
486         res = d - s;
487         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
488         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
489         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
490
491         /* calculate the borrow chain.  See note at top */
492         bc = (res & (~d | s)) | (~d & s);
493         CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
494         CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
495         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
496         return d;
497 }
498
499 /****************************************************************************
500 REMARKS:
501 Implements the DAA instruction and side effects.
502 ****************************************************************************/
503 u8 daa_byte(u8 d)
504 {
505         u32 res = d;
506         if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
507                 res += 6;
508                 SET_FLAG(F_AF);
509         }
510         if (res > 0x9F || ACCESS_FLAG(F_CF)) {
511                 res += 0x60;
512                 SET_FLAG(F_CF);
513         }
514         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
515         CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
516         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
517         return (u8) res;
518 }
519
520 /****************************************************************************
521 REMARKS:
522 Implements the DAS instruction and side effects.
523 ****************************************************************************/
524 u8 das_byte(u8 d)
525 {
526         if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
527                 d -= 6;
528                 SET_FLAG(F_AF);
529         }
530         if (d > 0x9F || ACCESS_FLAG(F_CF)) {
531                 d -= 0x60;
532                 SET_FLAG(F_CF);
533         }
534         CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
535         CONDITIONAL_SET_FLAG(d == 0, F_ZF);
536         CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
537         return d;
538 }
539
540 /****************************************************************************
541 REMARKS:
542 Implements the DEC instruction and side effects.
543 ****************************************************************************/
544 u8 dec_byte(u8 d)
545 {
546         register u32 res;       /* all operands in native machine order */
547         register u32 bc;
548
549         res = d - 1;
550         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
551         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
552         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
553
554         /* calculate the borrow chain.  See note at top */
555         /* based on sub_byte, uses s==1.  */
556         bc = (res & (~d | 1)) | (~d & 1);
557         /* carry flag unchanged */
558         CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
559         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
560         return (u8) res;
561 }
562
563 /****************************************************************************
564 REMARKS:
565 Implements the DEC instruction and side effects.
566 ****************************************************************************/
567 u16 dec_word(u16 d)
568 {
569         register u32 res;       /* all operands in native machine order */
570         register u32 bc;
571
572         res = d - 1;
573         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
574         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
575         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
576
577         /* calculate the borrow chain.  See note at top */
578         /* based on the sub_byte routine, with s==1 */
579         bc = (res & (~d | 1)) | (~d & 1);
580         /* carry flag unchanged */
581         CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
582         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
583         return (u16) res;
584 }
585
586 /****************************************************************************
587 REMARKS:
588 Implements the DEC instruction and side effects.
589 ****************************************************************************/
590 u32 dec_long(u32 d)
591 {
592         register u32 res;       /* all operands in native machine order */
593         register u32 bc;
594
595         res = d - 1;
596
597         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
598         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
599         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
600
601         /* calculate the borrow chain.  See note at top */
602         bc = (res & (~d | 1)) | (~d & 1);
603         /* carry flag unchanged */
604         CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
605         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
606         return res;
607 }
608
609 /****************************************************************************
610 REMARKS:
611 Implements the INC instruction and side effects.
612 ****************************************************************************/
613 u8 inc_byte(u8 d)
614 {
615         register u32 res;       /* all operands in native machine order */
616         register u32 cc;
617
618         res = d + 1;
619         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
620         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
621         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
622
623         /* calculate the carry chain  SEE NOTE AT TOP. */
624         cc = ((1 & d) | (~res)) & (1 | d);
625         CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
626         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
627         return (u8) res;
628 }
629
630 /****************************************************************************
631 REMARKS:
632 Implements the INC instruction and side effects.
633 ****************************************************************************/
634 u16 inc_word(u16 d)
635 {
636         register u32 res;       /* all operands in native machine order */
637         register u32 cc;
638
639         res = d + 1;
640         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
641         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
642         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
643
644         /* calculate the carry chain  SEE NOTE AT TOP. */
645         cc = (1 & d) | ((~res) & (1 | d));
646         CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
647         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
648         return (u16) res;
649 }
650
651 /****************************************************************************
652 REMARKS:
653 Implements the INC instruction and side effects.
654 ****************************************************************************/
655 u32 inc_long(u32 d)
656 {
657         register u32 res;       /* all operands in native machine order */
658         register u32 cc;
659
660         res = d + 1;
661         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
662         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
663         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
664
665         /* calculate the carry chain  SEE NOTE AT TOP. */
666         cc = (1 & d) | ((~res) & (1 | d));
667         CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
668         CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
669         return res;
670 }
671
672 /****************************************************************************
673 REMARKS:
674 Implements the OR instruction and side effects.
675 ****************************************************************************/
676 u8 or_byte(u8 d, u8 s)
677 {
678         register u8 res;        /* all operands in native machine order */
679
680         res = d | s;
681         CLEAR_FLAG(F_OF);
682         CLEAR_FLAG(F_CF);
683         CLEAR_FLAG(F_AF);
684         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
685         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
686         CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
687         return res;
688 }
689
690 /****************************************************************************
691 REMARKS:
692 Implements the OR instruction and side effects.
693 ****************************************************************************/
694 u16 or_word(u16 d, u16 s)
695 {
696         register u16 res;       /* all operands in native machine order */
697
698         res = d | s;
699         /* set the carry flag to be bit 8 */
700         CLEAR_FLAG(F_OF);
701         CLEAR_FLAG(F_CF);
702         CLEAR_FLAG(F_AF);
703         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
704         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
705         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
706         return res;
707 }
708
709 /****************************************************************************
710 REMARKS:
711 Implements the OR instruction and side effects.
712 ****************************************************************************/
713 u32 or_long(u32 d, u32 s)
714 {
715         register u32 res;       /* all operands in native machine order */
716
717         res = d | s;
718
719         /* set the carry flag to be bit 8 */
720         CLEAR_FLAG(F_OF);
721         CLEAR_FLAG(F_CF);
722         CLEAR_FLAG(F_AF);
723         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
724         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
725         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
726         return res;
727 }
728
729 /****************************************************************************
730 REMARKS:
731 Implements the OR instruction and side effects.
732 ****************************************************************************/
733 u8 neg_byte(u8 s)
734 {
735         register u8 res;
736         register u8 bc;
737
738         CONDITIONAL_SET_FLAG(s != 0, F_CF);
739         res = (u8) - s;
740         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
741         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
742         CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
743         /* calculate the borrow chain --- modified such that d=0.
744            substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
745            (the one used for sub) and simplifying, since ~d=0xff...,
746            ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
747            ~d&s == s.  So the simplified result is: */
748         bc = res | s;
749         CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
750         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
751         return res;
752 }
753
754 /****************************************************************************
755 REMARKS:
756 Implements the OR instruction and side effects.
757 ****************************************************************************/
758 u16 neg_word(u16 s)
759 {
760         register u16 res;
761         register u16 bc;
762
763         CONDITIONAL_SET_FLAG(s != 0, F_CF);
764         res = (u16) - s;
765         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
766         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
767         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
768
769         /* calculate the borrow chain --- modified such that d=0.
770            substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
771            (the one used for sub) and simplifying, since ~d=0xff...,
772            ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
773            ~d&s == s.  So the simplified result is: */
774         bc = res | s;
775         CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
776         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
777         return res;
778 }
779
780 /****************************************************************************
781 REMARKS:
782 Implements the OR instruction and side effects.
783 ****************************************************************************/
784 u32 neg_long(u32 s)
785 {
786         register u32 res;
787         register u32 bc;
788
789         CONDITIONAL_SET_FLAG(s != 0, F_CF);
790         res = (u32) - s;
791         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
792         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
793         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
794
795         /* calculate the borrow chain --- modified such that d=0.
796            substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
797            (the one used for sub) and simplifying, since ~d=0xff...,
798            ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
799            ~d&s == s.  So the simplified result is: */
800         bc = res | s;
801         CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
802         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
803         return res;
804 }
805
806 /****************************************************************************
807 REMARKS:
808 Implements the NOT instruction and side effects.
809 ****************************************************************************/
810 u8 not_byte(u8 s)
811 {
812         return ~s;
813 }
814
815 /****************************************************************************
816 REMARKS:
817 Implements the NOT instruction and side effects.
818 ****************************************************************************/
819 u16 not_word(u16 s)
820 {
821         return ~s;
822 }
823
824 /****************************************************************************
825 REMARKS:
826 Implements the NOT instruction and side effects.
827 ****************************************************************************/
828 u32 not_long(u32 s)
829 {
830         return ~s;
831 }
832
833 /****************************************************************************
834 REMARKS:
835 Implements the RCL instruction and side effects.
836 ****************************************************************************/
837 u8 rcl_byte(u8 d, u8 s)
838 {
839         register unsigned int res, cnt, mask, cf;
840
841         /* s is the rotate distance.  It varies from 0 - 8. */
842         /* have
843
844            CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 
845
846            want to rotate through the carry by "s" bits.  We could 
847            loop, but that's inefficient.  So the width is 9,
848            and we split into three parts:
849
850            The new carry flag   (was B_n)
851            the stuff in B_n-1 .. B_0
852            the stuff in B_7 .. B_n+1
853
854            The new rotate is done mod 9, and given this,
855            for a rotation of n bits (mod 9) the new carry flag is
856            then located n bits from the MSB.  The low part is 
857            then shifted up cnt bits, and the high part is or'd
858            in.  Using CAPS for new values, and lowercase for the 
859            original values, this can be expressed as:
860
861            IF n > 0 
862            1) CF <-  b_(8-n)
863            2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
864            3) B_(n-1) <- cf
865            4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
866          */
867         res = d;
868         if ((cnt = s % 9) != 0) {
869                 /* extract the new CARRY FLAG. */
870                 /* CF <-  b_(8-n)             */
871                 cf = (d >> (8 - cnt)) & 0x1;
872
873                 /* get the low stuff which rotated 
874                    into the range B_7 .. B_cnt */
875                 /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
876                 /* note that the right hand side done by the mask */
877                 res = (d << cnt) & 0xff;
878
879                 /* now the high stuff which rotated around 
880                    into the positions B_cnt-2 .. B_0 */
881                 /* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
882                 /* shift it downward, 7-(n-2) = 9-n positions. 
883                    and mask off the result before or'ing in. 
884                  */
885                 mask = (1 << (cnt - 1)) - 1;
886                 res |= (d >> (9 - cnt)) & mask;
887
888                 /* if the carry flag was set, or it in.  */
889                 if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
890                         /*  B_(n-1) <- cf */
891                         res |= 1 << (cnt - 1);
892                 }
893                 /* set the new carry flag, based on the variable "cf" */
894                 CONDITIONAL_SET_FLAG(cf, F_CF);
895                 /* OVERFLOW is set *IFF* cnt==1, then it is the 
896                    xor of CF and the most significant bit.  Blecck. */
897                 /* parenthesized this expression since it appears to
898                    be causing OF to be misset */
899                 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), F_OF);
900
901         }
902         return (u8) res;
903 }
904
905 /****************************************************************************
906 REMARKS:
907 Implements the RCL instruction and side effects.
908 ****************************************************************************/
909 u16 rcl_word(u16 d, u8 s)
910 {
911         register unsigned int res, cnt, mask, cf;
912
913         res = d;
914         if ((cnt = s % 17) != 0) {
915                 cf = (d >> (16 - cnt)) & 0x1;
916                 res = (d << cnt) & 0xffff;
917                 mask = (1 << (cnt - 1)) - 1;
918                 res |= (d >> (17 - cnt)) & mask;
919                 if (ACCESS_FLAG(F_CF)) {
920                         res |= 1 << (cnt - 1);
921                 }
922                 CONDITIONAL_SET_FLAG(cf, F_CF);
923                 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF);
924         }
925         return (u16) res;
926 }
927
928 /****************************************************************************
929 REMARKS:
930 Implements the RCL instruction and side effects.
931 ****************************************************************************/
932 u32 rcl_long(u32 d, u8 s)
933 {
934         register u32 res, cnt, mask, cf;
935
936         res = d;
937         if ((cnt = s % 33) != 0) {
938                 cf = (d >> (32 - cnt)) & 0x1;
939                 res = (d << cnt) & 0xffffffff;
940                 mask = (1 << (cnt - 1)) - 1;
941                 res |= (d >> (33 - cnt)) & mask;
942                 if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
943                         res |= 1 << (cnt - 1);
944                 }
945                 CONDITIONAL_SET_FLAG(cf, F_CF);
946                 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF);
947         }
948         return res;
949 }
950
951 /****************************************************************************
952 REMARKS:
953 Implements the RCR instruction and side effects.
954 ****************************************************************************/
955 u8 rcr_byte(u8 d, u8 s)
956 {
957         u32 res, cnt;
958         u32 mask, cf, ocf = 0;
959
960         /* rotate right through carry */
961         /* 
962            s is the rotate distance.  It varies from 0 - 8.
963            d is the byte object rotated.  
964
965            have 
966
967            CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 
968
969            The new rotate is done mod 9, and given this,
970            for a rotation of n bits (mod 9) the new carry flag is
971            then located n bits from the LSB.  The low part is 
972            then shifted up cnt bits, and the high part is or'd
973            in.  Using CAPS for new values, and lowercase for the 
974            original values, this can be expressed as:
975
976            IF n > 0 
977            1) CF <-  b_(n-1)
978            2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
979            3) B_(8-n) <- cf
980            4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0)
981          */
982         res = d;
983         if ((cnt = s % 9) != 0) {
984                 /* extract the new CARRY FLAG. */
985                 /* CF <-  b_(n-1)              */
986                 if (cnt == 1) {
987                         cf = d & 0x1;
988                         /* note hackery here.  Access_flag(..) evaluates to either
989                            0 if flag not set
990                            non-zero if flag is set.
991                            doing access_flag(..) != 0 casts that into either 
992                            0..1 in any representation of the flags register
993                            (i.e. packed bit array or unpacked.)
994                          */
995                         ocf = ACCESS_FLAG(F_CF) != 0;
996                 } else
997                         cf = (d >> (cnt - 1)) & 0x1;
998
999                 /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
1000                 /* note that the right hand side done by the mask
1001                    This is effectively done by shifting the 
1002                    object to the right.  The result must be masked,
1003                    in case the object came in and was treated 
1004                    as a negative number.  Needed??? */
1005
1006                 mask = (1 << (8 - cnt)) - 1;
1007                 res = (d >> cnt) & mask;
1008
1009                 /* now the high stuff which rotated around 
1010                    into the positions B_cnt-2 .. B_0 */
1011                 /* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
1012                 /* shift it downward, 7-(n-2) = 9-n positions. 
1013                    and mask off the result before or'ing in. 
1014                  */
1015                 res |= (d << (9 - cnt));
1016
1017                 /* if the carry flag was set, or it in.  */
1018                 if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
1019                         /*  B_(8-n) <- cf */
1020                         res |= 1 << (8 - cnt);
1021                 }
1022                 /* set the new carry flag, based on the variable "cf" */
1023                 CONDITIONAL_SET_FLAG(cf, F_CF);
1024                 /* OVERFLOW is set *IFF* cnt==1, then it is the 
1025                    xor of CF and the most significant bit.  Blecck. */
1026                 /* parenthesized... */
1027                 if (cnt == 1) {
1028                         CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF);
1029                 }
1030         }
1031         return (u8) res;
1032 }
1033
1034 /****************************************************************************
1035 REMARKS:
1036 Implements the RCR instruction and side effects.
1037 ****************************************************************************/
1038 u16 rcr_word(u16 d, u8 s)
1039 {
1040         u32 res, cnt;
1041         u32 mask, cf, ocf = 0;
1042
1043         /* rotate right through carry */
1044         res = d;
1045         if ((cnt = s % 17) != 0) {
1046                 if (cnt == 1) {
1047                         cf = d & 0x1;
1048                         ocf = ACCESS_FLAG(F_CF) != 0;
1049                 } else
1050                         cf = (d >> (cnt - 1)) & 0x1;
1051                 mask = (1 << (16 - cnt)) - 1;
1052                 res = (d >> cnt) & mask;
1053                 res |= (d << (17 - cnt));
1054                 if (ACCESS_FLAG(F_CF)) {
1055                         res |= 1 << (16 - cnt);
1056                 }
1057                 CONDITIONAL_SET_FLAG(cf, F_CF);
1058                 if (cnt == 1) {
1059                         CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF);
1060                 }
1061         }
1062         return (u16) res;
1063 }
1064
1065 /****************************************************************************
1066 REMARKS:
1067 Implements the RCR instruction and side effects.
1068 ****************************************************************************/
1069 u32 rcr_long(u32 d, u8 s)
1070 {
1071         u32 res, cnt;
1072         u32 mask, cf, ocf = 0;
1073
1074         /* rotate right through carry */
1075         res = d;
1076         if ((cnt = s % 33) != 0) {
1077                 if (cnt == 1) {
1078                         cf = d & 0x1;
1079                         ocf = ACCESS_FLAG(F_CF) != 0;
1080                 } else
1081                         cf = (d >> (cnt - 1)) & 0x1;
1082                 mask = (1 << (32 - cnt)) - 1;
1083                 res = (d >> cnt) & mask;
1084                 if (cnt != 1)
1085                         res |= (d << (33 - cnt));
1086                 if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
1087                         res |= 1 << (32 - cnt);
1088                 }
1089                 CONDITIONAL_SET_FLAG(cf, F_CF);
1090                 if (cnt == 1) {
1091                         CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF);
1092                 }
1093         }
1094         return res;
1095 }
1096
1097 /****************************************************************************
1098 REMARKS:
1099 Implements the ROL instruction and side effects.
1100 ****************************************************************************/
1101 u8 rol_byte(u8 d, u8 s)
1102 {
1103         register unsigned int res, cnt, mask;
1104
1105         /* rotate left */
1106         /* 
1107            s is the rotate distance.  It varies from 0 - 8.
1108            d is the byte object rotated.  
1109
1110            have 
1111
1112            CF  B_7 ... B_0 
1113
1114            The new rotate is done mod 8.
1115            Much simpler than the "rcl" or "rcr" operations.
1116
1117            IF n > 0 
1118            1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0)
1119            2) B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n)
1120          */
1121         res = d;
1122         if ((cnt = s % 8) != 0) {
1123                 /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
1124                 res = (d << cnt);
1125
1126                 /* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
1127                 mask = (1 << cnt) - 1;
1128                 res |= (d >> (8 - cnt)) & mask;
1129
1130                 /* set the new carry flag, Note that it is the low order
1131                    bit of the result!!!                               */
1132                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1133                 /* OVERFLOW is set *IFF* s==1, then it is the
1134                    xor of CF and the most significant bit.  Blecck. */
1135                 CONDITIONAL_SET_FLAG(s == 1 &&
1136                                      XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF);
1137         }
1138         if (s != 0) {
1139                 /* set the new carry flag, Note that it is the low order
1140                    bit of the result!!!                               */
1141                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1142         }
1143         return (u8) res;
1144 }
1145
1146 /****************************************************************************
1147 REMARKS:
1148 Implements the ROL instruction and side effects.
1149 ****************************************************************************/
1150 u16 rol_word(u16 d, u8 s)
1151 {
1152         register unsigned int res, cnt, mask;
1153
1154         res = d;
1155         if ((cnt = s % 16) != 0) {
1156                 res = (d << cnt);
1157                 mask = (1 << cnt) - 1;
1158                 res |= (d >> (16 - cnt)) & mask;
1159                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1160                 CONDITIONAL_SET_FLAG(s == 1 &&
1161                                      XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF);
1162         }
1163         if (s != 0) {
1164                 /* set the new carry flag, Note that it is the low order
1165                    bit of the result!!!                               */
1166                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1167         }
1168         return (u16) res;
1169 }
1170
1171 /****************************************************************************
1172 REMARKS:
1173 Implements the ROL instruction and side effects.
1174 ****************************************************************************/
1175 u32 rol_long(u32 d, u8 s)
1176 {
1177         register u32 res, cnt, mask;
1178
1179         res = d;
1180         if ((cnt = s % 32) != 0) {
1181                 res = (d << cnt);
1182                 mask = (1 << cnt) - 1;
1183                 res |= (d >> (32 - cnt)) & mask;
1184                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1185                 CONDITIONAL_SET_FLAG(s == 1 &&
1186                                      XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF);
1187         }
1188         if (s != 0) {
1189                 /* set the new carry flag, Note that it is the low order
1190                    bit of the result!!!                               */
1191                 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1192         }
1193         return res;
1194 }
1195
1196 /****************************************************************************
1197 REMARKS:
1198 Implements the ROR instruction and side effects.
1199 ****************************************************************************/
1200 u8 ror_byte(u8 d, u8 s)
1201 {
1202         register unsigned int res, cnt, mask;
1203
1204         /* rotate right */
1205         /* 
1206            s is the rotate distance.  It varies from 0 - 8.
1207            d is the byte object rotated.  
1208
1209            have 
1210
1211            B_7 ... B_0 
1212
1213            The rotate is done mod 8.
1214
1215            IF n > 0 
1216            1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
1217            2) B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0)
1218          */
1219         res = d;
1220         if ((cnt = s % 8) != 0) {       /* not a typo, do nada if cnt==0 */
1221                 /* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
1222                 res = (d << (8 - cnt));
1223
1224                 /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
1225                 mask = (1 << (8 - cnt)) - 1;
1226                 res |= (d >> (cnt)) & mask;
1227
1228                 /* set the new carry flag, Note that it is the low order 
1229                    bit of the result!!!                               */
1230                 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1231                 /* OVERFLOW is set *IFF* s==1, then it is the
1232                    xor of the two most significant bits.  Blecck. */
1233                 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1234         } else if (s != 0) {
1235                 /* set the new carry flag, Note that it is the low order
1236                    bit of the result!!!                               */
1237                 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1238         }
1239         return (u8) res;
1240 }
1241
1242 /****************************************************************************
1243 REMARKS:
1244 Implements the ROR instruction and side effects.
1245 ****************************************************************************/
1246 u16 ror_word(u16 d, u8 s)
1247 {
1248         register unsigned int res, cnt, mask;
1249
1250         res = d;
1251         if ((cnt = s % 16) != 0) {
1252                 res = (d << (16 - cnt));
1253                 mask = (1 << (16 - cnt)) - 1;
1254                 res |= (d >> (cnt)) & mask;
1255                 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1256                 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1257         } else if (s != 0) {
1258                 /* set the new carry flag, Note that it is the low order
1259                    bit of the result!!!                               */
1260                 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1261         }
1262         return (u16) res;
1263 }
1264
1265 /****************************************************************************
1266 REMARKS:
1267 Implements the ROR instruction and side effects.
1268 ****************************************************************************/
1269 u32 ror_long(u32 d, u8 s)
1270 {
1271         register u32 res, cnt, mask;
1272
1273         res = d;
1274         if ((cnt = s % 32) != 0) {
1275                 res = (d << (32 - cnt));
1276                 mask = (1 << (32 - cnt)) - 1;
1277                 res |= (d >> (cnt)) & mask;
1278                 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1279                 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1280         } else if (s != 0) {
1281                 /* set the new carry flag, Note that it is the low order
1282                    bit of the result!!!                               */
1283                 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1284         }
1285         return res;
1286 }
1287
1288 /****************************************************************************
1289 REMARKS:
1290 Implements the SHL instruction and side effects.
1291 ****************************************************************************/
1292 u8 shl_byte(u8 d, u8 s)
1293 {
1294         unsigned int cnt, res, cf;
1295
1296         if (s < 8) {
1297                 cnt = s % 8;
1298
1299                 /* last bit shifted out goes into carry flag */
1300                 if (cnt > 0) {
1301                         res = d << cnt;
1302                         cf = d & (1 << (8 - cnt));
1303                         CONDITIONAL_SET_FLAG(cf, F_CF);
1304                         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1305                         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1306                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1307                 } else {
1308                         res = (u8) d;
1309                 }
1310
1311                 if (cnt == 1) {
1312                         /* Needs simplification. */
1313                         CONDITIONAL_SET_FLAG((((res & 0x80) == 0x80) ^
1314                                               (ACCESS_FLAG(F_CF) != 0)),
1315                                              /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1316                                              F_OF);
1317                 } else {
1318                         CLEAR_FLAG(F_OF);
1319                 }
1320         } else {
1321                 res = 0;
1322                 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, 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 SHL instruction and side effects.
1334 ****************************************************************************/
1335 u16 shl_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                         res = d << cnt;
1343                         cf = d & (1 << (16 - cnt));
1344                         CONDITIONAL_SET_FLAG(cf, F_CF);
1345                         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1346                         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1347                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1348                 } else {
1349                         res = (u16) d;
1350                 }
1351
1352                 if (cnt == 1) {
1353                         CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1354                                               (ACCESS_FLAG(F_CF) != 0)), F_OF);
1355                 } else {
1356                         CLEAR_FLAG(F_OF);
1357                 }
1358         } else {
1359                 res = 0;
1360                 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
1361                 CLEAR_FLAG(F_OF);
1362                 CLEAR_FLAG(F_SF);
1363                 SET_FLAG(F_PF);
1364                 SET_FLAG(F_ZF);
1365         }
1366         return (u16) res;
1367 }
1368
1369 /****************************************************************************
1370 REMARKS:
1371 Implements the SHL instruction and side effects.
1372 ****************************************************************************/
1373 u32 shl_long(u32 d, u8 s)
1374 {
1375         unsigned int cnt, res, cf;
1376
1377         if (s < 32) {
1378                 cnt = s % 32;
1379                 if (cnt > 0) {
1380                         res = d << cnt;
1381                         cf = d & (1 << (32 - cnt));
1382                         CONDITIONAL_SET_FLAG(cf, F_CF);
1383                         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1384                         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1385                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1386                 } else {
1387                         res = d;
1388                 }
1389                 if (cnt == 1) {
1390                         CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1391                                               (ACCESS_FLAG(F_CF) != 0)), F_OF);
1392                 } else {
1393                         CLEAR_FLAG(F_OF);
1394                 }
1395         } else {
1396                 res = 0;
1397                 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
1398                 CLEAR_FLAG(F_OF);
1399                 CLEAR_FLAG(F_SF);
1400                 SET_FLAG(F_PF);
1401                 SET_FLAG(F_ZF);
1402         }
1403         return res;
1404 }
1405
1406 /****************************************************************************
1407 REMARKS:
1408 Implements the SHR instruction and side effects.
1409 ****************************************************************************/
1410 u8 shr_byte(u8 d, u8 s)
1411 {
1412         unsigned int cnt, res, cf;
1413
1414         if (s < 8) {
1415                 cnt = s % 8;
1416                 if (cnt > 0) {
1417                         cf = d & (1 << (cnt - 1));
1418                         res = d >> cnt;
1419                         CONDITIONAL_SET_FLAG(cf, F_CF);
1420                         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1421                         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1422                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1423                 } else {
1424                         res = (u8) d;
1425                 }
1426
1427                 if (cnt == 1) {
1428                         CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1429                 } else {
1430                         CLEAR_FLAG(F_OF);
1431                 }
1432         } else {
1433                 res = 0;
1434                 CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
1435                 CLEAR_FLAG(F_OF);
1436                 CLEAR_FLAG(F_SF);
1437                 SET_FLAG(F_PF);
1438                 SET_FLAG(F_ZF);
1439         }
1440         return (u8) res;
1441 }
1442
1443 /****************************************************************************
1444 REMARKS:
1445 Implements the SHR instruction and side effects.
1446 ****************************************************************************/
1447 u16 shr_word(u16 d, u8 s)
1448 {
1449         unsigned int cnt, res, cf;
1450
1451         if (s < 16) {
1452                 cnt = s % 16;
1453                 if (cnt > 0) {
1454                         cf = d & (1 << (cnt - 1));
1455                         res = d >> cnt;
1456                         CONDITIONAL_SET_FLAG(cf, F_CF);
1457                         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1458                         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1459                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1460                 } else {
1461                         res = d;
1462                 }
1463
1464                 if (cnt == 1) {
1465                         CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1466                 } else {
1467                         CLEAR_FLAG(F_OF);
1468                 }
1469         } else {
1470                 res = 0;
1471                 CLEAR_FLAG(F_CF);
1472                 CLEAR_FLAG(F_OF);
1473                 SET_FLAG(F_ZF);
1474                 CLEAR_FLAG(F_SF);
1475                 CLEAR_FLAG(F_PF);
1476         }
1477         return (u16) res;
1478 }
1479
1480 /****************************************************************************
1481 REMARKS:
1482 Implements the SHR instruction and side effects.
1483 ****************************************************************************/
1484 u32 shr_long(u32 d, u8 s)
1485 {
1486         unsigned int cnt, res, cf;
1487
1488         if (s < 32) {
1489                 cnt = s % 32;
1490                 if (cnt > 0) {
1491                         cf = d & (1 << (cnt - 1));
1492                         res = d >> cnt;
1493                         CONDITIONAL_SET_FLAG(cf, F_CF);
1494                         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1495                         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1496                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1497                 } else {
1498                         res = d;
1499                 }
1500                 if (cnt == 1) {
1501                         CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1502                 } else {
1503                         CLEAR_FLAG(F_OF);
1504                 }
1505         } else {
1506                 res = 0;
1507                 CLEAR_FLAG(F_CF);
1508                 CLEAR_FLAG(F_OF);
1509                 SET_FLAG(F_ZF);
1510                 CLEAR_FLAG(F_SF);
1511                 CLEAR_FLAG(F_PF);
1512         }
1513         return res;
1514 }
1515
1516 /****************************************************************************
1517 REMARKS:
1518 Implements the SAR instruction and side effects.
1519 ****************************************************************************/
1520 u8 sar_byte(u8 d, u8 s)
1521 {
1522         unsigned int cnt, res, cf, mask, sf;
1523
1524         res = d;
1525         sf = d & 0x80;
1526         cnt = s % 8;
1527         if (cnt > 0 && cnt < 8) {
1528                 mask = (1 << (8 - cnt)) - 1;
1529                 cf = d & (1 << (cnt - 1));
1530                 res = (d >> cnt) & mask;
1531                 CONDITIONAL_SET_FLAG(cf, F_CF);
1532                 if (sf) {
1533                         res |= ~mask;
1534                 }
1535                 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1536                 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1537                 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1538         } else if (cnt >= 8) {
1539                 if (sf) {
1540                         res = 0xff;
1541                         SET_FLAG(F_CF);
1542                         CLEAR_FLAG(F_ZF);
1543                         SET_FLAG(F_SF);
1544                         SET_FLAG(F_PF);
1545                 } else {
1546                         res = 0;
1547                         CLEAR_FLAG(F_CF);
1548                         SET_FLAG(F_ZF);
1549                         CLEAR_FLAG(F_SF);
1550                         CLEAR_FLAG(F_PF);
1551                 }
1552         }
1553         return (u8) res;
1554 }
1555
1556 /****************************************************************************
1557 REMARKS:
1558 Implements the SAR instruction and side effects.
1559 ****************************************************************************/
1560 u16 sar_word(u16 d, u8 s)
1561 {
1562         unsigned int cnt, res, cf, mask, sf;
1563
1564         sf = d & 0x8000;
1565         cnt = s % 16;
1566         res = d;
1567         if (cnt > 0 && cnt < 16) {
1568                 mask = (1 << (16 - cnt)) - 1;
1569                 cf = d & (1 << (cnt - 1));
1570                 res = (d >> cnt) & mask;
1571                 CONDITIONAL_SET_FLAG(cf, F_CF);
1572                 if (sf) {
1573                         res |= ~mask;
1574                 }
1575                 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1576                 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1577                 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1578         } else if (cnt >= 16) {
1579                 if (sf) {
1580                         res = 0xffff;
1581                         SET_FLAG(F_CF);
1582                         CLEAR_FLAG(F_ZF);
1583                         SET_FLAG(F_SF);
1584                         SET_FLAG(F_PF);
1585                 } else {
1586                         res = 0;
1587                         CLEAR_FLAG(F_CF);
1588                         SET_FLAG(F_ZF);
1589                         CLEAR_FLAG(F_SF);
1590                         CLEAR_FLAG(F_PF);
1591                 }
1592         }
1593         return (u16) res;
1594 }
1595
1596 /****************************************************************************
1597 REMARKS:
1598 Implements the SAR instruction and side effects.
1599 ****************************************************************************/
1600 u32 sar_long(u32 d, u8 s)
1601 {
1602         u32 cnt, res, cf, mask, sf;
1603
1604         sf = d & 0x80000000;
1605         cnt = s % 32;
1606         res = d;
1607         if (cnt > 0 && cnt < 32) {
1608                 mask = (1 << (32 - cnt)) - 1;
1609                 cf = d & (1 << (cnt - 1));
1610                 res = (d >> cnt) & mask;
1611                 CONDITIONAL_SET_FLAG(cf, F_CF);
1612                 if (sf) {
1613                         res |= ~mask;
1614                 }
1615                 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1616                 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1617                 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1618         } else if (cnt >= 32) {
1619                 if (sf) {
1620                         res = 0xffffffff;
1621                         SET_FLAG(F_CF);
1622                         CLEAR_FLAG(F_ZF);
1623                         SET_FLAG(F_SF);
1624                         SET_FLAG(F_PF);
1625                 } else {
1626                         res = 0;
1627                         CLEAR_FLAG(F_CF);
1628                         SET_FLAG(F_ZF);
1629                         CLEAR_FLAG(F_SF);
1630                         CLEAR_FLAG(F_PF);
1631                 }
1632         }
1633         return res;
1634 }
1635
1636 /****************************************************************************
1637 REMARKS:
1638 Implements the SHLD instruction and side effects.
1639 ****************************************************************************/
1640 u16 shld_word(u16 d, u16 fill, u8 s)
1641 {
1642         unsigned int cnt, res, cf;
1643
1644         if (s < 16) {
1645                 cnt = s % 16;
1646                 if (cnt > 0) {
1647                         res = (d << cnt) | (fill >> (16 - cnt));
1648                         cf = d & (1 << (16 - cnt));
1649                         CONDITIONAL_SET_FLAG(cf, F_CF);
1650                         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1651                         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1652                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1653                 } else {
1654                         res = d;
1655                 }
1656                 if (cnt == 1) {
1657                         CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1658                                               (ACCESS_FLAG(F_CF) != 0)), F_OF);
1659                 } else {
1660                         CLEAR_FLAG(F_OF);
1661                 }
1662         } else {
1663                 res = 0;
1664                 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
1665                 CLEAR_FLAG(F_OF);
1666                 CLEAR_FLAG(F_SF);
1667                 SET_FLAG(F_PF);
1668                 SET_FLAG(F_ZF);
1669         }
1670         return (u16) res;
1671 }
1672
1673 /****************************************************************************
1674 REMARKS:
1675 Implements the SHLD instruction and side effects.
1676 ****************************************************************************/
1677 u32 shld_long(u32 d, u32 fill, u8 s)
1678 {
1679         unsigned int cnt, res, cf;
1680
1681         if (s < 32) {
1682                 cnt = s % 32;
1683                 if (cnt > 0) {
1684                         res = (d << cnt) | (fill >> (32 - cnt));
1685                         cf = d & (1 << (32 - cnt));
1686                         CONDITIONAL_SET_FLAG(cf, F_CF);
1687                         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1688                         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1689                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1690                 } else {
1691                         res = d;
1692                 }
1693                 if (cnt == 1) {
1694                         CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1695                                               (ACCESS_FLAG(F_CF) != 0)), F_OF);
1696                 } else {
1697                         CLEAR_FLAG(F_OF);
1698                 }
1699         } else {
1700                 res = 0;
1701                 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
1702                 CLEAR_FLAG(F_OF);
1703                 CLEAR_FLAG(F_SF);
1704                 SET_FLAG(F_PF);
1705                 SET_FLAG(F_ZF);
1706         }
1707         return res;
1708 }
1709
1710 /****************************************************************************
1711 REMARKS:
1712 Implements the SHRD instruction and side effects.
1713 ****************************************************************************/
1714 u16 shrd_word(u16 d, u16 fill, u8 s)
1715 {
1716         unsigned int cnt, res, cf;
1717
1718         if (s < 16) {
1719                 cnt = s % 16;
1720                 if (cnt > 0) {
1721                         cf = d & (1 << (cnt - 1));
1722                         res = (d >> cnt) | (fill << (16 - cnt));
1723                         CONDITIONAL_SET_FLAG(cf, F_CF);
1724                         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1725                         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1726                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1727                 } else {
1728                         res = d;
1729                 }
1730
1731                 if (cnt == 1) {
1732                         CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1733                 } else {
1734                         CLEAR_FLAG(F_OF);
1735                 }
1736         } else {
1737                 res = 0;
1738                 CLEAR_FLAG(F_CF);
1739                 CLEAR_FLAG(F_OF);
1740                 SET_FLAG(F_ZF);
1741                 CLEAR_FLAG(F_SF);
1742                 CLEAR_FLAG(F_PF);
1743         }
1744         return (u16) res;
1745 }
1746
1747 /****************************************************************************
1748 REMARKS:
1749 Implements the SHRD instruction and side effects.
1750 ****************************************************************************/
1751 u32 shrd_long(u32 d, u32 fill, u8 s)
1752 {
1753         unsigned int cnt, res, cf;
1754
1755         if (s < 32) {
1756                 cnt = s % 32;
1757                 if (cnt > 0) {
1758                         cf = d & (1 << (cnt - 1));
1759                         res = (d >> cnt) | (fill << (32 - cnt));
1760                         CONDITIONAL_SET_FLAG(cf, F_CF);
1761                         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1762                         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1763                         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1764                 } else {
1765                         res = d;
1766                 }
1767                 if (cnt == 1) {
1768                         CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1769                 } else {
1770                         CLEAR_FLAG(F_OF);
1771                 }
1772         } else {
1773                 res = 0;
1774                 CLEAR_FLAG(F_CF);
1775                 CLEAR_FLAG(F_OF);
1776                 SET_FLAG(F_ZF);
1777                 CLEAR_FLAG(F_SF);
1778                 CLEAR_FLAG(F_PF);
1779         }
1780         return res;
1781 }
1782
1783 /****************************************************************************
1784 REMARKS:
1785 Implements the SBB instruction and side effects.
1786 ****************************************************************************/
1787 u8 sbb_byte(u8 d, u8 s)
1788 {
1789         register u32 res;       /* all operands in native machine order */
1790         register u32 bc;
1791
1792         if (ACCESS_FLAG(F_CF))
1793                 res = d - s - 1;
1794         else
1795                 res = d - s;
1796         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1797         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1798         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1799
1800         /* calculate the borrow chain.  See note at top */
1801         bc = (res & (~d | s)) | (~d & s);
1802         CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1803         CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1804         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1805         return (u8) res;
1806 }
1807
1808 /****************************************************************************
1809 REMARKS:
1810 Implements the SBB instruction and side effects.
1811 ****************************************************************************/
1812 u16 sbb_word(u16 d, u16 s)
1813 {
1814         register u32 res;       /* all operands in native machine order */
1815         register u32 bc;
1816
1817         if (ACCESS_FLAG(F_CF))
1818                 res = d - s - 1;
1819         else
1820                 res = d - s;
1821         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1822         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1823         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1824
1825         /* calculate the borrow chain.  See note at top */
1826         bc = (res & (~d | s)) | (~d & s);
1827         CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1828         CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1829         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1830         return (u16) res;
1831 }
1832
1833 /****************************************************************************
1834 REMARKS:
1835 Implements the SBB instruction and side effects.
1836 ****************************************************************************/
1837 u32 sbb_long(u32 d, u32 s)
1838 {
1839         register u32 res;       /* all operands in native machine order */
1840         register u32 bc;
1841
1842         if (ACCESS_FLAG(F_CF))
1843                 res = d - s - 1;
1844         else
1845                 res = d - s;
1846         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1847         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1848         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1849
1850         /* calculate the borrow chain.  See note at top */
1851         bc = (res & (~d | s)) | (~d & s);
1852         CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1853         CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1854         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1855         return res;
1856 }
1857
1858 /****************************************************************************
1859 REMARKS:
1860 Implements the SUB instruction and side effects.
1861 ****************************************************************************/
1862 u8 sub_byte(u8 d, u8 s)
1863 {
1864         register u32 res;       /* all operands in native machine order */
1865         register u32 bc;
1866
1867         res = d - s;
1868         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1869         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1870         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1871
1872         /* calculate the borrow chain.  See note at top */
1873         bc = (res & (~d | s)) | (~d & s);
1874         CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1875         CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1876         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1877         return (u8) res;
1878 }
1879
1880 /****************************************************************************
1881 REMARKS:
1882 Implements the SUB instruction and side effects.
1883 ****************************************************************************/
1884 u16 sub_word(u16 d, u16 s)
1885 {
1886         register u32 res;       /* all operands in native machine order */
1887         register u32 bc;
1888
1889         res = d - s;
1890         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1891         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1892         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1893
1894         /* calculate the borrow chain.  See note at top */
1895         bc = (res & (~d | s)) | (~d & s);
1896         CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1897         CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1898         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1899         return (u16) res;
1900 }
1901
1902 /****************************************************************************
1903 REMARKS:
1904 Implements the SUB instruction and side effects.
1905 ****************************************************************************/
1906 u32 sub_long(u32 d, u32 s)
1907 {
1908         register u32 res;       /* all operands in native machine order */
1909         register u32 bc;
1910
1911         res = d - s;
1912         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1913         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1914         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1915
1916         /* calculate the borrow chain.  See note at top */
1917         bc = (res & (~d | s)) | (~d & s);
1918         CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1919         CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1920         CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1921         return res;
1922 }
1923
1924 /****************************************************************************
1925 REMARKS:
1926 Implements the TEST instruction and side effects.
1927 ****************************************************************************/
1928 void test_byte(u8 d, u8 s)
1929 {
1930         register u32 res;       /* all operands in native machine order */
1931
1932         res = d & s;
1933
1934         CLEAR_FLAG(F_OF);
1935         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1936         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1937         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1938         /* AF == dont care */
1939         CLEAR_FLAG(F_CF);
1940 }
1941
1942 /****************************************************************************
1943 REMARKS:
1944 Implements the TEST instruction and side effects.
1945 ****************************************************************************/
1946 void test_word(u16 d, u16 s)
1947 {
1948         register u32 res;       /* all operands in native machine order */
1949
1950         res = d & s;
1951
1952         CLEAR_FLAG(F_OF);
1953         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1954         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1955         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1956         /* AF == dont care */
1957         CLEAR_FLAG(F_CF);
1958 }
1959
1960 /****************************************************************************
1961 REMARKS:
1962 Implements the TEST instruction and side effects.
1963 ****************************************************************************/
1964 void test_long(u32 d, u32 s)
1965 {
1966         register u32 res;       /* all operands in native machine order */
1967
1968         res = d & s;
1969
1970         CLEAR_FLAG(F_OF);
1971         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1972         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1973         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1974         /* AF == dont care */
1975         CLEAR_FLAG(F_CF);
1976 }
1977
1978 /****************************************************************************
1979 REMARKS:
1980 Implements the XOR instruction and side effects.
1981 ****************************************************************************/
1982 u8 xor_byte(u8 d, u8 s)
1983 {
1984         register u8 res;        /* all operands in native machine order */
1985
1986         res = d ^ s;
1987         CLEAR_FLAG(F_OF);
1988         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1989         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1990         CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
1991         CLEAR_FLAG(F_CF);
1992         CLEAR_FLAG(F_AF);
1993         return res;
1994 }
1995
1996 /****************************************************************************
1997 REMARKS:
1998 Implements the XOR instruction and side effects.
1999 ****************************************************************************/
2000 u16 xor_word(u16 d, u16 s)
2001 {
2002         register u16 res;       /* all operands in native machine order */
2003
2004         res = d ^ s;
2005         CLEAR_FLAG(F_OF);
2006         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
2007         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2008         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2009         CLEAR_FLAG(F_CF);
2010         CLEAR_FLAG(F_AF);
2011         return res;
2012 }
2013
2014 /****************************************************************************
2015 REMARKS:
2016 Implements the XOR instruction and side effects.
2017 ****************************************************************************/
2018 u32 xor_long(u32 d, u32 s)
2019 {
2020         register u32 res;       /* all operands in native machine order */
2021
2022         res = d ^ s;
2023         CLEAR_FLAG(F_OF);
2024         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
2025         CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2026         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2027         CLEAR_FLAG(F_CF);
2028         CLEAR_FLAG(F_AF);
2029         return res;
2030 }
2031
2032 /****************************************************************************
2033 REMARKS:
2034 Implements the IMUL instruction and side effects.
2035 ****************************************************************************/
2036 void imul_byte(u8 s)
2037 {
2038         s16 res = (s16) ((s8) M.x86.R_AL * (s8) s);
2039
2040         M.x86.R_AX = res;
2041         if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
2042             ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
2043                 CLEAR_FLAG(F_CF);
2044                 CLEAR_FLAG(F_OF);
2045         } else {
2046                 SET_FLAG(F_CF);
2047                 SET_FLAG(F_OF);
2048         }
2049 }
2050
2051 /****************************************************************************
2052 REMARKS:
2053 Implements the IMUL instruction and side effects.
2054 ****************************************************************************/
2055 void imul_word(u16 s)
2056 {
2057         s32 res = (s16) M.x86.R_AX * (s16) s;
2058
2059         M.x86.R_AX = (u16) res;
2060         M.x86.R_DX = (u16) (res >> 16);
2061         if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
2062             ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
2063                 CLEAR_FLAG(F_CF);
2064                 CLEAR_FLAG(F_OF);
2065         } else {
2066                 SET_FLAG(F_CF);
2067                 SET_FLAG(F_OF);
2068         }
2069 }
2070
2071 /****************************************************************************
2072 REMARKS:
2073 Implements the IMUL instruction and side effects.
2074 ****************************************************************************/
2075 void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
2076 {
2077 #ifdef  __HAS_LONG_LONG__
2078         s64 res = (s32) d * (s32) s;
2079
2080         *res_lo = (u32) res;
2081         *res_hi = (u32) (res >> 32);
2082 #else
2083         u32 d_lo, d_hi, d_sign;
2084         u32 s_lo, s_hi, s_sign;
2085         u32 rlo_lo, rlo_hi, rhi_lo;
2086
2087         if ((d_sign = d & 0x80000000) != 0)
2088                 d = -d;
2089         d_lo = d & 0xFFFF;
2090         d_hi = d >> 16;
2091         if ((s_sign = s & 0x80000000) != 0)
2092                 s = -s;
2093         s_lo = s & 0xFFFF;
2094         s_hi = s >> 16;
2095         rlo_lo = d_lo * s_lo;
2096         rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
2097         rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
2098         *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2099         *res_hi = rhi_lo;
2100         if (d_sign != s_sign) {
2101                 d = ~*res_lo;
2102                 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
2103                 *res_lo = ~*res_lo + 1;
2104                 *res_hi = ~*res_hi + (s >> 16);
2105         }
2106 #endif
2107 }
2108
2109 /****************************************************************************
2110 REMARKS:
2111 Implements the IMUL instruction and side effects.
2112 ****************************************************************************/
2113 void imul_long(u32 s)
2114 {
2115         imul_long_direct(&M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
2116         if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
2117             ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
2118                 CLEAR_FLAG(F_CF);
2119                 CLEAR_FLAG(F_OF);
2120         } else {
2121                 SET_FLAG(F_CF);
2122                 SET_FLAG(F_OF);
2123         }
2124 }
2125
2126 /****************************************************************************
2127 REMARKS:
2128 Implements the MUL instruction and side effects.
2129 ****************************************************************************/
2130 void mul_byte(u8 s)
2131 {
2132         u16 res = (u16) (M.x86.R_AL * s);
2133
2134         M.x86.R_AX = res;
2135         if (M.x86.R_AH == 0) {
2136                 CLEAR_FLAG(F_CF);
2137                 CLEAR_FLAG(F_OF);
2138         } else {
2139                 SET_FLAG(F_CF);
2140                 SET_FLAG(F_OF);
2141         }
2142 }
2143
2144 /****************************************************************************
2145 REMARKS:
2146 Implements the MUL instruction and side effects.
2147 ****************************************************************************/
2148 void mul_word(u16 s)
2149 {
2150         u32 res = M.x86.R_AX * s;
2151
2152         M.x86.R_AX = (u16) res;
2153         M.x86.R_DX = (u16) (res >> 16);
2154         if (M.x86.R_DX == 0) {
2155                 CLEAR_FLAG(F_CF);
2156                 CLEAR_FLAG(F_OF);
2157         } else {
2158                 SET_FLAG(F_CF);
2159                 SET_FLAG(F_OF);
2160         }
2161 }
2162
2163 /****************************************************************************
2164 REMARKS:
2165 Implements the MUL instruction and side effects.
2166 ****************************************************************************/
2167 void mul_long(u32 s)
2168 {
2169 #ifdef  __HAS_LONG_LONG__
2170         u64 res = (u32) M.x86.R_EAX * (u32) s;
2171
2172         M.x86.R_EAX = (u32) res;
2173         M.x86.R_EDX = (u32) (res >> 32);
2174 #else
2175         u32 a, a_lo, a_hi;
2176         u32 s_lo, s_hi;
2177         u32 rlo_lo, rlo_hi, rhi_lo;
2178
2179         a = M.x86.R_EAX;
2180         a_lo = a & 0xFFFF;
2181         a_hi = a >> 16;
2182         s_lo = s & 0xFFFF;
2183         s_hi = s >> 16;
2184         rlo_lo = a_lo * s_lo;
2185         rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2186         rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2187         M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2188         M.x86.R_EDX = rhi_lo;
2189 #endif
2190
2191         if (M.x86.R_EDX == 0) {
2192                 CLEAR_FLAG(F_CF);
2193                 CLEAR_FLAG(F_OF);
2194         } else {
2195                 SET_FLAG(F_CF);
2196                 SET_FLAG(F_OF);
2197         }
2198 }
2199
2200 /****************************************************************************
2201 REMARKS:
2202 Implements the IDIV instruction and side effects.
2203 ****************************************************************************/
2204 void idiv_byte(u8 s)
2205 {
2206         s32 dvd, div, mod;
2207
2208         dvd = (s16) M.x86.R_AX;
2209         if (s == 0) {
2210                 x86emu_intr_raise(0);
2211                 return;
2212         }
2213         div = dvd / (s8) s;
2214         mod = dvd % (s8) s;
2215         if (abs(div) > 0x7f) {
2216                 x86emu_intr_raise(0);
2217                 return;
2218         }
2219         M.x86.R_AL = (s8) div;
2220         M.x86.R_AH = (s8) mod;
2221 }
2222
2223 /****************************************************************************
2224 REMARKS:
2225 Implements the IDIV instruction and side effects.
2226 ****************************************************************************/
2227 void idiv_word(u16 s)
2228 {
2229         s32 dvd, div, mod;
2230
2231         dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX;
2232         if (s == 0) {
2233                 x86emu_intr_raise(0);
2234                 return;
2235         }
2236         div = dvd / (s16) s;
2237         mod = dvd % (s16) s;
2238         if (abs(div) > 0x7fff) {
2239                 x86emu_intr_raise(0);
2240                 return;
2241         }
2242         CLEAR_FLAG(F_CF);
2243         CLEAR_FLAG(F_SF);
2244         CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2245         CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2246
2247         M.x86.R_AX = (u16) div;
2248         M.x86.R_DX = (u16) mod;
2249 }
2250
2251 /****************************************************************************
2252 REMARKS:
2253 Implements the IDIV instruction and side effects.
2254 ****************************************************************************/
2255 void idiv_long(u32 s)
2256 {
2257 #ifdef  __HAS_LONG_LONG__
2258         s64 dvd, div, mod;
2259
2260         dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
2261         if (s == 0) {
2262                 x86emu_intr_raise(0);
2263                 return;
2264         }
2265         div = dvd / (s32) s;
2266         mod = dvd % (s32) s;
2267         if (abs(div) > 0x7fffffff) {
2268                 x86emu_intr_raise(0);
2269                 return;
2270         }
2271 #else
2272         s32 div = 0, mod;
2273         s32 h_dvd = M.x86.R_EDX;
2274         u32 l_dvd = M.x86.R_EAX;
2275         u32 abs_s = s & 0x7FFFFFFF;
2276         u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2277         u32 h_s = abs_s >> 1;
2278         u32 l_s = abs_s << 31;
2279         int counter = 31;
2280         int carry;
2281
2282         if (s == 0) {
2283                 x86emu_intr_raise(0);
2284                 return;
2285         }
2286         do {
2287                 div <<= 1;
2288                 carry = (l_dvd >= l_s) ? 0 : 1;
2289
2290                 if (abs_h_dvd < (h_s + carry)) {
2291                         h_s >>= 1;
2292                         l_s = abs_s << (--counter);
2293                         continue;
2294                 } else {
2295                         abs_h_dvd -= (h_s + carry);
2296                         l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2297                             : (l_dvd - l_s);
2298                         h_s >>= 1;
2299                         l_s = abs_s << (--counter);
2300                         div |= 1;
2301                         continue;
2302                 }
2303
2304         } while (counter > -1);
2305         /* overflow */
2306         if (abs_h_dvd || (l_dvd > abs_s)) {
2307                 x86emu_intr_raise(0);
2308                 return;
2309         }
2310         /* sign */
2311         div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2312         mod = l_dvd;
2313
2314 #endif
2315         CLEAR_FLAG(F_CF);
2316         CLEAR_FLAG(F_AF);
2317         CLEAR_FLAG(F_SF);
2318         SET_FLAG(F_ZF);
2319         CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2320
2321         M.x86.R_EAX = (u32) div;
2322         M.x86.R_EDX = (u32) mod;
2323 }
2324
2325 /****************************************************************************
2326 REMARKS:
2327 Implements the DIV instruction and side effects.
2328 ****************************************************************************/
2329 void div_byte(u8 s)
2330 {
2331         u32 dvd, div, mod;
2332
2333         dvd = M.x86.R_AX;
2334         if (s == 0) {
2335                 x86emu_intr_raise(0);
2336                 return;
2337         }
2338         div = dvd / (u8) s;
2339         mod = dvd % (u8) s;
2340         if (abs(div) > 0xff) {
2341                 x86emu_intr_raise(0);
2342                 return;
2343         }
2344         M.x86.R_AL = (u8) div;
2345         M.x86.R_AH = (u8) mod;
2346 }
2347
2348 /****************************************************************************
2349 REMARKS:
2350 Implements the DIV instruction and side effects.
2351 ****************************************************************************/
2352 void div_word(u16 s)
2353 {
2354         u32 dvd, div, mod;
2355
2356         dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX;
2357         if (s == 0) {
2358                 x86emu_intr_raise(0);
2359                 return;
2360         }
2361         div = dvd / (u16) s;
2362         mod = dvd % (u16) s;
2363         if (abs(div) > 0xffff) {
2364                 x86emu_intr_raise(0);
2365                 return;
2366         }
2367         CLEAR_FLAG(F_CF);
2368         CLEAR_FLAG(F_SF);
2369         CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2370         CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2371
2372         M.x86.R_AX = (u16) div;
2373         M.x86.R_DX = (u16) mod;
2374 }
2375
2376 /****************************************************************************
2377 REMARKS:
2378 Implements the DIV instruction and side effects.
2379 ****************************************************************************/
2380 void div_long(u32 s)
2381 {
2382 #ifdef  __HAS_LONG_LONG__
2383         u64 dvd, div, mod;
2384
2385         dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
2386         if (s == 0) {
2387                 x86emu_intr_raise(0);
2388                 return;
2389         }
2390         div = dvd / (u32) s;
2391         mod = dvd % (u32) s;
2392         if (abs(div) > 0xffffffff) {
2393                 x86emu_intr_raise(0);
2394                 return;
2395         }
2396 #else
2397         s32 div = 0, mod;
2398         s32 h_dvd = M.x86.R_EDX;
2399         u32 l_dvd = M.x86.R_EAX;
2400
2401         u32 h_s = s;
2402         u32 l_s = 0;
2403         int counter = 32;
2404         int carry;
2405
2406         if (s == 0) {
2407                 x86emu_intr_raise(0);
2408                 return;
2409         }
2410         do {
2411                 div <<= 1;
2412                 carry = (l_dvd >= l_s) ? 0 : 1;
2413
2414                 if (h_dvd < (h_s + carry)) {
2415                         h_s >>= 1;
2416                         l_s = s << (--counter);
2417                         continue;
2418                 } else {
2419                         h_dvd -= (h_s + carry);
2420                         l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2421                             : (l_dvd - l_s);
2422                         h_s >>= 1;
2423                         l_s = s << (--counter);
2424                         div |= 1;
2425                         continue;
2426                 }
2427
2428         } while (counter > -1);
2429         /* overflow */
2430         if (h_dvd || (l_dvd > s)) {
2431                 x86emu_intr_raise(0);
2432                 return;
2433         }
2434         mod = l_dvd;
2435 #endif
2436         CLEAR_FLAG(F_CF);
2437         CLEAR_FLAG(F_AF);
2438         CLEAR_FLAG(F_SF);
2439         SET_FLAG(F_ZF);
2440         CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2441
2442         M.x86.R_EAX = (u32) div;
2443         M.x86.R_EDX = (u32) mod;
2444 }
2445
2446 #endif                          /* __HAVE_INLINE_ASSEMBLER__ */
2447
2448 /****************************************************************************
2449 REMARKS:
2450 Implements the IN string instruction and side effects.
2451 ****************************************************************************/
2452 void ins(int size)
2453 {
2454         int inc = size;
2455
2456         if (ACCESS_FLAG(F_DF)) {
2457                 inc = -size;
2458         }
2459         if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2460                 /* dont care whether REPE or REPNE */
2461                 /* in until CX is ZERO. */
2462                 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2463                              M.x86.R_ECX : M.x86.R_CX);
2464                 switch (size) {
2465                 case 1:
2466                         while (count--) {
2467                                 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2468                                                     (*sys_inb) (M.x86.R_DX));
2469                                 M.x86.R_DI += inc;
2470                         }
2471                         break;
2472
2473                 case 2:
2474                         while (count--) {
2475                                 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2476                                                     (*sys_inw) (M.x86.R_DX));
2477                                 M.x86.R_DI += inc;
2478                         }
2479                         break;
2480                 case 4:
2481                         while (count--) {
2482                                 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2483                                                     (*sys_inl) (M.x86.R_DX));
2484                                 M.x86.R_DI += inc;
2485                                 break;
2486                         }
2487                 }
2488                 M.x86.R_CX = 0;
2489                 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2490                         M.x86.R_ECX = 0;
2491                 }
2492                 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2493         } else {
2494                 switch (size) {
2495                 case 1:
2496                         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2497                                             (*sys_inb) (M.x86.R_DX));
2498                         break;
2499                 case 2:
2500                         store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2501                                             (*sys_inw) (M.x86.R_DX));
2502                         break;
2503                 case 4:
2504                         store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2505                                             (*sys_inl) (M.x86.R_DX));
2506                         break;
2507                 }
2508                 M.x86.R_DI += inc;
2509         }
2510 }
2511
2512 /****************************************************************************
2513 REMARKS:
2514 Implements the OUT string instruction and side effects.
2515 ****************************************************************************/
2516 void outs(int size)
2517 {
2518         int inc = size;
2519
2520         if (ACCESS_FLAG(F_DF)) {
2521                 inc = -size;
2522         }
2523         if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2524                 /* dont care whether REPE or REPNE */
2525                 /* out until CX is ZERO. */
2526                 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2527                              M.x86.R_ECX : M.x86.R_CX);
2528                 switch (size) {
2529                 case 1:
2530                         while (count--) {
2531                                 (*sys_outb) (M.x86.R_DX,
2532                                              fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2533                                 M.x86.R_SI += inc;
2534                         }
2535                         break;
2536
2537                 case 2:
2538                         while (count--) {
2539                                 (*sys_outw) (M.x86.R_DX,
2540                                              fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2541                                 M.x86.R_SI += inc;
2542                         }
2543                         break;
2544                 case 4:
2545                         while (count--) {
2546                                 (*sys_outl) (M.x86.R_DX,
2547                                              fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2548                                 M.x86.R_SI += inc;
2549                                 break;
2550                         }
2551                 }
2552                 M.x86.R_CX = 0;
2553                 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2554                         M.x86.R_ECX = 0;
2555                 }
2556                 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2557         } else {
2558                 switch (size) {
2559                 case 1:
2560                         (*sys_outb) (M.x86.R_DX,
2561                                      fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2562                         break;
2563                 case 2:
2564                         (*sys_outw) (M.x86.R_DX,
2565                                      fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2566                         break;
2567                 case 4:
2568                         (*sys_outl) (M.x86.R_DX,
2569                                      fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2570                         break;
2571                 }
2572                 M.x86.R_SI += inc;
2573         }
2574 }
2575
2576 /****************************************************************************
2577 PARAMETERS:
2578 addr    - Address to fetch word from
2579
2580 REMARKS:
2581 Fetches a word from emulator memory using an absolute address.
2582 ****************************************************************************/
2583 u16 mem_access_word(int addr)
2584 {
2585         DB(if (CHECK_MEM_ACCESS())
2586            x86emu_check_mem_access(addr);)
2587                 return (*sys_rdw) (addr);
2588 }
2589
2590 /****************************************************************************
2591 REMARKS:
2592 Pushes a word onto the stack.
2593
2594 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2595 ****************************************************************************/
2596 void push_word(u16 w)
2597 {
2598         DB(if (CHECK_SP_ACCESS())
2599            x86emu_check_sp_access();)
2600                 M.x86.R_SP -= 2;
2601         (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
2602 }
2603
2604 /****************************************************************************
2605 REMARKS:
2606 Pushes a long onto the stack.
2607
2608 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2609 ****************************************************************************/
2610 void push_long(u32 w)
2611 {
2612         DB(if (CHECK_SP_ACCESS())
2613            x86emu_check_sp_access();)
2614                 M.x86.R_SP -= 4;
2615         (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
2616 }
2617
2618 /****************************************************************************
2619 REMARKS:
2620 Pops a word from the stack.
2621
2622 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2623 ****************************************************************************/
2624 u16 pop_word(void)
2625 {
2626         register u16 res;
2627
2628         DB(if (CHECK_SP_ACCESS())
2629            x86emu_check_sp_access();)
2630                 res = (*sys_rdw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
2631         M.x86.R_SP += 2;
2632         return res;
2633 }
2634
2635 /****************************************************************************
2636 REMARKS:
2637 Pops a long from the stack.
2638
2639 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2640 ****************************************************************************/
2641 u32 pop_long(void)
2642 {
2643         register u32 res;
2644
2645         DB(if (CHECK_SP_ACCESS())
2646            x86emu_check_sp_access();)
2647                 res = (*sys_rdl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
2648         M.x86.R_SP += 4;
2649         return res;
2650 }
2651
2652 #ifdef  __HAVE_INLINE_ASSEMBLER__
2653
2654 u16 aaa_word(u16 d)
2655 {
2656         return aaa_word_asm(&M.x86.R_EFLG, d);
2657 }
2658
2659 u16 aas_word(u16 d)
2660 {
2661         return aas_word_asm(&M.x86.R_EFLG, d);
2662 }
2663
2664 u16 aad_word(u16 d)
2665 {
2666         return aad_word_asm(&M.x86.R_EFLG, d);
2667 }
2668
2669 u16 aam_word(u8 d)
2670 {
2671         return aam_word_asm(&M.x86.R_EFLG, d);
2672 }
2673
2674 u8 adc_byte(u8 d, u8 s)
2675 {
2676         return adc_byte_asm(&M.x86.R_EFLG, d, s);
2677 }
2678
2679 u16 adc_word(u16 d, u16 s)
2680 {
2681         return adc_word_asm(&M.x86.R_EFLG, d, s);
2682 }
2683
2684 u32 adc_long(u32 d, u32 s)
2685 {
2686         return adc_long_asm(&M.x86.R_EFLG, d, s);
2687 }
2688
2689 u8 add_byte(u8 d, u8 s)
2690 {
2691         return add_byte_asm(&M.x86.R_EFLG, d, s);
2692 }
2693
2694 u16 add_word(u16 d, u16 s)
2695 {
2696         return add_word_asm(&M.x86.R_EFLG, d, s);
2697 }
2698
2699 u32 add_long(u32 d, u32 s)
2700 {
2701         return add_long_asm(&M.x86.R_EFLG, d, s);
2702 }
2703
2704 u8 and_byte(u8 d, u8 s)
2705 {
2706         return and_byte_asm(&M.x86.R_EFLG, d, s);
2707 }
2708
2709 u16 and_word(u16 d, u16 s)
2710 {
2711         return and_word_asm(&M.x86.R_EFLG, d, s);
2712 }
2713
2714 u32 and_long(u32 d, u32 s)
2715 {
2716         return and_long_asm(&M.x86.R_EFLG, d, s);
2717 }
2718
2719 u8 cmp_byte(u8 d, u8 s)
2720 {
2721         return cmp_byte_asm(&M.x86.R_EFLG, d, s);
2722 }
2723
2724 u16 cmp_word(u16 d, u16 s)
2725 {
2726         return cmp_word_asm(&M.x86.R_EFLG, d, s);
2727 }
2728
2729 u32 cmp_long(u32 d, u32 s)
2730 {
2731         return cmp_long_asm(&M.x86.R_EFLG, d, s);
2732 }
2733
2734 u8 daa_byte(u8 d)
2735 {
2736         return daa_byte_asm(&M.x86.R_EFLG, d);
2737 }
2738
2739 u8 das_byte(u8 d)
2740 {
2741         return das_byte_asm(&M.x86.R_EFLG, d);
2742 }
2743
2744 u8 dec_byte(u8 d)
2745 {
2746         return dec_byte_asm(&M.x86.R_EFLG, d);
2747 }
2748
2749 u16 dec_word(u16 d)
2750 {
2751         return dec_word_asm(&M.x86.R_EFLG, d);
2752 }
2753
2754 u32 dec_long(u32 d)
2755 {
2756         return dec_long_asm(&M.x86.R_EFLG, d);
2757 }
2758
2759 u8 inc_byte(u8 d)
2760 {
2761         return inc_byte_asm(&M.x86.R_EFLG, d);
2762 }
2763
2764 u16 inc_word(u16 d)
2765 {
2766         return inc_word_asm(&M.x86.R_EFLG, d);
2767 }
2768
2769 u32 inc_long(u32 d)
2770 {
2771         return inc_long_asm(&M.x86.R_EFLG, d);
2772 }
2773
2774 u8 or_byte(u8 d, u8 s)
2775 {
2776         return or_byte_asm(&M.x86.R_EFLG, d, s);
2777 }
2778
2779 u16 or_word(u16 d, u16 s)
2780 {
2781         return or_word_asm(&M.x86.R_EFLG, d, s);
2782 }
2783
2784 u32 or_long(u32 d, u32 s)
2785 {
2786         return or_long_asm(&M.x86.R_EFLG, d, s);
2787 }
2788
2789 u8 neg_byte(u8 s)
2790 {
2791         return neg_byte_asm(&M.x86.R_EFLG, s);
2792 }
2793
2794 u16 neg_word(u16 s)
2795 {
2796         return neg_word_asm(&M.x86.R_EFLG, s);
2797 }
2798
2799 u32 neg_long(u32 s)
2800 {
2801         return neg_long_asm(&M.x86.R_EFLG, s);
2802 }
2803
2804 u8 not_byte(u8 s)
2805 {
2806         return not_byte_asm(&M.x86.R_EFLG, s);
2807 }
2808
2809 u16 not_word(u16 s)
2810 {
2811         return not_word_asm(&M.x86.R_EFLG, s);
2812 }
2813
2814 u32 not_long(u32 s)
2815 {
2816         return not_long_asm(&M.x86.R_EFLG, s);
2817 }
2818
2819 u8 rcl_byte(u8 d, u8 s)
2820 {
2821         return rcl_byte_asm(&M.x86.R_EFLG, d, s);
2822 }
2823
2824 u16 rcl_word(u16 d, u8 s)
2825 {
2826         return rcl_word_asm(&M.x86.R_EFLG, d, s);
2827 }
2828
2829 u32 rcl_long(u32 d, u8 s)
2830 {
2831         return rcl_long_asm(&M.x86.R_EFLG, d, s);
2832 }
2833
2834 u8 rcr_byte(u8 d, u8 s)
2835 {
2836         return rcr_byte_asm(&M.x86.R_EFLG, d, s);
2837 }
2838
2839 u16 rcr_word(u16 d, u8 s)
2840 {
2841         return rcr_word_asm(&M.x86.R_EFLG, d, s);
2842 }
2843
2844 u32 rcr_long(u32 d, u8 s)
2845 {
2846         return rcr_long_asm(&M.x86.R_EFLG, d, s);
2847 }
2848
2849 u8 rol_byte(u8 d, u8 s)
2850 {
2851         return rol_byte_asm(&M.x86.R_EFLG, d, s);
2852 }
2853
2854 u16 rol_word(u16 d, u8 s)
2855 {
2856         return rol_word_asm(&M.x86.R_EFLG, d, s);
2857 }
2858
2859 u32 rol_long(u32 d, u8 s)
2860 {
2861         return rol_long_asm(&M.x86.R_EFLG, d, s);
2862 }
2863
2864 u8 ror_byte(u8 d, u8 s)
2865 {
2866         return ror_byte_asm(&M.x86.R_EFLG, d, s);
2867 }
2868
2869 u16 ror_word(u16 d, u8 s)
2870 {
2871         return ror_word_asm(&M.x86.R_EFLG, d, s);
2872 }
2873
2874 u32 ror_long(u32 d, u8 s)
2875 {
2876         return ror_long_asm(&M.x86.R_EFLG, d, s);
2877 }
2878
2879 u8 shl_byte(u8 d, u8 s)
2880 {
2881         return shl_byte_asm(&M.x86.R_EFLG, d, s);
2882 }
2883
2884 u16 shl_word(u16 d, u8 s)
2885 {
2886         return shl_word_asm(&M.x86.R_EFLG, d, s);
2887 }
2888
2889 u32 shl_long(u32 d, u8 s)
2890 {
2891         return shl_long_asm(&M.x86.R_EFLG, d, s);
2892 }
2893
2894 u8 shr_byte(u8 d, u8 s)
2895 {
2896         return shr_byte_asm(&M.x86.R_EFLG, d, s);
2897 }
2898
2899 u16 shr_word(u16 d, u8 s)
2900 {
2901         return shr_word_asm(&M.x86.R_EFLG, d, s);
2902 }
2903
2904 u32 shr_long(u32 d, u8 s)
2905 {
2906         return shr_long_asm(&M.x86.R_EFLG, d, s);
2907 }
2908
2909 u8 sar_byte(u8 d, u8 s)
2910 {
2911         return sar_byte_asm(&M.x86.R_EFLG, d, s);
2912 }
2913
2914 u16 sar_word(u16 d, u8 s)
2915 {
2916         return sar_word_asm(&M.x86.R_EFLG, d, s);
2917 }
2918
2919 u32 sar_long(u32 d, u8 s)
2920 {
2921         return sar_long_asm(&M.x86.R_EFLG, d, s);
2922 }
2923
2924 u16 shld_word(u16 d, u16 fill, u8 s)
2925 {
2926         return shld_word_asm(&M.x86.R_EFLG, d, fill, s);
2927 }
2928
2929 u32 shld_long(u32 d, u32 fill, u8 s)
2930 {
2931         return shld_long_asm(&M.x86.R_EFLG, d, fill, s);
2932 }
2933
2934 u16 shrd_word(u16 d, u16 fill, u8 s)
2935 {
2936         return shrd_word_asm(&M.x86.R_EFLG, d, fill, s);
2937 }
2938
2939 u32 shrd_long(u32 d, u32 fill, u8 s)
2940 {
2941         return shrd_long_asm(&M.x86.R_EFLG, d, fill, s);
2942 }
2943
2944 u8 sbb_byte(u8 d, u8 s)
2945 {
2946         return sbb_byte_asm(&M.x86.R_EFLG, d, s);
2947 }
2948
2949 u16 sbb_word(u16 d, u16 s)
2950 {
2951         return sbb_word_asm(&M.x86.R_EFLG, d, s);
2952 }
2953
2954 u32 sbb_long(u32 d, u32 s)
2955 {
2956         return sbb_long_asm(&M.x86.R_EFLG, d, s);
2957 }
2958
2959 u8 sub_byte(u8 d, u8 s)
2960 {
2961         return sub_byte_asm(&M.x86.R_EFLG, d, s);
2962 }
2963
2964 u16 sub_word(u16 d, u16 s)
2965 {
2966         return sub_word_asm(&M.x86.R_EFLG, d, s);
2967 }
2968
2969 u32 sub_long(u32 d, u32 s)
2970 {
2971         return sub_long_asm(&M.x86.R_EFLG, d, s);
2972 }
2973
2974 void test_byte(u8 d, u8 s)
2975 {
2976         test_byte_asm(&M.x86.R_EFLG, d, s);
2977 }
2978
2979 void test_word(u16 d, u16 s)
2980 {
2981         test_word_asm(&M.x86.R_EFLG, d, s);
2982 }
2983
2984 void test_long(u32 d, u32 s)
2985 {
2986         test_long_asm(&M.x86.R_EFLG, d, s);
2987 }
2988
2989 u8 xor_byte(u8 d, u8 s)
2990 {
2991         return xor_byte_asm(&M.x86.R_EFLG, d, s);
2992 }
2993
2994 u16 xor_word(u16 d, u16 s)
2995 {
2996         return xor_word_asm(&M.x86.R_EFLG, d, s);
2997 }
2998
2999 u32 xor_long(u32 d, u32 s)
3000 {
3001         return xor_long_asm(&M.x86.R_EFLG, d, s);
3002 }
3003
3004 void imul_byte(u8 s)
3005 {
3006         imul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s);
3007 }
3008
3009 void imul_word(u16 s)
3010 {
3011         imul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s);
3012 }
3013
3014 void imul_long(u32 s)
3015 {
3016         imul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
3017 }
3018
3019 void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
3020 {
3021         imul_long_asm(&M.x86.R_EFLG, res_lo, res_hi, d, s);
3022 }
3023
3024 void mul_byte(u8 s)
3025 {
3026         mul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s);
3027 }
3028
3029 void mul_word(u16 s)
3030 {
3031         mul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s);
3032 }
3033
3034 void mul_long(u32 s)
3035 {
3036         mul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
3037 }
3038
3039 void idiv_byte(u8 s)
3040 {
3041         idiv_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s);
3042 }
3043
3044 void idiv_word(u16 s)
3045 {
3046         idiv_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, M.x86.R_DX, s);
3047 }
3048
3049 void idiv_long(u32 s)
3050 {
3051         idiv_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX,
3052                       s);
3053 }
3054
3055 void div_byte(u8 s)
3056 {
3057         div_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s);
3058 }
3059
3060 void div_word(u16 s)
3061 {
3062         div_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, M.x86.R_DX, s);
3063 }
3064
3065 void div_long(u32 s)
3066 {
3067         div_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX,
3068                      s);
3069 }
3070
3071 #endif