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] = {
120 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
121 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
123 /*----------------------------- Implementation ----------------------------*/
125 #ifndef __HAVE_INLINE_ASSEMBLER__
127 /****************************************************************************
129 Implements the AAA instruction and side effects.
130 ****************************************************************************/
134 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
143 res = (u16) (d & 0xFF0F);
145 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
146 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
150 /****************************************************************************
152 Implements the AAA instruction and side effects.
153 ****************************************************************************/
157 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
166 res = (u16) (d & 0xFF0F);
168 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
169 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
173 /****************************************************************************
175 Implements the AAD instruction and side effects.
176 ****************************************************************************/
182 hb = (u8) ((d >> 8) & 0xff);
183 lb = (u8) ((d & 0xff));
184 l = (u16) ((lb + 10 * hb) & 0xFF);
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);
195 /****************************************************************************
197 Implements the AAM instruction and side effects.
198 ****************************************************************************/
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);
216 /****************************************************************************
218 Implements the ADC instruction and side effects.
219 ****************************************************************************/
220 u8 adc_byte(u8 d, u8 s)
222 register u32 res; /* all operands in native machine order */
225 if (ACCESS_FLAG(F_CF))
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);
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);
242 /****************************************************************************
244 Implements the ADC instruction and side effects.
245 ****************************************************************************/
246 u16 adc_word(u16 d, u16 s)
248 register u32 res; /* all operands in native machine order */
251 if (ACCESS_FLAG(F_CF))
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);
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);
268 /****************************************************************************
270 Implements the ADC instruction and side effects.
271 ****************************************************************************/
272 u32 adc_long(u32 d, u32 s)
274 register u32 lo; /* all operands in native machine order */
279 if (ACCESS_FLAG(F_CF)) {
280 lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
283 lo = (d & 0xFFFF) + (s & 0xFFFF);
286 hi = (lo >> 16) + (d >> 16) + (s >> 16);
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);
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);
300 /****************************************************************************
302 Implements the ADD instruction and side effects.
303 ****************************************************************************/
304 u8 add_byte(u8 d, u8 s)
306 register u32 res; /* all operands in native machine order */
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);
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);
322 /****************************************************************************
324 Implements the ADD instruction and side effects.
325 ****************************************************************************/
326 u16 add_word(u16 d, u16 s)
328 register u32 res; /* all operands in native machine order */
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);
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);
344 /****************************************************************************
346 Implements the ADD instruction and side effects.
347 ****************************************************************************/
348 u32 add_long(u32 d, u32 s)
350 register u32 lo; /* all operands in native machine order */
355 lo = (d & 0xFFFF) + (s & 0xFFFF);
357 hi = (lo >> 16) + (d >> 16) + (s >> 16);
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);
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);
372 /****************************************************************************
374 Implements the AND instruction and side effects.
375 ****************************************************************************/
376 u8 and_byte(u8 d, u8 s)
378 register u8 res; /* all operands in native machine order */
386 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
387 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
388 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
392 /****************************************************************************
394 Implements the AND instruction and side effects.
395 ****************************************************************************/
396 u16 and_word(u16 d, u16 s)
398 register u16 res; /* all operands in native machine order */
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);
412 /****************************************************************************
414 Implements the AND instruction and side effects.
415 ****************************************************************************/
416 u32 and_long(u32 d, u32 s)
418 register u32 res; /* all operands in native machine order */
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);
432 /****************************************************************************
434 Implements the CMP instruction and side effects.
435 ****************************************************************************/
436 u8 cmp_byte(u8 d, u8 s)
438 register u32 res; /* all operands in native machine order */
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);
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);
455 /****************************************************************************
457 Implements the CMP instruction and side effects.
458 ****************************************************************************/
459 u16 cmp_word(u16 d, u16 s)
461 register u32 res; /* all operands in native machine order */
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);
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);
477 /****************************************************************************
479 Implements the CMP instruction and side effects.
480 ****************************************************************************/
481 u32 cmp_long(u32 d, u32 s)
483 register u32 res; /* all operands in native machine order */
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);
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);
499 /****************************************************************************
501 Implements the DAA instruction and side effects.
502 ****************************************************************************/
506 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
510 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
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);
520 /****************************************************************************
522 Implements the DAS instruction and side effects.
523 ****************************************************************************/
526 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
530 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
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);
540 /****************************************************************************
542 Implements the DEC instruction and side effects.
543 ****************************************************************************/
546 register u32 res; /* all operands in native machine order */
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);
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);
563 /****************************************************************************
565 Implements the DEC instruction and side effects.
566 ****************************************************************************/
569 register u32 res; /* all operands in native machine order */
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);
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);
586 /****************************************************************************
588 Implements the DEC instruction and side effects.
589 ****************************************************************************/
592 register u32 res; /* all operands in native machine order */
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);
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);
609 /****************************************************************************
611 Implements the INC instruction and side effects.
612 ****************************************************************************/
615 register u32 res; /* all operands in native machine order */
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);
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);
630 /****************************************************************************
632 Implements the INC instruction and side effects.
633 ****************************************************************************/
636 register u32 res; /* all operands in native machine order */
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);
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);
651 /****************************************************************************
653 Implements the INC instruction and side effects.
654 ****************************************************************************/
657 register u32 res; /* all operands in native machine order */
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);
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);
672 /****************************************************************************
674 Implements the OR instruction and side effects.
675 ****************************************************************************/
676 u8 or_byte(u8 d, u8 s)
678 register u8 res; /* all operands in native machine order */
684 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
685 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
686 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
690 /****************************************************************************
692 Implements the OR instruction and side effects.
693 ****************************************************************************/
694 u16 or_word(u16 d, u16 s)
696 register u16 res; /* all operands in native machine order */
699 /* set the carry flag to be bit 8 */
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);
709 /****************************************************************************
711 Implements the OR instruction and side effects.
712 ****************************************************************************/
713 u32 or_long(u32 d, u32 s)
715 register u32 res; /* all operands in native machine order */
719 /* set the carry flag to be bit 8 */
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);
729 /****************************************************************************
731 Implements the OR instruction and side effects.
732 ****************************************************************************/
738 CONDITIONAL_SET_FLAG(s != 0, F_CF);
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: */
749 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
750 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
754 /****************************************************************************
756 Implements the OR instruction and side effects.
757 ****************************************************************************/
763 CONDITIONAL_SET_FLAG(s != 0, F_CF);
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);
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: */
775 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
776 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
780 /****************************************************************************
782 Implements the OR instruction and side effects.
783 ****************************************************************************/
789 CONDITIONAL_SET_FLAG(s != 0, F_CF);
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);
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: */
801 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
802 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
806 /****************************************************************************
808 Implements the NOT instruction and side effects.
809 ****************************************************************************/
815 /****************************************************************************
817 Implements the NOT instruction and side effects.
818 ****************************************************************************/
824 /****************************************************************************
826 Implements the NOT instruction and side effects.
827 ****************************************************************************/
833 /****************************************************************************
835 Implements the RCL instruction and side effects.
836 ****************************************************************************/
837 u8 rcl_byte(u8 d, u8 s)
839 register unsigned int res, cnt, mask, cf;
841 /* s is the rotate distance. It varies from 0 - 8. */
844 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
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:
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
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:
863 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
865 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
868 if ((cnt = s % 9) != 0) {
869 /* extract the new CARRY FLAG. */
871 cf = (d >> (8 - cnt)) & 0x1;
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;
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.
885 mask = (1 << (cnt - 1)) - 1;
886 res |= (d >> (9 - cnt)) & mask;
888 /* if the carry flag was set, or it in. */
889 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
891 res |= 1 << (cnt - 1);
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);
905 /****************************************************************************
907 Implements the RCL instruction and side effects.
908 ****************************************************************************/
909 u16 rcl_word(u16 d, u8 s)
911 register unsigned int res, cnt, mask, cf;
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);
922 CONDITIONAL_SET_FLAG(cf, F_CF);
923 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF);
928 /****************************************************************************
930 Implements the RCL instruction and side effects.
931 ****************************************************************************/
932 u32 rcl_long(u32 d, u8 s)
934 register u32 res, cnt, mask, cf;
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);
945 CONDITIONAL_SET_FLAG(cf, F_CF);
946 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF);
951 /****************************************************************************
953 Implements the RCR instruction and side effects.
954 ****************************************************************************/
955 u8 rcr_byte(u8 d, u8 s)
958 u32 mask, cf, ocf = 0;
960 /* rotate right through carry */
962 s is the rotate distance. It varies from 0 - 8.
963 d is the byte object rotated.
967 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
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:
978 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
980 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
983 if ((cnt = s % 9) != 0) {
984 /* extract the new CARRY FLAG. */
988 /* note hackery here. Access_flag(..) evaluates to either
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.)
995 ocf = ACCESS_FLAG(F_CF) != 0;
997 cf = (d >> (cnt - 1)) & 0x1;
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??? */
1006 mask = (1 << (8 - cnt)) - 1;
1007 res = (d >> cnt) & mask;
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.
1015 res |= (d << (9 - cnt));
1017 /* if the carry flag was set, or it in. */
1018 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1020 res |= 1 << (8 - cnt);
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... */
1028 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF);
1034 /****************************************************************************
1036 Implements the RCR instruction and side effects.
1037 ****************************************************************************/
1038 u16 rcr_word(u16 d, u8 s)
1041 u32 mask, cf, ocf = 0;
1043 /* rotate right through carry */
1045 if ((cnt = s % 17) != 0) {
1048 ocf = ACCESS_FLAG(F_CF) != 0;
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);
1057 CONDITIONAL_SET_FLAG(cf, F_CF);
1059 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF);
1065 /****************************************************************************
1067 Implements the RCR instruction and side effects.
1068 ****************************************************************************/
1069 u32 rcr_long(u32 d, u8 s)
1072 u32 mask, cf, ocf = 0;
1074 /* rotate right through carry */
1076 if ((cnt = s % 33) != 0) {
1079 ocf = ACCESS_FLAG(F_CF) != 0;
1081 cf = (d >> (cnt - 1)) & 0x1;
1082 mask = (1 << (32 - cnt)) - 1;
1083 res = (d >> cnt) & mask;
1085 res |= (d << (33 - cnt));
1086 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1087 res |= 1 << (32 - cnt);
1089 CONDITIONAL_SET_FLAG(cf, F_CF);
1091 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF);
1097 /****************************************************************************
1099 Implements the ROL instruction and side effects.
1100 ****************************************************************************/
1101 u8 rol_byte(u8 d, u8 s)
1103 register unsigned int res, cnt, mask;
1107 s is the rotate distance. It varies from 0 - 8.
1108 d is the byte object rotated.
1114 The new rotate is done mod 8.
1115 Much simpler than the "rcl" or "rcr" operations.
1118 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1119 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1122 if ((cnt = s % 8) != 0) {
1123 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1126 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1127 mask = (1 << cnt) - 1;
1128 res |= (d >> (8 - cnt)) & mask;
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);
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);
1146 /****************************************************************************
1148 Implements the ROL instruction and side effects.
1149 ****************************************************************************/
1150 u16 rol_word(u16 d, u8 s)
1152 register unsigned int res, cnt, mask;
1155 if ((cnt = s % 16) != 0) {
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);
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);
1171 /****************************************************************************
1173 Implements the ROL instruction and side effects.
1174 ****************************************************************************/
1175 u32 rol_long(u32 d, u8 s)
1177 register u32 res, cnt, mask;
1180 if ((cnt = s % 32) != 0) {
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);
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);
1196 /****************************************************************************
1198 Implements the ROR instruction and side effects.
1199 ****************************************************************************/
1200 u8 ror_byte(u8 d, u8 s)
1202 register unsigned int res, cnt, mask;
1206 s is the rotate distance. It varies from 0 - 8.
1207 d is the byte object rotated.
1213 The rotate is done mod 8.
1216 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1217 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
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));
1224 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1225 mask = (1 << (8 - cnt)) - 1;
1226 res |= (d >> (cnt)) & mask;
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);
1242 /****************************************************************************
1244 Implements the ROR instruction and side effects.
1245 ****************************************************************************/
1246 u16 ror_word(u16 d, u8 s)
1248 register unsigned int res, cnt, mask;
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);
1265 /****************************************************************************
1267 Implements the ROR instruction and side effects.
1268 ****************************************************************************/
1269 u32 ror_long(u32 d, u8 s)
1271 register u32 res, cnt, mask;
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);
1288 /****************************************************************************
1290 Implements the SHL instruction and side effects.
1291 ****************************************************************************/
1292 u8 shl_byte(u8 d, u8 s)
1294 unsigned int cnt, res, cf;
1299 /* last bit shifted out goes into carry flag */
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);
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)), */
1322 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
1331 /****************************************************************************
1333 Implements the SHL instruction and side effects.
1334 ****************************************************************************/
1335 u16 shl_word(u16 d, u8 s)
1337 unsigned int cnt, res, cf;
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);
1353 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1354 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1360 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
1369 /****************************************************************************
1371 Implements the SHL instruction and side effects.
1372 ****************************************************************************/
1373 u32 shl_long(u32 d, u8 s)
1375 unsigned int cnt, res, cf;
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);
1390 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1391 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1397 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
1406 /****************************************************************************
1408 Implements the SHR instruction and side effects.
1409 ****************************************************************************/
1410 u8 shr_byte(u8 d, u8 s)
1412 unsigned int cnt, res, cf;
1417 cf = d & (1 << (cnt - 1));
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);
1428 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1434 CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
1443 /****************************************************************************
1445 Implements the SHR instruction and side effects.
1446 ****************************************************************************/
1447 u16 shr_word(u16 d, u8 s)
1449 unsigned int cnt, res, cf;
1454 cf = d & (1 << (cnt - 1));
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);
1465 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1480 /****************************************************************************
1482 Implements the SHR instruction and side effects.
1483 ****************************************************************************/
1484 u32 shr_long(u32 d, u8 s)
1486 unsigned int cnt, res, cf;
1491 cf = d & (1 << (cnt - 1));
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);
1501 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1516 /****************************************************************************
1518 Implements the SAR instruction and side effects.
1519 ****************************************************************************/
1520 u8 sar_byte(u8 d, u8 s)
1522 unsigned int cnt, res, cf, mask, sf;
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);
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) {
1556 /****************************************************************************
1558 Implements the SAR instruction and side effects.
1559 ****************************************************************************/
1560 u16 sar_word(u16 d, u8 s)
1562 unsigned int cnt, res, cf, mask, sf;
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);
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) {
1596 /****************************************************************************
1598 Implements the SAR instruction and side effects.
1599 ****************************************************************************/
1600 u32 sar_long(u32 d, u8 s)
1602 u32 cnt, res, cf, mask, sf;
1604 sf = d & 0x80000000;
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);
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) {
1636 /****************************************************************************
1638 Implements the SHLD instruction and side effects.
1639 ****************************************************************************/
1640 u16 shld_word(u16 d, u16 fill, u8 s)
1642 unsigned int cnt, res, cf;
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);
1657 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1658 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1664 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
1673 /****************************************************************************
1675 Implements the SHLD instruction and side effects.
1676 ****************************************************************************/
1677 u32 shld_long(u32 d, u32 fill, u8 s)
1679 unsigned int cnt, res, cf;
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);
1694 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1695 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1701 CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
1710 /****************************************************************************
1712 Implements the SHRD instruction and side effects.
1713 ****************************************************************************/
1714 u16 shrd_word(u16 d, u16 fill, u8 s)
1716 unsigned int cnt, res, cf;
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);
1732 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1747 /****************************************************************************
1749 Implements the SHRD instruction and side effects.
1750 ****************************************************************************/
1751 u32 shrd_long(u32 d, u32 fill, u8 s)
1753 unsigned int cnt, res, cf;
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);
1768 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1783 /****************************************************************************
1785 Implements the SBB instruction and side effects.
1786 ****************************************************************************/
1787 u8 sbb_byte(u8 d, u8 s)
1789 register u32 res; /* all operands in native machine order */
1792 if (ACCESS_FLAG(F_CF))
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);
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);
1808 /****************************************************************************
1810 Implements the SBB instruction and side effects.
1811 ****************************************************************************/
1812 u16 sbb_word(u16 d, u16 s)
1814 register u32 res; /* all operands in native machine order */
1817 if (ACCESS_FLAG(F_CF))
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);
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);
1833 /****************************************************************************
1835 Implements the SBB instruction and side effects.
1836 ****************************************************************************/
1837 u32 sbb_long(u32 d, u32 s)
1839 register u32 res; /* all operands in native machine order */
1842 if (ACCESS_FLAG(F_CF))
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);
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);
1858 /****************************************************************************
1860 Implements the SUB instruction and side effects.
1861 ****************************************************************************/
1862 u8 sub_byte(u8 d, u8 s)
1864 register u32 res; /* all operands in native machine order */
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);
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);
1880 /****************************************************************************
1882 Implements the SUB instruction and side effects.
1883 ****************************************************************************/
1884 u16 sub_word(u16 d, u16 s)
1886 register u32 res; /* all operands in native machine order */
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);
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);
1902 /****************************************************************************
1904 Implements the SUB instruction and side effects.
1905 ****************************************************************************/
1906 u32 sub_long(u32 d, u32 s)
1908 register u32 res; /* all operands in native machine order */
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);
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);
1924 /****************************************************************************
1926 Implements the TEST instruction and side effects.
1927 ****************************************************************************/
1928 void test_byte(u8 d, u8 s)
1930 register u32 res; /* all operands in native machine order */
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 */
1942 /****************************************************************************
1944 Implements the TEST instruction and side effects.
1945 ****************************************************************************/
1946 void test_word(u16 d, u16 s)
1948 register u32 res; /* all operands in native machine order */
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 */
1960 /****************************************************************************
1962 Implements the TEST instruction and side effects.
1963 ****************************************************************************/
1964 void test_long(u32 d, u32 s)
1966 register u32 res; /* all operands in native machine order */
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 */
1978 /****************************************************************************
1980 Implements the XOR instruction and side effects.
1981 ****************************************************************************/
1982 u8 xor_byte(u8 d, u8 s)
1984 register u8 res; /* all operands in native machine order */
1988 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1989 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1990 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
1996 /****************************************************************************
1998 Implements the XOR instruction and side effects.
1999 ****************************************************************************/
2000 u16 xor_word(u16 d, u16 s)
2002 register u16 res; /* all operands in native machine order */
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);
2014 /****************************************************************************
2016 Implements the XOR instruction and side effects.
2017 ****************************************************************************/
2018 u32 xor_long(u32 d, u32 s)
2020 register u32 res; /* all operands in native machine order */
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);
2032 /****************************************************************************
2034 Implements the IMUL instruction and side effects.
2035 ****************************************************************************/
2036 void imul_byte(u8 s)
2038 s16 res = (s16) ((s8) M.x86.R_AL * (s8) s);
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)) {
2051 /****************************************************************************
2053 Implements the IMUL instruction and side effects.
2054 ****************************************************************************/
2055 void imul_word(u16 s)
2057 s32 res = (s16) M.x86.R_AX * (s16) s;
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)) {
2071 /****************************************************************************
2073 Implements the IMUL instruction and side effects.
2074 ****************************************************************************/
2075 void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
2077 #ifdef __HAS_LONG_LONG__
2078 s64 res = (s32) d * (s32) s;
2080 *res_lo = (u32) res;
2081 *res_hi = (u32) (res >> 32);
2083 u32 d_lo, d_hi, d_sign;
2084 u32 s_lo, s_hi, s_sign;
2085 u32 rlo_lo, rlo_hi, rhi_lo;
2087 if ((d_sign = d & 0x80000000) != 0)
2091 if ((s_sign = s & 0x80000000) != 0)
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);
2100 if (d_sign != s_sign) {
2102 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
2103 *res_lo = ~*res_lo + 1;
2104 *res_hi = ~*res_hi + (s >> 16);
2109 /****************************************************************************
2111 Implements the IMUL instruction and side effects.
2112 ****************************************************************************/
2113 void imul_long(u32 s)
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)) {
2126 /****************************************************************************
2128 Implements the MUL instruction and side effects.
2129 ****************************************************************************/
2132 u16 res = (u16) (M.x86.R_AL * s);
2135 if (M.x86.R_AH == 0) {
2144 /****************************************************************************
2146 Implements the MUL instruction and side effects.
2147 ****************************************************************************/
2148 void mul_word(u16 s)
2150 u32 res = M.x86.R_AX * s;
2152 M.x86.R_AX = (u16) res;
2153 M.x86.R_DX = (u16) (res >> 16);
2154 if (M.x86.R_DX == 0) {
2163 /****************************************************************************
2165 Implements the MUL instruction and side effects.
2166 ****************************************************************************/
2167 void mul_long(u32 s)
2169 #ifdef __HAS_LONG_LONG__
2170 u64 res = (u32) M.x86.R_EAX * (u32) s;
2172 M.x86.R_EAX = (u32) res;
2173 M.x86.R_EDX = (u32) (res >> 32);
2177 u32 rlo_lo, rlo_hi, rhi_lo;
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;
2191 if (M.x86.R_EDX == 0) {
2200 /****************************************************************************
2202 Implements the IDIV instruction and side effects.
2203 ****************************************************************************/
2204 void idiv_byte(u8 s)
2208 dvd = (s16) M.x86.R_AX;
2210 x86emu_intr_raise(0);
2215 if (abs(div) > 0x7f) {
2216 x86emu_intr_raise(0);
2219 M.x86.R_AL = (s8) div;
2220 M.x86.R_AH = (s8) mod;
2223 /****************************************************************************
2225 Implements the IDIV instruction and side effects.
2226 ****************************************************************************/
2227 void idiv_word(u16 s)
2231 dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX;
2233 x86emu_intr_raise(0);
2236 div = dvd / (s16) s;
2237 mod = dvd % (s16) s;
2238 if (abs(div) > 0x7fff) {
2239 x86emu_intr_raise(0);
2244 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2245 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2247 M.x86.R_AX = (u16) div;
2248 M.x86.R_DX = (u16) mod;
2251 /****************************************************************************
2253 Implements the IDIV instruction and side effects.
2254 ****************************************************************************/
2255 void idiv_long(u32 s)
2257 #ifdef __HAS_LONG_LONG__
2260 dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
2262 x86emu_intr_raise(0);
2265 div = dvd / (s32) s;
2266 mod = dvd % (s32) s;
2267 if (abs(div) > 0x7fffffff) {
2268 x86emu_intr_raise(0);
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;
2283 x86emu_intr_raise(0);
2288 carry = (l_dvd >= l_s) ? 0 : 1;
2290 if (abs_h_dvd < (h_s + carry)) {
2292 l_s = abs_s << (--counter);
2295 abs_h_dvd -= (h_s + carry);
2296 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2299 l_s = abs_s << (--counter);
2304 } while (counter > -1);
2306 if (abs_h_dvd || (l_dvd > abs_s)) {
2307 x86emu_intr_raise(0);
2311 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2319 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2321 M.x86.R_EAX = (u32) div;
2322 M.x86.R_EDX = (u32) mod;
2325 /****************************************************************************
2327 Implements the DIV instruction and side effects.
2328 ****************************************************************************/
2335 x86emu_intr_raise(0);
2340 if (abs(div) > 0xff) {
2341 x86emu_intr_raise(0);
2344 M.x86.R_AL = (u8) div;
2345 M.x86.R_AH = (u8) mod;
2348 /****************************************************************************
2350 Implements the DIV instruction and side effects.
2351 ****************************************************************************/
2352 void div_word(u16 s)
2356 dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX;
2358 x86emu_intr_raise(0);
2361 div = dvd / (u16) s;
2362 mod = dvd % (u16) s;
2363 if (abs(div) > 0xffff) {
2364 x86emu_intr_raise(0);
2369 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2370 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2372 M.x86.R_AX = (u16) div;
2373 M.x86.R_DX = (u16) mod;
2376 /****************************************************************************
2378 Implements the DIV instruction and side effects.
2379 ****************************************************************************/
2380 void div_long(u32 s)
2382 #ifdef __HAS_LONG_LONG__
2385 dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
2387 x86emu_intr_raise(0);
2390 div = dvd / (u32) s;
2391 mod = dvd % (u32) s;
2392 if (abs(div) > 0xffffffff) {
2393 x86emu_intr_raise(0);
2398 s32 h_dvd = M.x86.R_EDX;
2399 u32 l_dvd = M.x86.R_EAX;
2407 x86emu_intr_raise(0);
2412 carry = (l_dvd >= l_s) ? 0 : 1;
2414 if (h_dvd < (h_s + carry)) {
2416 l_s = s << (--counter);
2419 h_dvd -= (h_s + carry);
2420 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2423 l_s = s << (--counter);
2428 } while (counter > -1);
2430 if (h_dvd || (l_dvd > s)) {
2431 x86emu_intr_raise(0);
2440 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2442 M.x86.R_EAX = (u32) div;
2443 M.x86.R_EDX = (u32) mod;
2446 #endif /* __HAVE_INLINE_ASSEMBLER__ */
2448 /****************************************************************************
2450 Implements the IN string instruction and side effects.
2451 ****************************************************************************/
2456 if (ACCESS_FLAG(F_DF)) {
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);
2467 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2468 (*sys_inb) (M.x86.R_DX));
2475 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2476 (*sys_inw) (M.x86.R_DX));
2482 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2483 (*sys_inl) (M.x86.R_DX));
2489 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2492 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2496 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2497 (*sys_inb) (M.x86.R_DX));
2500 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2501 (*sys_inw) (M.x86.R_DX));
2504 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2505 (*sys_inl) (M.x86.R_DX));
2512 /****************************************************************************
2514 Implements the OUT string instruction and side effects.
2515 ****************************************************************************/
2520 if (ACCESS_FLAG(F_DF)) {
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);
2531 (*sys_outb) (M.x86.R_DX,
2532 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2539 (*sys_outw) (M.x86.R_DX,
2540 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2546 (*sys_outl) (M.x86.R_DX,
2547 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2553 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2556 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2560 (*sys_outb) (M.x86.R_DX,
2561 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2564 (*sys_outw) (M.x86.R_DX,
2565 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2568 (*sys_outl) (M.x86.R_DX,
2569 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2576 /****************************************************************************
2578 addr - Address to fetch word from
2581 Fetches a word from emulator memory using an absolute address.
2582 ****************************************************************************/
2583 u16 mem_access_word(int addr)
2585 DB(if (CHECK_MEM_ACCESS())
2586 x86emu_check_mem_access(addr);)
2587 return (*sys_rdw) (addr);
2590 /****************************************************************************
2592 Pushes a word onto the stack.
2594 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2595 ****************************************************************************/
2596 void push_word(u16 w)
2598 DB(if (CHECK_SP_ACCESS())
2599 x86emu_check_sp_access();)
2601 (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
2604 /****************************************************************************
2606 Pushes a long onto the stack.
2608 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2609 ****************************************************************************/
2610 void push_long(u32 w)
2612 DB(if (CHECK_SP_ACCESS())
2613 x86emu_check_sp_access();)
2615 (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
2618 /****************************************************************************
2620 Pops a word from the stack.
2622 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2623 ****************************************************************************/
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);
2635 /****************************************************************************
2637 Pops a long from the stack.
2639 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2640 ****************************************************************************/
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);
2652 #ifdef __HAVE_INLINE_ASSEMBLER__
2656 return aaa_word_asm(&M.x86.R_EFLG, d);
2661 return aas_word_asm(&M.x86.R_EFLG, d);
2666 return aad_word_asm(&M.x86.R_EFLG, d);
2671 return aam_word_asm(&M.x86.R_EFLG, d);
2674 u8 adc_byte(u8 d, u8 s)
2676 return adc_byte_asm(&M.x86.R_EFLG, d, s);
2679 u16 adc_word(u16 d, u16 s)
2681 return adc_word_asm(&M.x86.R_EFLG, d, s);
2684 u32 adc_long(u32 d, u32 s)
2686 return adc_long_asm(&M.x86.R_EFLG, d, s);
2689 u8 add_byte(u8 d, u8 s)
2691 return add_byte_asm(&M.x86.R_EFLG, d, s);
2694 u16 add_word(u16 d, u16 s)
2696 return add_word_asm(&M.x86.R_EFLG, d, s);
2699 u32 add_long(u32 d, u32 s)
2701 return add_long_asm(&M.x86.R_EFLG, d, s);
2704 u8 and_byte(u8 d, u8 s)
2706 return and_byte_asm(&M.x86.R_EFLG, d, s);
2709 u16 and_word(u16 d, u16 s)
2711 return and_word_asm(&M.x86.R_EFLG, d, s);
2714 u32 and_long(u32 d, u32 s)
2716 return and_long_asm(&M.x86.R_EFLG, d, s);
2719 u8 cmp_byte(u8 d, u8 s)
2721 return cmp_byte_asm(&M.x86.R_EFLG, d, s);
2724 u16 cmp_word(u16 d, u16 s)
2726 return cmp_word_asm(&M.x86.R_EFLG, d, s);
2729 u32 cmp_long(u32 d, u32 s)
2731 return cmp_long_asm(&M.x86.R_EFLG, d, s);
2736 return daa_byte_asm(&M.x86.R_EFLG, d);
2741 return das_byte_asm(&M.x86.R_EFLG, d);
2746 return dec_byte_asm(&M.x86.R_EFLG, d);
2751 return dec_word_asm(&M.x86.R_EFLG, d);
2756 return dec_long_asm(&M.x86.R_EFLG, d);
2761 return inc_byte_asm(&M.x86.R_EFLG, d);
2766 return inc_word_asm(&M.x86.R_EFLG, d);
2771 return inc_long_asm(&M.x86.R_EFLG, d);
2774 u8 or_byte(u8 d, u8 s)
2776 return or_byte_asm(&M.x86.R_EFLG, d, s);
2779 u16 or_word(u16 d, u16 s)
2781 return or_word_asm(&M.x86.R_EFLG, d, s);
2784 u32 or_long(u32 d, u32 s)
2786 return or_long_asm(&M.x86.R_EFLG, d, s);
2791 return neg_byte_asm(&M.x86.R_EFLG, s);
2796 return neg_word_asm(&M.x86.R_EFLG, s);
2801 return neg_long_asm(&M.x86.R_EFLG, s);
2806 return not_byte_asm(&M.x86.R_EFLG, s);
2811 return not_word_asm(&M.x86.R_EFLG, s);
2816 return not_long_asm(&M.x86.R_EFLG, s);
2819 u8 rcl_byte(u8 d, u8 s)
2821 return rcl_byte_asm(&M.x86.R_EFLG, d, s);
2824 u16 rcl_word(u16 d, u8 s)
2826 return rcl_word_asm(&M.x86.R_EFLG, d, s);
2829 u32 rcl_long(u32 d, u8 s)
2831 return rcl_long_asm(&M.x86.R_EFLG, d, s);
2834 u8 rcr_byte(u8 d, u8 s)
2836 return rcr_byte_asm(&M.x86.R_EFLG, d, s);
2839 u16 rcr_word(u16 d, u8 s)
2841 return rcr_word_asm(&M.x86.R_EFLG, d, s);
2844 u32 rcr_long(u32 d, u8 s)
2846 return rcr_long_asm(&M.x86.R_EFLG, d, s);
2849 u8 rol_byte(u8 d, u8 s)
2851 return rol_byte_asm(&M.x86.R_EFLG, d, s);
2854 u16 rol_word(u16 d, u8 s)
2856 return rol_word_asm(&M.x86.R_EFLG, d, s);
2859 u32 rol_long(u32 d, u8 s)
2861 return rol_long_asm(&M.x86.R_EFLG, d, s);
2864 u8 ror_byte(u8 d, u8 s)
2866 return ror_byte_asm(&M.x86.R_EFLG, d, s);
2869 u16 ror_word(u16 d, u8 s)
2871 return ror_word_asm(&M.x86.R_EFLG, d, s);
2874 u32 ror_long(u32 d, u8 s)
2876 return ror_long_asm(&M.x86.R_EFLG, d, s);
2879 u8 shl_byte(u8 d, u8 s)
2881 return shl_byte_asm(&M.x86.R_EFLG, d, s);
2884 u16 shl_word(u16 d, u8 s)
2886 return shl_word_asm(&M.x86.R_EFLG, d, s);
2889 u32 shl_long(u32 d, u8 s)
2891 return shl_long_asm(&M.x86.R_EFLG, d, s);
2894 u8 shr_byte(u8 d, u8 s)
2896 return shr_byte_asm(&M.x86.R_EFLG, d, s);
2899 u16 shr_word(u16 d, u8 s)
2901 return shr_word_asm(&M.x86.R_EFLG, d, s);
2904 u32 shr_long(u32 d, u8 s)
2906 return shr_long_asm(&M.x86.R_EFLG, d, s);
2909 u8 sar_byte(u8 d, u8 s)
2911 return sar_byte_asm(&M.x86.R_EFLG, d, s);
2914 u16 sar_word(u16 d, u8 s)
2916 return sar_word_asm(&M.x86.R_EFLG, d, s);
2919 u32 sar_long(u32 d, u8 s)
2921 return sar_long_asm(&M.x86.R_EFLG, d, s);
2924 u16 shld_word(u16 d, u16 fill, u8 s)
2926 return shld_word_asm(&M.x86.R_EFLG, d, fill, s);
2929 u32 shld_long(u32 d, u32 fill, u8 s)
2931 return shld_long_asm(&M.x86.R_EFLG, d, fill, s);
2934 u16 shrd_word(u16 d, u16 fill, u8 s)
2936 return shrd_word_asm(&M.x86.R_EFLG, d, fill, s);
2939 u32 shrd_long(u32 d, u32 fill, u8 s)
2941 return shrd_long_asm(&M.x86.R_EFLG, d, fill, s);
2944 u8 sbb_byte(u8 d, u8 s)
2946 return sbb_byte_asm(&M.x86.R_EFLG, d, s);
2949 u16 sbb_word(u16 d, u16 s)
2951 return sbb_word_asm(&M.x86.R_EFLG, d, s);
2954 u32 sbb_long(u32 d, u32 s)
2956 return sbb_long_asm(&M.x86.R_EFLG, d, s);
2959 u8 sub_byte(u8 d, u8 s)
2961 return sub_byte_asm(&M.x86.R_EFLG, d, s);
2964 u16 sub_word(u16 d, u16 s)
2966 return sub_word_asm(&M.x86.R_EFLG, d, s);
2969 u32 sub_long(u32 d, u32 s)
2971 return sub_long_asm(&M.x86.R_EFLG, d, s);
2974 void test_byte(u8 d, u8 s)
2976 test_byte_asm(&M.x86.R_EFLG, d, s);
2979 void test_word(u16 d, u16 s)
2981 test_word_asm(&M.x86.R_EFLG, d, s);
2984 void test_long(u32 d, u32 s)
2986 test_long_asm(&M.x86.R_EFLG, d, s);
2989 u8 xor_byte(u8 d, u8 s)
2991 return xor_byte_asm(&M.x86.R_EFLG, d, s);
2994 u16 xor_word(u16 d, u16 s)
2996 return xor_word_asm(&M.x86.R_EFLG, d, s);
2999 u32 xor_long(u32 d, u32 s)
3001 return xor_long_asm(&M.x86.R_EFLG, d, s);
3004 void imul_byte(u8 s)
3006 imul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s);
3009 void imul_word(u16 s)
3011 imul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s);
3014 void imul_long(u32 s)
3016 imul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
3019 void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
3021 imul_long_asm(&M.x86.R_EFLG, res_lo, res_hi, d, s);
3026 mul_byte_asm(&M.x86.R_EFLG, &M.x86.R_AX, M.x86.R_AL, s);
3029 void mul_word(u16 s)
3031 mul_word_asm(&M.x86.R_EFLG, &M.x86.R_AX, &M.x86.R_DX, M.x86.R_AX, s);
3034 void mul_long(u32 s)
3036 mul_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
3039 void idiv_byte(u8 s)
3041 idiv_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s);
3044 void idiv_word(u16 s)
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);
3049 void idiv_long(u32 s)
3051 idiv_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX,
3057 div_byte_asm(&M.x86.R_EFLG, &M.x86.R_AL, &M.x86.R_AH, M.x86.R_AX, s);
3060 void div_word(u16 s)
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);
3065 void div_long(u32 s)
3067 div_long_asm(&M.x86.R_EFLG, &M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, M.x86.R_EDX,