1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
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.
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.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file contains the code to implement the primitive
36 * machine operations used by the emulation code in ops.c
38 * Carry Chain Calculation
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.
48 * So, given the following table, which represents the addition of two
49 * bits, we can derive a formula for the carry chain.
61 * Construction of table for cout:
69 * By inspection, one gets: cc = ab + r'(a + b)
71 * That represents alot of operations, but NO CHOICE....
73 * Borrow Chain Calculation.
75 * The following table represents the subtraction of two bits, from
76 * which we can derive a formula for the borrow chain.
88 * Construction of table for cout:
96 * By inspection, one gets: bc = a'b + r(a' + b)
98 ****************************************************************************/
100 #define PRIM_OPS_NO_REDEFINE_ASM
101 #include "x86emu/x86emui.h"
103 /*------------------------- Global Variables ------------------------------*/
105 #ifndef __HAVE_INLINE_ASSEMBLER__
107 static u32 x86emu_parity_tab[8] =
121 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
122 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
124 /*----------------------------- Implementation ----------------------------*/
126 #ifndef __HAVE_INLINE_ASSEMBLER__
128 /****************************************************************************
130 Implements the AAA instruction and side effects.
131 ****************************************************************************/
135 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
144 res = (u16)(d & 0xFF0F);
146 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
147 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
151 /****************************************************************************
153 Implements the AAA instruction and side effects.
154 ****************************************************************************/
158 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
167 res = (u16)(d & 0xFF0F);
169 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
170 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
174 /****************************************************************************
176 Implements the AAD instruction and side effects.
177 ****************************************************************************/
183 hb = (u8)((d >> 8) & 0xff);
184 lb = (u8)((d & 0xff));
185 l = (u16)((lb + 10 * hb) & 0xFF);
190 CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
191 CONDITIONAL_SET_FLAG(l == 0, F_ZF);
192 CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
196 /****************************************************************************
198 Implements the AAM instruction and side effects.
199 ****************************************************************************/
211 CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
212 CONDITIONAL_SET_FLAG(l == 0, F_ZF);
213 CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
217 /****************************************************************************
219 Implements the ADC instruction and side effects.
220 ****************************************************************************/
221 u8 adc_byte(u8 d, u8 s)
223 register u32 res; /* all operands in native machine order */
226 if (ACCESS_FLAG(F_CF))
231 CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
232 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
233 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
234 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
236 /* calculate the carry chain SEE NOTE AT TOP. */
237 cc = (s & d) | ((~res) & (s | d));
238 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
239 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
243 /****************************************************************************
245 Implements the ADC instruction and side effects.
246 ****************************************************************************/
247 u16 adc_word(u16 d, u16 s)
249 register u32 res; /* all operands in native machine order */
252 if (ACCESS_FLAG(F_CF))
257 CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
258 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
259 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
260 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
262 /* calculate the carry chain SEE NOTE AT TOP. */
263 cc = (s & d) | ((~res) & (s | d));
264 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
265 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
269 /****************************************************************************
271 Implements the ADC instruction and side effects.
272 ****************************************************************************/
273 u32 adc_long(u32 d, u32 s)
275 register u32 lo; /* all operands in native machine order */
280 if (ACCESS_FLAG(F_CF)) {
281 lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
285 lo = (d & 0xFFFF) + (s & 0xFFFF);
288 hi = (lo >> 16) + (d >> 16) + (s >> 16);
290 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
291 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
292 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
293 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
295 /* calculate the carry chain SEE NOTE AT TOP. */
296 cc = (s & d) | ((~res) & (s | d));
297 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
298 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
302 /****************************************************************************
304 Implements the ADD instruction and side effects.
305 ****************************************************************************/
306 u8 add_byte(u8 d, u8 s)
308 register u32 res; /* all operands in native machine order */
312 CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
313 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
314 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
315 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
317 /* calculate the carry chain SEE NOTE AT TOP. */
318 cc = (s & d) | ((~res) & (s | d));
319 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
320 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
324 /****************************************************************************
326 Implements the ADD instruction and side effects.
327 ****************************************************************************/
328 u16 add_word(u16 d, u16 s)
330 register u32 res; /* all operands in native machine order */
334 CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
335 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
336 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
337 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
339 /* calculate the carry chain SEE NOTE AT TOP. */
340 cc = (s & d) | ((~res) & (s | d));
341 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
342 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
346 /****************************************************************************
348 Implements the ADD instruction and side effects.
349 ****************************************************************************/
350 u32 add_long(u32 d, u32 s)
352 register u32 lo; /* all operands in native machine order */
357 lo = (d & 0xFFFF) + (s & 0xFFFF);
359 hi = (lo >> 16) + (d >> 16) + (s >> 16);
361 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
362 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
363 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
364 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
366 /* calculate the carry chain SEE NOTE AT TOP. */
367 cc = (s & d) | ((~res) & (s | d));
368 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
369 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
374 /****************************************************************************
376 Implements the AND instruction and side effects.
377 ****************************************************************************/
378 u8 and_byte(u8 d, u8 s)
380 register u8 res; /* all operands in native machine order */
388 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
389 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
390 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
394 /****************************************************************************
396 Implements the AND instruction and side effects.
397 ****************************************************************************/
398 u16 and_word(u16 d, u16 s)
400 register u16 res; /* all operands in native machine order */
408 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
409 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
410 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
414 /****************************************************************************
416 Implements the AND instruction and side effects.
417 ****************************************************************************/
418 u32 and_long(u32 d, u32 s)
420 register u32 res; /* all operands in native machine order */
428 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
429 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
430 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
434 /****************************************************************************
436 Implements the CMP instruction and side effects.
437 ****************************************************************************/
438 u8 cmp_byte(u8 d, u8 s)
440 register u32 res; /* all operands in native machine order */
445 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
446 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
447 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
449 /* calculate the borrow chain. See note at top */
450 bc = (res & (~d | s)) | (~d & s);
451 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
452 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
453 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
457 /****************************************************************************
459 Implements the CMP instruction and side effects.
460 ****************************************************************************/
461 u16 cmp_word(u16 d, u16 s)
463 register u32 res; /* all operands in native machine order */
467 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
468 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
469 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
471 /* calculate the borrow chain. See note at top */
472 bc = (res & (~d | s)) | (~d & s);
473 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
474 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
475 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
479 /****************************************************************************
481 Implements the CMP instruction and side effects.
482 ****************************************************************************/
483 u32 cmp_long(u32 d, u32 s)
485 register u32 res; /* all operands in native machine order */
489 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
490 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
491 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
493 /* calculate the borrow chain. See note at top */
494 bc = (res & (~d | s)) | (~d & s);
495 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
496 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
497 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
501 /****************************************************************************
503 Implements the DAA instruction and side effects.
504 ****************************************************************************/
508 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
512 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
516 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
517 CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
518 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
522 /****************************************************************************
524 Implements the DAS instruction and side effects.
525 ****************************************************************************/
528 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
532 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
536 CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
537 CONDITIONAL_SET_FLAG(d == 0, F_ZF);
538 CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
542 /****************************************************************************
544 Implements the DEC instruction and side effects.
545 ****************************************************************************/
548 register u32 res; /* all operands in native machine order */
552 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
553 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
554 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
556 /* calculate the borrow chain. See note at top */
557 /* based on sub_byte, uses s==1. */
558 bc = (res & (~d | 1)) | (~d & 1);
559 /* carry flag unchanged */
560 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
561 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
565 /****************************************************************************
567 Implements the DEC instruction and side effects.
568 ****************************************************************************/
571 register u32 res; /* all operands in native machine order */
575 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
576 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
577 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
579 /* calculate the borrow chain. See note at top */
580 /* based on the sub_byte routine, with s==1 */
581 bc = (res & (~d | 1)) | (~d & 1);
582 /* carry flag unchanged */
583 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
584 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
588 /****************************************************************************
590 Implements the DEC instruction and side effects.
591 ****************************************************************************/
594 register u32 res; /* all operands in native machine order */
599 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
600 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
601 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
603 /* calculate the borrow chain. See note at top */
604 bc = (res & (~d | 1)) | (~d & 1);
605 /* carry flag unchanged */
606 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
607 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
611 /****************************************************************************
613 Implements the INC instruction and side effects.
614 ****************************************************************************/
617 register u32 res; /* all operands in native machine order */
621 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
622 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
623 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
625 /* calculate the carry chain SEE NOTE AT TOP. */
626 cc = ((1 & d) | (~res)) & (1 | d);
627 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
628 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
632 /****************************************************************************
634 Implements the INC instruction and side effects.
635 ****************************************************************************/
638 register u32 res; /* all operands in native machine order */
642 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
643 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
644 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
646 /* calculate the carry chain SEE NOTE AT TOP. */
647 cc = (1 & d) | ((~res) & (1 | d));
648 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
649 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
653 /****************************************************************************
655 Implements the INC instruction and side effects.
656 ****************************************************************************/
659 register u32 res; /* all operands in native machine order */
663 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
664 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
665 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
667 /* calculate the carry chain SEE NOTE AT TOP. */
668 cc = (1 & d) | ((~res) & (1 | d));
669 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
670 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
674 /****************************************************************************
676 Implements the OR instruction and side effects.
677 ****************************************************************************/
678 u8 or_byte(u8 d, u8 s)
680 register u8 res; /* all operands in native machine order */
686 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
687 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
688 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
692 /****************************************************************************
694 Implements the OR instruction and side effects.
695 ****************************************************************************/
696 u16 or_word(u16 d, u16 s)
698 register u16 res; /* all operands in native machine order */
701 /* set the carry flag to be bit 8 */
705 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
706 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
707 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
711 /****************************************************************************
713 Implements the OR instruction and side effects.
714 ****************************************************************************/
715 u32 or_long(u32 d, u32 s)
717 register u32 res; /* all operands in native machine order */
721 /* set the carry flag to be bit 8 */
725 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
726 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
727 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
731 /****************************************************************************
733 Implements the OR instruction and side effects.
734 ****************************************************************************/
740 CONDITIONAL_SET_FLAG(s != 0, F_CF);
742 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
743 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
744 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
745 /* calculate the borrow chain --- modified such that d=0.
746 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
747 (the one used for sub) and simplifying, since ~d=0xff...,
748 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
749 ~d&s == s. So the simplified result is: */
751 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
752 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
756 /****************************************************************************
758 Implements the OR instruction and side effects.
759 ****************************************************************************/
765 CONDITIONAL_SET_FLAG(s != 0, F_CF);
767 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
768 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
769 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
771 /* calculate the borrow chain --- modified such that d=0.
772 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
773 (the one used for sub) and simplifying, since ~d=0xff...,
774 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
775 ~d&s == s. So the simplified result is: */
777 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
778 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
782 /****************************************************************************
784 Implements the OR instruction and side effects.
785 ****************************************************************************/
791 CONDITIONAL_SET_FLAG(s != 0, F_CF);
793 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
794 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
795 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
797 /* calculate the borrow chain --- modified such that d=0.
798 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
799 (the one used for sub) and simplifying, since ~d=0xff...,
800 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
801 ~d&s == s. So the simplified result is: */
803 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
804 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
808 /****************************************************************************
810 Implements the NOT instruction and side effects.
811 ****************************************************************************/
817 /****************************************************************************
819 Implements the NOT instruction and side effects.
820 ****************************************************************************/
826 /****************************************************************************
828 Implements the NOT instruction and side effects.
829 ****************************************************************************/
835 /****************************************************************************
837 Implements the RCL instruction and side effects.
838 ****************************************************************************/
839 u8 rcl_byte(u8 d, u8 s)
841 register unsigned int res, cnt, mask, cf;
843 /* s is the rotate distance. It varies from 0 - 8. */
846 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
848 want to rotate through the carry by "s" bits. We could
849 loop, but that's inefficient. So the width is 9,
850 and we split into three parts:
852 The new carry flag (was B_n)
853 the stuff in B_n-1 .. B_0
854 the stuff in B_7 .. B_n+1
856 The new rotate is done mod 9, and given this,
857 for a rotation of n bits (mod 9) the new carry flag is
858 then located n bits from the MSB. The low part is
859 then shifted up cnt bits, and the high part is or'd
860 in. Using CAPS for new values, and lowercase for the
861 original values, this can be expressed as:
865 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
867 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
870 if ((cnt = s % 9) != 0) {
871 /* extract the new CARRY FLAG. */
873 cf = (d >> (8 - cnt)) & 0x1;
875 /* get the low stuff which rotated
876 into the range B_7 .. B_cnt */
877 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
878 /* note that the right hand side done by the mask */
879 res = (d << cnt) & 0xff;
881 /* now the high stuff which rotated around
882 into the positions B_cnt-2 .. B_0 */
883 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
884 /* shift it downward, 7-(n-2) = 9-n positions.
885 and mask off the result before or'ing in.
887 mask = (1 << (cnt - 1)) - 1;
888 res |= (d >> (9 - cnt)) & mask;
890 /* if the carry flag was set, or it in. */
891 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
893 res |= 1 << (cnt - 1);
895 /* set the new carry flag, based on the variable "cf" */
896 CONDITIONAL_SET_FLAG(cf, F_CF);
897 /* OVERFLOW is set *IFF* cnt==1, then it is the
898 xor of CF and the most significant bit. Blecck. */
899 /* parenthesized this expression since it appears to
900 be causing OF to be misset */
901 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
908 /****************************************************************************
910 Implements the RCL instruction and side effects.
911 ****************************************************************************/
912 u16 rcl_word(u16 d, u8 s)
914 register unsigned int res, cnt, mask, cf;
917 if ((cnt = s % 17) != 0) {
918 cf = (d >> (16 - cnt)) & 0x1;
919 res = (d << cnt) & 0xffff;
920 mask = (1 << (cnt - 1)) - 1;
921 res |= (d >> (17 - cnt)) & mask;
922 if (ACCESS_FLAG(F_CF)) {
923 res |= 1 << (cnt - 1);
925 CONDITIONAL_SET_FLAG(cf, F_CF);
926 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
932 /****************************************************************************
934 Implements the RCL instruction and side effects.
935 ****************************************************************************/
936 u32 rcl_long(u32 d, u8 s)
938 register u32 res, cnt, mask, cf;
941 if ((cnt = s % 33) != 0) {
942 cf = (d >> (32 - cnt)) & 0x1;
943 res = (d << cnt) & 0xffffffff;
944 mask = (1 << (cnt - 1)) - 1;
945 res |= (d >> (33 - cnt)) & mask;
946 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
947 res |= 1 << (cnt - 1);
949 CONDITIONAL_SET_FLAG(cf, F_CF);
950 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
956 /****************************************************************************
958 Implements the RCR instruction and side effects.
959 ****************************************************************************/
960 u8 rcr_byte(u8 d, u8 s)
963 u32 mask, cf, ocf = 0;
965 /* rotate right through carry */
967 s is the rotate distance. It varies from 0 - 8.
968 d is the byte object rotated.
972 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
974 The new rotate is done mod 9, and given this,
975 for a rotation of n bits (mod 9) the new carry flag is
976 then located n bits from the LSB. The low part is
977 then shifted up cnt bits, and the high part is or'd
978 in. Using CAPS for new values, and lowercase for the
979 original values, this can be expressed as:
983 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
985 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
988 if ((cnt = s % 9) != 0) {
989 /* extract the new CARRY FLAG. */
993 /* note hackery here. Access_flag(..) evaluates to either
995 non-zero if flag is set.
996 doing access_flag(..) != 0 casts that into either
997 0..1 in any representation of the flags register
998 (i.e. packed bit array or unpacked.)
1000 ocf = ACCESS_FLAG(F_CF) != 0;
1002 cf = (d >> (cnt - 1)) & 0x1;
1004 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
1005 /* note that the right hand side done by the mask
1006 This is effectively done by shifting the
1007 object to the right. The result must be masked,
1008 in case the object came in and was treated
1009 as a negative number. Needed??? */
1011 mask = (1 << (8 - cnt)) - 1;
1012 res = (d >> cnt) & mask;
1014 /* now the high stuff which rotated around
1015 into the positions B_cnt-2 .. B_0 */
1016 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
1017 /* shift it downward, 7-(n-2) = 9-n positions.
1018 and mask off the result before or'ing in.
1020 res |= (d << (9 - cnt));
1022 /* if the carry flag was set, or it in. */
1023 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1025 res |= 1 << (8 - cnt);
1027 /* set the new carry flag, based on the variable "cf" */
1028 CONDITIONAL_SET_FLAG(cf, F_CF);
1029 /* OVERFLOW is set *IFF* cnt==1, then it is the
1030 xor of CF and the most significant bit. Blecck. */
1031 /* parenthesized... */
1033 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
1040 /****************************************************************************
1042 Implements the RCR instruction and side effects.
1043 ****************************************************************************/
1044 u16 rcr_word(u16 d, u8 s)
1047 u32 mask, cf, ocf = 0;
1049 /* rotate right through carry */
1051 if ((cnt = s % 17) != 0) {
1054 ocf = ACCESS_FLAG(F_CF) != 0;
1056 cf = (d >> (cnt - 1)) & 0x1;
1057 mask = (1 << (16 - cnt)) - 1;
1058 res = (d >> cnt) & mask;
1059 res |= (d << (17 - cnt));
1060 if (ACCESS_FLAG(F_CF)) {
1061 res |= 1 << (16 - cnt);
1063 CONDITIONAL_SET_FLAG(cf, F_CF);
1065 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
1072 /****************************************************************************
1074 Implements the RCR instruction and side effects.
1075 ****************************************************************************/
1076 u32 rcr_long(u32 d, u8 s)
1079 u32 mask, cf, ocf = 0;
1081 /* rotate right through carry */
1083 if ((cnt = s % 33) != 0) {
1086 ocf = ACCESS_FLAG(F_CF) != 0;
1088 cf = (d >> (cnt - 1)) & 0x1;
1089 mask = (1 << (32 - cnt)) - 1;
1090 res = (d >> cnt) & mask;
1092 res |= (d << (33 - cnt));
1093 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1094 res |= 1 << (32 - cnt);
1096 CONDITIONAL_SET_FLAG(cf, F_CF);
1098 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
1105 /****************************************************************************
1107 Implements the ROL instruction and side effects.
1108 ****************************************************************************/
1109 u8 rol_byte(u8 d, u8 s)
1111 register unsigned int res, cnt, mask;
1115 s is the rotate distance. It varies from 0 - 8.
1116 d is the byte object rotated.
1122 The new rotate is done mod 8.
1123 Much simpler than the "rcl" or "rcr" operations.
1126 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1127 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1130 if ((cnt = s % 8) != 0) {
1131 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1134 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1135 mask = (1 << cnt) - 1;
1136 res |= (d >> (8 - cnt)) & mask;
1138 /* set the new carry flag, Note that it is the low order
1139 bit of the result!!! */
1140 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1141 /* OVERFLOW is set *IFF* s==1, then it is the
1142 xor of CF and the most significant bit. Blecck. */
1143 CONDITIONAL_SET_FLAG(s == 1 &&
1144 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1147 /* set the new carry flag, Note that it is the low order
1148 bit of the result!!! */
1149 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1154 /****************************************************************************
1156 Implements the ROL instruction and side effects.
1157 ****************************************************************************/
1158 u16 rol_word(u16 d, u8 s)
1160 register unsigned int res, cnt, mask;
1163 if ((cnt = s % 16) != 0) {
1165 mask = (1 << cnt) - 1;
1166 res |= (d >> (16 - cnt)) & mask;
1167 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1168 CONDITIONAL_SET_FLAG(s == 1 &&
1169 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1172 /* set the new carry flag, Note that it is the low order
1173 bit of the result!!! */
1174 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1179 /****************************************************************************
1181 Implements the ROL instruction and side effects.
1182 ****************************************************************************/
1183 u32 rol_long(u32 d, u8 s)
1185 register u32 res, cnt, mask;
1188 if ((cnt = s % 32) != 0) {
1190 mask = (1 << cnt) - 1;
1191 res |= (d >> (32 - cnt)) & mask;
1192 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1193 CONDITIONAL_SET_FLAG(s == 1 &&
1194 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1197 /* set the new carry flag, Note that it is the low order
1198 bit of the result!!! */
1199 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1204 /****************************************************************************
1206 Implements the ROR instruction and side effects.
1207 ****************************************************************************/
1208 u8 ror_byte(u8 d, u8 s)
1210 register unsigned int res, cnt, mask;
1214 s is the rotate distance. It varies from 0 - 8.
1215 d is the byte object rotated.
1221 The rotate is done mod 8.
1224 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1225 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1228 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1229 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1230 res = (d << (8 - cnt));
1232 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1233 mask = (1 << (8 - cnt)) - 1;
1234 res |= (d >> (cnt)) & mask;
1236 /* set the new carry flag, Note that it is the low order
1237 bit of the result!!! */
1238 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1239 /* OVERFLOW is set *IFF* s==1, then it is the
1240 xor of the two most significant bits. Blecck. */
1241 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1242 } else if (s != 0) {
1243 /* set the new carry flag, Note that it is the low order
1244 bit of the result!!! */
1245 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1250 /****************************************************************************
1252 Implements the ROR instruction and side effects.
1253 ****************************************************************************/
1254 u16 ror_word(u16 d, u8 s)
1256 register unsigned int res, cnt, mask;
1259 if ((cnt = s % 16) != 0) {
1260 res = (d << (16 - cnt));
1261 mask = (1 << (16 - cnt)) - 1;
1262 res |= (d >> (cnt)) & mask;
1263 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1264 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1265 } else if (s != 0) {
1266 /* set the new carry flag, Note that it is the low order
1267 bit of the result!!! */
1268 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1273 /****************************************************************************
1275 Implements the ROR instruction and side effects.
1276 ****************************************************************************/
1277 u32 ror_long(u32 d, u8 s)
1279 register u32 res, cnt, mask;
1282 if ((cnt = s % 32) != 0) {
1283 res = (d << (32 - cnt));
1284 mask = (1 << (32 - cnt)) - 1;
1285 res |= (d >> (cnt)) & mask;
1286 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1287 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1288 } else if (s != 0) {
1289 /* set the new carry flag, Note that it is the low order
1290 bit of the result!!! */
1291 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1296 /****************************************************************************
1298 Implements the SHL instruction and side effects.
1299 ****************************************************************************/
1300 u8 shl_byte(u8 d, u8 s)
1302 unsigned int cnt, res, cf;
1307 /* last bit shifted out goes into carry flag */
1310 cf = d & (1 << (8 - cnt));
1311 CONDITIONAL_SET_FLAG(cf, F_CF);
1312 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1313 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1314 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1320 /* Needs simplification. */
1321 CONDITIONAL_SET_FLAG(
1322 (((res & 0x80) == 0x80) ^
1323 (ACCESS_FLAG(F_CF) != 0)),
1324 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1331 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1340 /****************************************************************************
1342 Implements the SHL instruction and side effects.
1343 ****************************************************************************/
1344 u16 shl_word(u16 d, u8 s)
1346 unsigned int cnt, res, cf;
1352 cf = d & (1 << (16 - cnt));
1353 CONDITIONAL_SET_FLAG(cf, F_CF);
1354 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1355 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1356 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1362 CONDITIONAL_SET_FLAG(
1363 (((res & 0x8000) == 0x8000) ^
1364 (ACCESS_FLAG(F_CF) != 0)),
1371 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1380 /****************************************************************************
1382 Implements the SHL instruction and side effects.
1383 ****************************************************************************/
1384 u32 shl_long(u32 d, u8 s)
1386 unsigned int cnt, res, cf;
1392 cf = d & (1 << (32 - cnt));
1393 CONDITIONAL_SET_FLAG(cf, F_CF);
1394 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1395 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1396 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1401 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1402 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1408 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1417 /****************************************************************************
1419 Implements the SHR instruction and side effects.
1420 ****************************************************************************/
1421 u8 shr_byte(u8 d, u8 s)
1423 unsigned int cnt, res, cf;
1428 cf = d & (1 << (cnt - 1));
1430 CONDITIONAL_SET_FLAG(cf, F_CF);
1431 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1432 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1433 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1439 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1445 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1454 /****************************************************************************
1456 Implements the SHR instruction and side effects.
1457 ****************************************************************************/
1458 u16 shr_word(u16 d, u8 s)
1460 unsigned int cnt, res, cf;
1465 cf = d & (1 << (cnt - 1));
1467 CONDITIONAL_SET_FLAG(cf, F_CF);
1468 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1469 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1470 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1476 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1491 /****************************************************************************
1493 Implements the SHR instruction and side effects.
1494 ****************************************************************************/
1495 u32 shr_long(u32 d, u8 s)
1497 unsigned int cnt, res, cf;
1502 cf = d & (1 << (cnt - 1));
1504 CONDITIONAL_SET_FLAG(cf, F_CF);
1505 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1506 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1507 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1512 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1527 /****************************************************************************
1529 Implements the SAR instruction and side effects.
1530 ****************************************************************************/
1531 u8 sar_byte(u8 d, u8 s)
1533 unsigned int cnt, res, cf, mask, sf;
1538 if (cnt > 0 && cnt < 8) {
1539 mask = (1 << (8 - cnt)) - 1;
1540 cf = d & (1 << (cnt - 1));
1541 res = (d >> cnt) & mask;
1542 CONDITIONAL_SET_FLAG(cf, F_CF);
1546 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1547 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1548 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1549 } else if (cnt >= 8) {
1567 /****************************************************************************
1569 Implements the SAR instruction and side effects.
1570 ****************************************************************************/
1571 u16 sar_word(u16 d, u8 s)
1573 unsigned int cnt, res, cf, mask, sf;
1578 if (cnt > 0 && cnt < 16) {
1579 mask = (1 << (16 - cnt)) - 1;
1580 cf = d & (1 << (cnt - 1));
1581 res = (d >> cnt) & mask;
1582 CONDITIONAL_SET_FLAG(cf, F_CF);
1586 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1587 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1588 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1589 } else if (cnt >= 16) {
1607 /****************************************************************************
1609 Implements the SAR instruction and side effects.
1610 ****************************************************************************/
1611 u32 sar_long(u32 d, u8 s)
1613 u32 cnt, res, cf, mask, sf;
1615 sf = d & 0x80000000;
1618 if (cnt > 0 && cnt < 32) {
1619 mask = (1 << (32 - cnt)) - 1;
1620 cf = d & (1 << (cnt - 1));
1621 res = (d >> cnt) & mask;
1622 CONDITIONAL_SET_FLAG(cf, F_CF);
1626 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1627 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1628 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1629 } else if (cnt >= 32) {
1647 /****************************************************************************
1649 Implements the SHLD instruction and side effects.
1650 ****************************************************************************/
1651 u16 shld_word (u16 d, u16 fill, u8 s)
1653 unsigned int cnt, res, cf;
1658 res = (d << cnt) | (fill >> (16-cnt));
1659 cf = d & (1 << (16 - cnt));
1660 CONDITIONAL_SET_FLAG(cf, F_CF);
1661 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1662 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1663 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1668 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1669 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1675 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1684 /****************************************************************************
1686 Implements the SHLD instruction and side effects.
1687 ****************************************************************************/
1688 u32 shld_long (u32 d, u32 fill, u8 s)
1690 unsigned int cnt, res, cf;
1695 res = (d << cnt) | (fill >> (32-cnt));
1696 cf = d & (1 << (32 - cnt));
1697 CONDITIONAL_SET_FLAG(cf, F_CF);
1698 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1699 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1700 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1705 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1706 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1712 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1721 /****************************************************************************
1723 Implements the SHRD instruction and side effects.
1724 ****************************************************************************/
1725 u16 shrd_word (u16 d, u16 fill, u8 s)
1727 unsigned int cnt, res, cf;
1732 cf = d & (1 << (cnt - 1));
1733 res = (d >> cnt) | (fill << (16 - cnt));
1734 CONDITIONAL_SET_FLAG(cf, F_CF);
1735 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1736 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1737 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1743 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1758 /****************************************************************************
1760 Implements the SHRD instruction and side effects.
1761 ****************************************************************************/
1762 u32 shrd_long (u32 d, u32 fill, u8 s)
1764 unsigned int cnt, res, cf;
1769 cf = d & (1 << (cnt - 1));
1770 res = (d >> cnt) | (fill << (32 - cnt));
1771 CONDITIONAL_SET_FLAG(cf, F_CF);
1772 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1773 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1774 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1779 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1794 /****************************************************************************
1796 Implements the SBB instruction and side effects.
1797 ****************************************************************************/
1798 u8 sbb_byte(u8 d, u8 s)
1800 register u32 res; /* all operands in native machine order */
1803 if (ACCESS_FLAG(F_CF))
1807 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1808 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1809 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1811 /* calculate the borrow chain. See note at top */
1812 bc = (res & (~d | s)) | (~d & s);
1813 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1814 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1815 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1819 /****************************************************************************
1821 Implements the SBB instruction and side effects.
1822 ****************************************************************************/
1823 u16 sbb_word(u16 d, u16 s)
1825 register u32 res; /* all operands in native machine order */
1828 if (ACCESS_FLAG(F_CF))
1832 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1833 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1834 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1836 /* calculate the borrow chain. See note at top */
1837 bc = (res & (~d | s)) | (~d & s);
1838 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1839 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1840 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1844 /****************************************************************************
1846 Implements the SBB instruction and side effects.
1847 ****************************************************************************/
1848 u32 sbb_long(u32 d, u32 s)
1850 register u32 res; /* all operands in native machine order */
1853 if (ACCESS_FLAG(F_CF))
1857 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1858 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1859 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1861 /* calculate the borrow chain. See note at top */
1862 bc = (res & (~d | s)) | (~d & s);
1863 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1864 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1865 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1869 /****************************************************************************
1871 Implements the SUB instruction and side effects.
1872 ****************************************************************************/
1873 u8 sub_byte(u8 d, u8 s)
1875 register u32 res; /* all operands in native machine order */
1879 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1880 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1881 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1883 /* calculate the borrow chain. See note at top */
1884 bc = (res & (~d | s)) | (~d & s);
1885 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1886 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1887 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1891 /****************************************************************************
1893 Implements the SUB instruction and side effects.
1894 ****************************************************************************/
1895 u16 sub_word(u16 d, u16 s)
1897 register u32 res; /* all operands in native machine order */
1901 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1902 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1903 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1905 /* calculate the borrow chain. See note at top */
1906 bc = (res & (~d | s)) | (~d & s);
1907 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1908 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1909 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1913 /****************************************************************************
1915 Implements the SUB instruction and side effects.
1916 ****************************************************************************/
1917 u32 sub_long(u32 d, u32 s)
1919 register u32 res; /* all operands in native machine order */
1923 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1924 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1925 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1927 /* calculate the borrow chain. See note at top */
1928 bc = (res & (~d | s)) | (~d & s);
1929 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1930 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1931 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1935 /****************************************************************************
1937 Implements the TEST instruction and side effects.
1938 ****************************************************************************/
1939 void test_byte(u8 d, u8 s)
1941 register u32 res; /* all operands in native machine order */
1946 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1947 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1948 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1949 /* AF == dont care */
1953 /****************************************************************************
1955 Implements the TEST instruction and side effects.
1956 ****************************************************************************/
1957 void test_word(u16 d, u16 s)
1959 register u32 res; /* all operands in native machine order */
1964 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1965 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1966 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1967 /* AF == dont care */
1971 /****************************************************************************
1973 Implements the TEST instruction and side effects.
1974 ****************************************************************************/
1975 void test_long(u32 d, u32 s)
1977 register u32 res; /* all operands in native machine order */
1982 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1983 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1984 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1985 /* AF == dont care */
1989 /****************************************************************************
1991 Implements the XOR instruction and side effects.
1992 ****************************************************************************/
1993 u8 xor_byte(u8 d, u8 s)
1995 register u8 res; /* all operands in native machine order */
1999 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
2000 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2001 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
2007 /****************************************************************************
2009 Implements the XOR instruction and side effects.
2010 ****************************************************************************/
2011 u16 xor_word(u16 d, u16 s)
2013 register u16 res; /* all operands in native machine order */
2017 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
2018 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2019 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2025 /****************************************************************************
2027 Implements the XOR instruction and side effects.
2028 ****************************************************************************/
2029 u32 xor_long(u32 d, u32 s)
2031 register u32 res; /* all operands in native machine order */
2035 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
2036 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2037 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2043 /****************************************************************************
2045 Implements the IMUL instruction and side effects.
2046 ****************************************************************************/
2047 void imul_byte(u8 s)
2049 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
2052 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
2053 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
2062 /****************************************************************************
2064 Implements the IMUL instruction and side effects.
2065 ****************************************************************************/
2066 void imul_word(u16 s)
2068 s32 res = (s16)M.x86.R_AX * (s16)s;
2070 M.x86.R_AX = (u16)res;
2071 M.x86.R_DX = (u16)(res >> 16);
2072 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
2073 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
2082 /****************************************************************************
2084 Implements the IMUL instruction and side effects.
2085 ****************************************************************************/
2086 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2088 #ifdef __HAS_LONG_LONG__
2089 s64 res = (s32)d * (s32)s;
2092 *res_hi = (u32)(res >> 32);
2094 u32 d_lo,d_hi,d_sign;
2095 u32 s_lo,s_hi,s_sign;
2096 u32 rlo_lo,rlo_hi,rhi_lo;
2098 if ((d_sign = d & 0x80000000) != 0)
2102 if ((s_sign = s & 0x80000000) != 0)
2106 rlo_lo = d_lo * s_lo;
2107 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
2108 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
2109 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2111 if (d_sign != s_sign) {
2113 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
2114 *res_lo = ~*res_lo+1;
2115 *res_hi = ~*res_hi+(s >> 16);
2120 /****************************************************************************
2122 Implements the IMUL instruction and side effects.
2123 ****************************************************************************/
2124 void imul_long(u32 s)
2126 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
2127 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
2128 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
2137 /****************************************************************************
2139 Implements the MUL instruction and side effects.
2140 ****************************************************************************/
2143 u16 res = (u16)(M.x86.R_AL * s);
2146 if (M.x86.R_AH == 0) {
2155 /****************************************************************************
2157 Implements the MUL instruction and side effects.
2158 ****************************************************************************/
2159 void mul_word(u16 s)
2161 u32 res = M.x86.R_AX * s;
2163 M.x86.R_AX = (u16)res;
2164 M.x86.R_DX = (u16)(res >> 16);
2165 if (M.x86.R_DX == 0) {
2174 /****************************************************************************
2176 Implements the MUL instruction and side effects.
2177 ****************************************************************************/
2178 void mul_long(u32 s)
2180 #ifdef __HAS_LONG_LONG__
2181 u64 res = (u32)M.x86.R_EAX * (u32)s;
2183 M.x86.R_EAX = (u32)res;
2184 M.x86.R_EDX = (u32)(res >> 32);
2188 u32 rlo_lo,rlo_hi,rhi_lo;
2195 rlo_lo = a_lo * s_lo;
2196 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2197 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2198 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2199 M.x86.R_EDX = rhi_lo;
2202 if (M.x86.R_EDX == 0) {
2211 /****************************************************************************
2213 Implements the IDIV instruction and side effects.
2214 ****************************************************************************/
2215 void idiv_byte(u8 s)
2219 dvd = (s16)M.x86.R_AX;
2221 x86emu_intr_raise(0);
2226 if (abs(div) > 0x7f) {
2227 x86emu_intr_raise(0);
2230 M.x86.R_AL = (s8) div;
2231 M.x86.R_AH = (s8) mod;
2234 /****************************************************************************
2236 Implements the IDIV instruction and side effects.
2237 ****************************************************************************/
2238 void idiv_word(u16 s)
2242 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2244 x86emu_intr_raise(0);
2249 if (abs(div) > 0x7fff) {
2250 x86emu_intr_raise(0);
2255 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2256 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2258 M.x86.R_AX = (u16)div;
2259 M.x86.R_DX = (u16)mod;
2262 /****************************************************************************
2264 Implements the IDIV instruction and side effects.
2265 ****************************************************************************/
2266 void idiv_long(u32 s)
2268 #ifdef __HAS_LONG_LONG__
2271 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2273 x86emu_intr_raise(0);
2278 if (abs(div) > 0x7fffffff) {
2279 x86emu_intr_raise(0);
2284 s32 h_dvd = M.x86.R_EDX;
2285 u32 l_dvd = M.x86.R_EAX;
2286 u32 abs_s = s & 0x7FFFFFFF;
2287 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2288 u32 h_s = abs_s >> 1;
2289 u32 l_s = abs_s << 31;
2294 x86emu_intr_raise(0);
2299 carry = (l_dvd >= l_s) ? 0 : 1;
2301 if (abs_h_dvd < (h_s + carry)) {
2303 l_s = abs_s << (--counter);
2306 abs_h_dvd -= (h_s + carry);
2307 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2310 l_s = abs_s << (--counter);
2315 } while (counter > -1);
2317 if (abs_h_dvd || (l_dvd > abs_s)) {
2318 x86emu_intr_raise(0);
2322 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2330 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2332 M.x86.R_EAX = (u32)div;
2333 M.x86.R_EDX = (u32)mod;
2336 /****************************************************************************
2338 Implements the DIV instruction and side effects.
2339 ****************************************************************************/
2346 x86emu_intr_raise(0);
2351 if (abs(div) > 0xff) {
2352 x86emu_intr_raise(0);
2355 M.x86.R_AL = (u8)div;
2356 M.x86.R_AH = (u8)mod;
2359 /****************************************************************************
2361 Implements the DIV instruction and side effects.
2362 ****************************************************************************/
2363 void div_word(u16 s)
2367 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2369 x86emu_intr_raise(0);
2374 if (abs(div) > 0xffff) {
2375 x86emu_intr_raise(0);
2380 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2381 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2383 M.x86.R_AX = (u16)div;
2384 M.x86.R_DX = (u16)mod;
2387 /****************************************************************************
2389 Implements the DIV instruction and side effects.
2390 ****************************************************************************/
2391 void div_long(u32 s)
2393 #ifdef __HAS_LONG_LONG__
2396 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2398 x86emu_intr_raise(0);
2403 if (abs(div) > 0xffffffff) {
2404 x86emu_intr_raise(0);
2409 s32 h_dvd = M.x86.R_EDX;
2410 u32 l_dvd = M.x86.R_EAX;
2418 x86emu_intr_raise(0);
2423 carry = (l_dvd >= l_s) ? 0 : 1;
2425 if (h_dvd < (h_s + carry)) {
2427 l_s = s << (--counter);
2430 h_dvd -= (h_s + carry);
2431 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2434 l_s = s << (--counter);
2439 } while (counter > -1);
2441 if (h_dvd || (l_dvd > s)) {
2442 x86emu_intr_raise(0);
2451 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2453 M.x86.R_EAX = (u32)div;
2454 M.x86.R_EDX = (u32)mod;
2457 #endif /* __HAVE_INLINE_ASSEMBLER__ */
2459 /****************************************************************************
2461 Implements the IN string instruction and side effects.
2462 ****************************************************************************/
2467 if (ACCESS_FLAG(F_DF)) {
2470 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2471 /* dont care whether REPE or REPNE */
2472 /* in until CX is ZERO. */
2473 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2474 M.x86.R_ECX : M.x86.R_CX);
2478 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2479 (*sys_inb)(M.x86.R_DX));
2486 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2487 (*sys_inw)(M.x86.R_DX));
2493 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2494 (*sys_inl)(M.x86.R_DX));
2500 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2503 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2507 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2508 (*sys_inb)(M.x86.R_DX));
2511 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2512 (*sys_inw)(M.x86.R_DX));
2515 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2516 (*sys_inl)(M.x86.R_DX));
2523 /****************************************************************************
2525 Implements the OUT string instruction and side effects.
2526 ****************************************************************************/
2531 if (ACCESS_FLAG(F_DF)) {
2534 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2535 /* dont care whether REPE or REPNE */
2536 /* out until CX is ZERO. */
2537 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2538 M.x86.R_ECX : M.x86.R_CX);
2542 (*sys_outb)(M.x86.R_DX,
2543 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2550 (*sys_outw)(M.x86.R_DX,
2551 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2557 (*sys_outl)(M.x86.R_DX,
2558 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2564 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2567 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2571 (*sys_outb)(M.x86.R_DX,
2572 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2575 (*sys_outw)(M.x86.R_DX,
2576 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2579 (*sys_outl)(M.x86.R_DX,
2580 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2587 /****************************************************************************
2589 addr - Address to fetch word from
2592 Fetches a word from emulator memory using an absolute address.
2593 ****************************************************************************/
2594 u16 mem_access_word(int addr)
2596 DB( if (CHECK_MEM_ACCESS())
2597 x86emu_check_mem_access(addr);)
2598 return (*sys_rdw)(addr);
2601 /****************************************************************************
2603 Pushes a word onto the stack.
2605 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2606 ****************************************************************************/
2607 void push_word(u16 w)
2609 DB( if (CHECK_SP_ACCESS())
2610 x86emu_check_sp_access();)
2612 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2615 /****************************************************************************
2617 Pushes a long onto the stack.
2619 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2620 ****************************************************************************/
2621 void push_long(u32 w)
2623 DB( if (CHECK_SP_ACCESS())
2624 x86emu_check_sp_access();)
2626 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2629 /****************************************************************************
2631 Pops a word from the stack.
2633 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2634 ****************************************************************************/
2639 DB( if (CHECK_SP_ACCESS())
2640 x86emu_check_sp_access();)
2641 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2646 /****************************************************************************
2648 Pops a long from the stack.
2650 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2651 ****************************************************************************/
2656 DB( if (CHECK_SP_ACCESS())
2657 x86emu_check_sp_access();)
2658 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2663 #ifdef __HAVE_INLINE_ASSEMBLER__
2665 u16 aaa_word (u16 d)
2666 { return aaa_word_asm(&M.x86.R_EFLG,d); }
2668 u16 aas_word (u16 d)
2669 { return aas_word_asm(&M.x86.R_EFLG,d); }
2671 u16 aad_word (u16 d)
2672 { return aad_word_asm(&M.x86.R_EFLG,d); }
2675 { return aam_word_asm(&M.x86.R_EFLG,d); }
2677 u8 adc_byte (u8 d, u8 s)
2678 { return adc_byte_asm(&M.x86.R_EFLG,d,s); }
2680 u16 adc_word (u16 d, u16 s)
2681 { return adc_word_asm(&M.x86.R_EFLG,d,s); }
2683 u32 adc_long (u32 d, u32 s)
2684 { return adc_long_asm(&M.x86.R_EFLG,d,s); }
2686 u8 add_byte (u8 d, u8 s)
2687 { return add_byte_asm(&M.x86.R_EFLG,d,s); }
2689 u16 add_word (u16 d, u16 s)
2690 { return add_word_asm(&M.x86.R_EFLG,d,s); }
2692 u32 add_long (u32 d, u32 s)
2693 { return add_long_asm(&M.x86.R_EFLG,d,s); }
2695 u8 and_byte (u8 d, u8 s)
2696 { return and_byte_asm(&M.x86.R_EFLG,d,s); }
2698 u16 and_word (u16 d, u16 s)
2699 { return and_word_asm(&M.x86.R_EFLG,d,s); }
2701 u32 and_long (u32 d, u32 s)
2702 { return and_long_asm(&M.x86.R_EFLG,d,s); }
2704 u8 cmp_byte (u8 d, u8 s)
2705 { return cmp_byte_asm(&M.x86.R_EFLG,d,s); }
2707 u16 cmp_word (u16 d, u16 s)
2708 { return cmp_word_asm(&M.x86.R_EFLG,d,s); }
2710 u32 cmp_long (u32 d, u32 s)
2711 { return cmp_long_asm(&M.x86.R_EFLG,d,s); }
2714 { return daa_byte_asm(&M.x86.R_EFLG,d); }
2717 { return das_byte_asm(&M.x86.R_EFLG,d); }
2720 { return dec_byte_asm(&M.x86.R_EFLG,d); }
2722 u16 dec_word (u16 d)
2723 { return dec_word_asm(&M.x86.R_EFLG,d); }
2725 u32 dec_long (u32 d)
2726 { return dec_long_asm(&M.x86.R_EFLG,d); }
2729 { return inc_byte_asm(&M.x86.R_EFLG,d); }
2731 u16 inc_word (u16 d)
2732 { return inc_word_asm(&M.x86.R_EFLG,d); }
2734 u32 inc_long (u32 d)
2735 { return inc_long_asm(&M.x86.R_EFLG,d); }
2737 u8 or_byte (u8 d, u8 s)
2738 { return or_byte_asm(&M.x86.R_EFLG,d,s); }
2740 u16 or_word (u16 d, u16 s)
2741 { return or_word_asm(&M.x86.R_EFLG,d,s); }
2743 u32 or_long (u32 d, u32 s)
2744 { return or_long_asm(&M.x86.R_EFLG,d,s); }
2747 { return neg_byte_asm(&M.x86.R_EFLG,s); }
2749 u16 neg_word (u16 s)
2750 { return neg_word_asm(&M.x86.R_EFLG,s); }
2752 u32 neg_long (u32 s)
2753 { return neg_long_asm(&M.x86.R_EFLG,s); }
2756 { return not_byte_asm(&M.x86.R_EFLG,s); }
2758 u16 not_word (u16 s)
2759 { return not_word_asm(&M.x86.R_EFLG,s); }
2761 u32 not_long (u32 s)
2762 { return not_long_asm(&M.x86.R_EFLG,s); }
2764 u8 rcl_byte (u8 d, u8 s)
2765 { return rcl_byte_asm(&M.x86.R_EFLG,d,s); }
2767 u16 rcl_word (u16 d, u8 s)
2768 { return rcl_word_asm(&M.x86.R_EFLG,d,s); }
2770 u32 rcl_long (u32 d, u8 s)
2771 { return rcl_long_asm(&M.x86.R_EFLG,d,s); }
2773 u8 rcr_byte (u8 d, u8 s)
2774 { return rcr_byte_asm(&M.x86.R_EFLG,d,s); }
2776 u16 rcr_word (u16 d, u8 s)
2777 { return rcr_word_asm(&M.x86.R_EFLG,d,s); }
2779 u32 rcr_long (u32 d, u8 s)
2780 { return rcr_long_asm(&M.x86.R_EFLG,d,s); }
2782 u8 rol_byte (u8 d, u8 s)
2783 { return rol_byte_asm(&M.x86.R_EFLG,d,s); }
2785 u16 rol_word (u16 d, u8 s)
2786 { return rol_word_asm(&M.x86.R_EFLG,d,s); }
2788 u32 rol_long (u32 d, u8 s)
2789 { return rol_long_asm(&M.x86.R_EFLG,d,s); }
2791 u8 ror_byte (u8 d, u8 s)
2792 { return ror_byte_asm(&M.x86.R_EFLG,d,s); }
2794 u16 ror_word (u16 d, u8 s)
2795 { return ror_word_asm(&M.x86.R_EFLG,d,s); }
2797 u32 ror_long (u32 d, u8 s)
2798 { return ror_long_asm(&M.x86.R_EFLG,d,s); }
2800 u8 shl_byte (u8 d, u8 s)
2801 { return shl_byte_asm(&M.x86.R_EFLG,d,s); }
2803 u16 shl_word (u16 d, u8 s)
2804 { return shl_word_asm(&M.x86.R_EFLG,d,s); }
2806 u32 shl_long (u32 d, u8 s)
2807 { return shl_long_asm(&M.x86.R_EFLG,d,s); }
2809 u8 shr_byte (u8 d, u8 s)
2810 { return shr_byte_asm(&M.x86.R_EFLG,d,s); }
2812 u16 shr_word (u16 d, u8 s)
2813 { return shr_word_asm(&M.x86.R_EFLG,d,s); }
2815 u32 shr_long (u32 d, u8 s)
2816 { return shr_long_asm(&M.x86.R_EFLG,d,s); }
2818 u8 sar_byte (u8 d, u8 s)
2819 { return sar_byte_asm(&M.x86.R_EFLG,d,s); }
2821 u16 sar_word (u16 d, u8 s)
2822 { return sar_word_asm(&M.x86.R_EFLG,d,s); }
2824 u32 sar_long (u32 d, u8 s)
2825 { return sar_long_asm(&M.x86.R_EFLG,d,s); }
2827 u16 shld_word (u16 d, u16 fill, u8 s)
2828 { return shld_word_asm(&M.x86.R_EFLG,d,fill,s); }
2830 u32 shld_long (u32 d, u32 fill, u8 s)
2831 { return shld_long_asm(&M.x86.R_EFLG,d,fill,s); }
2833 u16 shrd_word (u16 d, u16 fill, u8 s)
2834 { return shrd_word_asm(&M.x86.R_EFLG,d,fill,s); }
2836 u32 shrd_long (u32 d, u32 fill, u8 s)
2837 { return shrd_long_asm(&M.x86.R_EFLG,d,fill,s); }
2839 u8 sbb_byte (u8 d, u8 s)
2840 { return sbb_byte_asm(&M.x86.R_EFLG,d,s); }
2842 u16 sbb_word (u16 d, u16 s)
2843 { return sbb_word_asm(&M.x86.R_EFLG,d,s); }
2845 u32 sbb_long (u32 d, u32 s)
2846 { return sbb_long_asm(&M.x86.R_EFLG,d,s); }
2848 u8 sub_byte (u8 d, u8 s)
2849 { return sub_byte_asm(&M.x86.R_EFLG,d,s); }
2851 u16 sub_word (u16 d, u16 s)
2852 { return sub_word_asm(&M.x86.R_EFLG,d,s); }
2854 u32 sub_long (u32 d, u32 s)
2855 { return sub_long_asm(&M.x86.R_EFLG,d,s); }
2857 void test_byte (u8 d, u8 s)
2858 { test_byte_asm(&M.x86.R_EFLG,d,s); }
2860 void test_word (u16 d, u16 s)
2861 { test_word_asm(&M.x86.R_EFLG,d,s); }
2863 void test_long (u32 d, u32 s)
2864 { test_long_asm(&M.x86.R_EFLG,d,s); }
2866 u8 xor_byte (u8 d, u8 s)
2867 { return xor_byte_asm(&M.x86.R_EFLG,d,s); }
2869 u16 xor_word (u16 d, u16 s)
2870 { return xor_word_asm(&M.x86.R_EFLG,d,s); }
2872 u32 xor_long (u32 d, u32 s)
2873 { return xor_long_asm(&M.x86.R_EFLG,d,s); }
2875 void imul_byte (u8 s)
2876 { imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2878 void imul_word (u16 s)
2879 { imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2881 void imul_long (u32 s)
2882 { imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2884 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2885 { imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s); }
2887 void mul_byte (u8 s)
2888 { mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2890 void mul_word (u16 s)
2891 { mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2893 void mul_long (u32 s)
2894 { mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2896 void idiv_byte (u8 s)
2897 { idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2899 void idiv_word (u16 s)
2900 { idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2902 void idiv_long (u32 s)
2903 { idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
2905 void div_byte (u8 s)
2906 { div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2908 void div_word (u16 s)
2909 { div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2911 void div_long (u32 s)
2912 { div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }