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 ****************************************************************************/
102 #define PRIM_OPS_NO_REDEFINE_ASM
103 #include "x86emu/x86emui.h"
105 #if defined(__GNUC__)
106 #if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__)
107 #include "x86emu/prim_x86_gcc.h"
111 /*------------------------- Global Variables ------------------------------*/
113 static u32 x86emu_parity_tab
[8] = {
124 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
125 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
127 /*----------------------------- Implementation ----------------------------*/
129 /****************************************************************************
131 Implements the AAA instruction and side effects.
132 ****************************************************************************/
138 if ((d
& 0xf) > 0x9 || ACCESS_FLAG(F_AF
)) {
148 res
= (u16
) (d
& 0xFF0F);
150 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
151 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
155 /****************************************************************************
157 Implements the AAA instruction and side effects.
158 ****************************************************************************/
164 if ((d
& 0xf) > 0x9 || ACCESS_FLAG(F_AF
)) {
174 res
= (u16
) (d
& 0xFF0F);
176 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
177 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
181 /****************************************************************************
183 Implements the AAD instruction and side effects.
184 ****************************************************************************/
191 hb
= (u8
) ((d
>> 8) & 0xff);
192 lb
= (u8
) ((d
& 0xff));
193 l
= (u16
) ((lb
+ 10 * hb
) & 0xFF);
198 CONDITIONAL_SET_FLAG(l
& 0x80, F_SF
);
199 CONDITIONAL_SET_FLAG(l
== 0, F_ZF
);
200 CONDITIONAL_SET_FLAG(PARITY(l
& 0xff), F_PF
);
204 /****************************************************************************
206 Implements the AAM instruction and side effects.
207 ****************************************************************************/
220 CONDITIONAL_SET_FLAG(l
& 0x80, F_SF
);
221 CONDITIONAL_SET_FLAG(l
== 0, F_ZF
);
222 CONDITIONAL_SET_FLAG(PARITY(l
& 0xff), F_PF
);
226 /****************************************************************************
228 Implements the ADC instruction and side effects.
229 ****************************************************************************/
233 register u32 res
; /* all operands in native machine order */
236 if (ACCESS_FLAG(F_CF
))
241 CONDITIONAL_SET_FLAG(res
& 0x100, F_CF
);
242 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
243 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
244 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
246 /* calculate the carry chain SEE NOTE AT TOP. */
247 cc
= (s
& d
) | ((~res
) & (s
| d
));
248 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
249 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
253 /****************************************************************************
255 Implements the ADC instruction and side effects.
256 ****************************************************************************/
258 adc_word(u16 d
, u16 s
)
260 register u32 res
; /* all operands in native machine order */
263 if (ACCESS_FLAG(F_CF
))
268 CONDITIONAL_SET_FLAG(res
& 0x10000, F_CF
);
269 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
270 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
271 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
273 /* calculate the carry chain SEE NOTE AT TOP. */
274 cc
= (s
& d
) | ((~res
) & (s
| d
));
275 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
276 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
280 /****************************************************************************
282 Implements the ADC instruction and side effects.
283 ****************************************************************************/
285 adc_long(u32 d
, u32 s
)
287 register u32 lo
; /* all operands in native machine order */
292 if (ACCESS_FLAG(F_CF
)) {
293 lo
= 1 + (d
& 0xFFFF) + (s
& 0xFFFF);
297 lo
= (d
& 0xFFFF) + (s
& 0xFFFF);
300 hi
= (lo
>> 16) + (d
>> 16) + (s
>> 16);
302 CONDITIONAL_SET_FLAG(hi
& 0x10000, F_CF
);
303 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
304 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
305 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
307 /* calculate the carry chain SEE NOTE AT TOP. */
308 cc
= (s
& d
) | ((~res
) & (s
| d
));
309 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
310 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
314 /****************************************************************************
316 Implements the ADD instruction and side effects.
317 ****************************************************************************/
321 register u32 res
; /* all operands in native machine order */
325 CONDITIONAL_SET_FLAG(res
& 0x100, F_CF
);
326 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
327 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
328 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
330 /* calculate the carry chain SEE NOTE AT TOP. */
331 cc
= (s
& d
) | ((~res
) & (s
| d
));
332 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
333 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
337 /****************************************************************************
339 Implements the ADD instruction and side effects.
340 ****************************************************************************/
342 add_word(u16 d
, u16 s
)
344 register u32 res
; /* all operands in native machine order */
348 CONDITIONAL_SET_FLAG(res
& 0x10000, F_CF
);
349 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
350 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
351 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
353 /* calculate the carry chain SEE NOTE AT TOP. */
354 cc
= (s
& d
) | ((~res
) & (s
| d
));
355 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
356 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
360 /****************************************************************************
362 Implements the ADD instruction and side effects.
363 ****************************************************************************/
365 add_long(u32 d
, u32 s
)
367 register u32 lo
; /* all operands in native machine order */
372 lo
= (d
& 0xFFFF) + (s
& 0xFFFF);
374 hi
= (lo
>> 16) + (d
>> 16) + (s
>> 16);
376 CONDITIONAL_SET_FLAG(hi
& 0x10000, F_CF
);
377 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
378 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
379 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
381 /* calculate the carry chain SEE NOTE AT TOP. */
382 cc
= (s
& d
) | ((~res
) & (s
| d
));
383 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
384 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
389 /****************************************************************************
391 Implements the AND instruction and side effects.
392 ****************************************************************************/
396 register u8 res
; /* all operands in native machine order */
404 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
405 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
406 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
410 /****************************************************************************
412 Implements the AND instruction and side effects.
413 ****************************************************************************/
415 and_word(u16 d
, u16 s
)
417 register u16 res
; /* all operands in native machine order */
425 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
426 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
427 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
431 /****************************************************************************
433 Implements the AND instruction and side effects.
434 ****************************************************************************/
436 and_long(u32 d
, u32 s
)
438 register u32 res
; /* all operands in native machine order */
446 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
447 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
448 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
452 /****************************************************************************
454 Implements the CMP instruction and side effects.
455 ****************************************************************************/
459 register u32 res
; /* all operands in native machine order */
464 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
465 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
466 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
468 /* calculate the borrow chain. See note at top */
469 bc
= (res
& (~d
| s
)) | (~d
& s
);
470 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
471 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
472 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
476 /****************************************************************************
478 Implements the CMP instruction and side effects.
479 ****************************************************************************/
481 cmp_word(u16 d
, u16 s
)
483 register u32 res
; /* all operands in native machine order */
487 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
488 CONDITIONAL_SET_FLAG((res
& 0xffff) == 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
& 0x8000, F_CF
);
494 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
495 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
499 /****************************************************************************
501 Implements the CMP instruction and side effects.
502 ****************************************************************************/
504 cmp_long(u32 d
, u32 s
)
506 register u32 res
; /* all operands in native machine order */
510 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
511 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
512 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
514 /* calculate the borrow chain. See note at top */
515 bc
= (res
& (~d
| s
)) | (~d
& s
);
516 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
517 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
518 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
522 /****************************************************************************
524 Implements the DAA instruction and side effects.
525 ****************************************************************************/
531 if ((d
& 0xf) > 9 || ACCESS_FLAG(F_AF
)) {
535 if (res
> 0x9F || ACCESS_FLAG(F_CF
)) {
539 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
540 CONDITIONAL_SET_FLAG((res
& 0xFF) == 0, F_ZF
);
541 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
545 /****************************************************************************
547 Implements the DAS instruction and side effects.
548 ****************************************************************************/
552 if ((d
& 0xf) > 9 || ACCESS_FLAG(F_AF
)) {
556 if (d
> 0x9F || ACCESS_FLAG(F_CF
)) {
560 CONDITIONAL_SET_FLAG(d
& 0x80, F_SF
);
561 CONDITIONAL_SET_FLAG(d
== 0, F_ZF
);
562 CONDITIONAL_SET_FLAG(PARITY(d
& 0xff), F_PF
);
566 /****************************************************************************
568 Implements the DEC instruction and side effects.
569 ****************************************************************************/
573 register u32 res
; /* all operands in native machine order */
577 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
578 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
579 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
581 /* calculate the borrow chain. See note at top */
582 /* based on sub_byte, uses s==1. */
583 bc
= (res
& (~d
| 1)) | (~d
& 1);
584 /* carry flag unchanged */
585 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
586 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
590 /****************************************************************************
592 Implements the DEC instruction and side effects.
593 ****************************************************************************/
597 register u32 res
; /* all operands in native machine order */
601 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
602 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
603 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
605 /* calculate the borrow chain. See note at top */
606 /* based on the sub_byte routine, with s==1 */
607 bc
= (res
& (~d
| 1)) | (~d
& 1);
608 /* carry flag unchanged */
609 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
610 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
614 /****************************************************************************
616 Implements the DEC instruction and side effects.
617 ****************************************************************************/
621 register u32 res
; /* all operands in native machine order */
626 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
627 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
628 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
630 /* calculate the borrow chain. See note at top */
631 bc
= (res
& (~d
| 1)) | (~d
& 1);
632 /* carry flag unchanged */
633 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
634 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
638 /****************************************************************************
640 Implements the INC instruction and side effects.
641 ****************************************************************************/
645 register u32 res
; /* all operands in native machine order */
649 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
650 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
651 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
653 /* calculate the carry chain SEE NOTE AT TOP. */
654 cc
= ((1 & d
) | (~res
)) & (1 | d
);
655 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
656 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
660 /****************************************************************************
662 Implements the INC instruction and side effects.
663 ****************************************************************************/
667 register u32 res
; /* all operands in native machine order */
671 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
672 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
673 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
675 /* calculate the carry chain SEE NOTE AT TOP. */
676 cc
= (1 & d
) | ((~res
) & (1 | d
));
677 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
678 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
682 /****************************************************************************
684 Implements the INC instruction and side effects.
685 ****************************************************************************/
689 register u32 res
; /* all operands in native machine order */
693 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
694 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
695 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
697 /* calculate the carry chain SEE NOTE AT TOP. */
698 cc
= (1 & d
) | ((~res
) & (1 | d
));
699 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
700 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
704 /****************************************************************************
706 Implements the OR instruction and side effects.
707 ****************************************************************************/
711 register u8 res
; /* all operands in native machine order */
717 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
718 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
719 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
723 /****************************************************************************
725 Implements the OR instruction and side effects.
726 ****************************************************************************/
728 or_word(u16 d
, u16 s
)
730 register u16 res
; /* all operands in native machine order */
733 /* set the carry flag to be bit 8 */
737 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
738 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
739 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
743 /****************************************************************************
745 Implements the OR instruction and side effects.
746 ****************************************************************************/
748 or_long(u32 d
, u32 s
)
750 register u32 res
; /* all operands in native machine order */
754 /* set the carry flag to be bit 8 */
758 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
759 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
760 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
764 /****************************************************************************
766 Implements the OR instruction and side effects.
767 ****************************************************************************/
774 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
776 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
777 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
778 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
779 /* calculate the borrow chain --- modified such that d=0.
780 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
781 (the one used for sub) and simplifying, since ~d=0xff...,
782 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
783 ~d&s == s. So the simplified result is: */
785 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
786 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
790 /****************************************************************************
792 Implements the OR instruction and side effects.
793 ****************************************************************************/
800 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
802 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
803 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
804 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
806 /* calculate the borrow chain --- modified such that d=0.
807 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
808 (the one used for sub) and simplifying, since ~d=0xff...,
809 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
810 ~d&s == s. So the simplified result is: */
812 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
813 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
817 /****************************************************************************
819 Implements the OR instruction and side effects.
820 ****************************************************************************/
827 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
829 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
830 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
831 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
833 /* calculate the borrow chain --- modified such that d=0.
834 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
835 (the one used for sub) and simplifying, since ~d=0xff...,
836 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
837 ~d&s == s. So the simplified result is: */
839 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
840 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
844 /****************************************************************************
846 Implements the NOT instruction and side effects.
847 ****************************************************************************/
854 /****************************************************************************
856 Implements the NOT instruction and side effects.
857 ****************************************************************************/
864 /****************************************************************************
866 Implements the NOT instruction and side effects.
867 ****************************************************************************/
874 /****************************************************************************
876 Implements the RCL instruction and side effects.
877 ****************************************************************************/
881 register unsigned int res
, cnt
, mask
, cf
;
883 /* s is the rotate distance. It varies from 0 - 8. */
886 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
888 want to rotate through the carry by "s" bits. We could
889 loop, but that's inefficient. So the width is 9,
890 and we split into three parts:
892 The new carry flag (was B_n)
893 the stuff in B_n-1 .. B_0
894 the stuff in B_7 .. B_n+1
896 The new rotate is done mod 9, and given this,
897 for a rotation of n bits (mod 9) the new carry flag is
898 then located n bits from the MSB. The low part is
899 then shifted up cnt bits, and the high part is or'd
900 in. Using CAPS for new values, and lowercase for the
901 original values, this can be expressed as:
905 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
907 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
910 if ((cnt
= s
% 9) != 0) {
911 /* extract the new CARRY FLAG. */
913 cf
= (d
>> (8 - cnt
)) & 0x1;
915 /* get the low stuff which rotated
916 into the range B_7 .. B_cnt */
917 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
918 /* note that the right hand side done by the mask */
919 res
= (d
<< cnt
) & 0xff;
921 /* now the high stuff which rotated around
922 into the positions B_cnt-2 .. B_0 */
923 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
924 /* shift it downward, 7-(n-2) = 9-n positions.
925 and mask off the result before or'ing in.
927 mask
= (1 << (cnt
- 1)) - 1;
928 res
|= (d
>> (9 - cnt
)) & mask
;
930 /* if the carry flag was set, or it in. */
931 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
933 res
|= 1 << (cnt
- 1);
935 /* set the new carry flag, based on the variable "cf" */
936 CONDITIONAL_SET_FLAG(cf
, F_CF
);
937 /* OVERFLOW is set *IFF* cnt==1, then it is the
938 xor of CF and the most significant bit. Blecck. */
939 /* parenthesized this expression since it appears to
940 be causing OF to be misset */
941 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 6) & 0x2)), F_OF
);
947 /****************************************************************************
949 Implements the RCL instruction and side effects.
950 ****************************************************************************/
952 rcl_word(u16 d
, u8 s
)
954 register unsigned int res
, cnt
, mask
, cf
;
957 if ((cnt
= s
% 17) != 0) {
958 cf
= (d
>> (16 - cnt
)) & 0x1;
959 res
= (d
<< cnt
) & 0xffff;
960 mask
= (1 << (cnt
- 1)) - 1;
961 res
|= (d
>> (17 - cnt
)) & mask
;
962 if (ACCESS_FLAG(F_CF
)) {
963 res
|= 1 << (cnt
- 1);
965 CONDITIONAL_SET_FLAG(cf
, F_CF
);
966 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 14) & 0x2)), F_OF
);
971 /****************************************************************************
973 Implements the RCL instruction and side effects.
974 ****************************************************************************/
976 rcl_long(u32 d
, u8 s
)
978 register u32 res
, cnt
, mask
, cf
;
981 if ((cnt
= s
% 33) != 0) {
982 cf
= (d
>> (32 - cnt
)) & 0x1;
983 res
= (d
<< cnt
) & 0xffffffff;
984 mask
= (1 << (cnt
- 1)) - 1;
985 res
|= (d
>> (33 - cnt
)) & mask
;
986 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
987 res
|= 1 << (cnt
- 1);
989 CONDITIONAL_SET_FLAG(cf
, F_CF
);
990 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 30) & 0x2)), F_OF
);
995 /****************************************************************************
997 Implements the RCR instruction and side effects.
998 ****************************************************************************/
1000 rcr_byte(u8 d
, u8 s
)
1003 u32 mask
, cf
, ocf
= 0;
1005 /* rotate right through carry */
1007 s is the rotate distance. It varies from 0 - 8.
1008 d is the byte object rotated.
1012 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
1014 The new rotate is done mod 9, and given this,
1015 for a rotation of n bits (mod 9) the new carry flag is
1016 then located n bits from the LSB. The low part is
1017 then shifted up cnt bits, and the high part is or'd
1018 in. Using CAPS for new values, and lowercase for the
1019 original values, this can be expressed as:
1023 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1025 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
1028 if ((cnt
= s
% 9) != 0) {
1029 /* extract the new CARRY FLAG. */
1033 /* note hackery here. Access_flag(..) evaluates to either
1035 non-zero if flag is set.
1036 doing access_flag(..) != 0 casts that into either
1037 0..1 in any representation of the flags register
1038 (i.e. packed bit array or unpacked.)
1040 ocf
= ACCESS_FLAG(F_CF
) != 0;
1043 cf
= (d
>> (cnt
- 1)) & 0x1;
1045 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
1046 /* note that the right hand side done by the mask
1047 This is effectively done by shifting the
1048 object to the right. The result must be masked,
1049 in case the object came in and was treated
1050 as a negative number. Needed??? */
1052 mask
= (1 << (8 - cnt
)) - 1;
1053 res
= (d
>> cnt
) & mask
;
1055 /* now the high stuff which rotated around
1056 into the positions B_cnt-2 .. B_0 */
1057 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
1058 /* shift it downward, 7-(n-2) = 9-n positions.
1059 and mask off the result before or'ing in.
1061 res
|= (d
<< (9 - cnt
));
1063 /* if the carry flag was set, or it in. */
1064 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
1066 res
|= 1 << (8 - cnt
);
1068 /* set the new carry flag, based on the variable "cf" */
1069 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1070 /* OVERFLOW is set *IFF* cnt==1, then it is the
1071 xor of CF and the most significant bit. Blecck. */
1072 /* parenthesized... */
1074 CONDITIONAL_SET_FLAG(XOR2(ocf
+ ((d
>> 6) & 0x2)), F_OF
);
1080 /****************************************************************************
1082 Implements the RCR instruction and side effects.
1083 ****************************************************************************/
1085 rcr_word(u16 d
, u8 s
)
1088 u32 mask
, cf
, ocf
= 0;
1090 /* rotate right through carry */
1092 if ((cnt
= s
% 17) != 0) {
1095 ocf
= ACCESS_FLAG(F_CF
) != 0;
1098 cf
= (d
>> (cnt
- 1)) & 0x1;
1099 mask
= (1 << (16 - cnt
)) - 1;
1100 res
= (d
>> cnt
) & mask
;
1101 res
|= (d
<< (17 - cnt
));
1102 if (ACCESS_FLAG(F_CF
)) {
1103 res
|= 1 << (16 - cnt
);
1105 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1107 CONDITIONAL_SET_FLAG(XOR2(ocf
+ ((d
>> 14) & 0x2)), F_OF
);
1113 /****************************************************************************
1115 Implements the RCR instruction and side effects.
1116 ****************************************************************************/
1118 rcr_long(u32 d
, u8 s
)
1121 u32 mask
, cf
, ocf
= 0;
1123 /* rotate right through carry */
1125 if ((cnt
= s
% 33) != 0) {
1128 ocf
= ACCESS_FLAG(F_CF
) != 0;
1131 cf
= (d
>> (cnt
- 1)) & 0x1;
1132 mask
= (1 << (32 - cnt
)) - 1;
1133 res
= (d
>> cnt
) & mask
;
1135 res
|= (d
<< (33 - cnt
));
1136 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
1137 res
|= 1 << (32 - cnt
);
1139 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1141 CONDITIONAL_SET_FLAG(XOR2(ocf
+ ((d
>> 30) & 0x2)), F_OF
);
1147 /****************************************************************************
1149 Implements the ROL instruction and side effects.
1150 ****************************************************************************/
1152 rol_byte(u8 d
, u8 s
)
1154 register unsigned int res
, cnt
, mask
;
1158 s is the rotate distance. It varies from 0 - 8.
1159 d is the byte object rotated.
1165 The new rotate is done mod 8.
1166 Much simpler than the "rcl" or "rcr" operations.
1169 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1170 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1173 if ((cnt
= s
% 8) != 0) {
1174 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1177 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1178 mask
= (1 << cnt
) - 1;
1179 res
|= (d
>> (8 - cnt
)) & mask
;
1181 /* set the new carry flag, Note that it is the low order
1182 bit of the result!!! */
1183 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1184 /* OVERFLOW is set *IFF* s==1, then it is the
1185 xor of CF and the most significant bit. Blecck. */
1186 CONDITIONAL_SET_FLAG(s
== 1 &&
1187 XOR2((res
& 0x1) + ((res
>> 6) & 0x2)), F_OF
);
1190 /* set the new carry flag, Note that it is the low order
1191 bit of the result!!! */
1192 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1197 /****************************************************************************
1199 Implements the ROL instruction and side effects.
1200 ****************************************************************************/
1202 rol_word(u16 d
, u8 s
)
1204 register unsigned int res
, cnt
, mask
;
1207 if ((cnt
= s
% 16) != 0) {
1209 mask
= (1 << cnt
) - 1;
1210 res
|= (d
>> (16 - cnt
)) & mask
;
1211 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1212 CONDITIONAL_SET_FLAG(s
== 1 &&
1213 XOR2((res
& 0x1) + ((res
>> 14) & 0x2)), F_OF
);
1216 /* set the new carry flag, Note that it is the low order
1217 bit of the result!!! */
1218 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1223 /****************************************************************************
1225 Implements the ROL instruction and side effects.
1226 ****************************************************************************/
1228 rol_long(u32 d
, u8 s
)
1230 register u32 res
, cnt
, mask
;
1233 if ((cnt
= s
% 32) != 0) {
1235 mask
= (1 << cnt
) - 1;
1236 res
|= (d
>> (32 - cnt
)) & mask
;
1237 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1238 CONDITIONAL_SET_FLAG(s
== 1 &&
1239 XOR2((res
& 0x1) + ((res
>> 30) & 0x2)), F_OF
);
1242 /* set the new carry flag, Note that it is the low order
1243 bit of the result!!! */
1244 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1249 /****************************************************************************
1251 Implements the ROR instruction and side effects.
1252 ****************************************************************************/
1254 ror_byte(u8 d
, u8 s
)
1256 register unsigned int res
, cnt
, mask
;
1260 s is the rotate distance. It varies from 0 - 8.
1261 d is the byte object rotated.
1267 The rotate is done mod 8.
1270 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1271 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1274 if ((cnt
= s
% 8) != 0) { /* not a typo, do nada if cnt==0 */
1275 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1276 res
= (d
<< (8 - cnt
));
1278 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1279 mask
= (1 << (8 - cnt
)) - 1;
1280 res
|= (d
>> (cnt
)) & mask
;
1282 /* set the new carry flag, Note that it is the low order
1283 bit of the result!!! */
1284 CONDITIONAL_SET_FLAG(res
& 0x80, F_CF
);
1285 /* OVERFLOW is set *IFF* s==1, then it is the
1286 xor of the two most significant bits. Blecck. */
1287 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 6), F_OF
);
1290 /* set the new carry flag, Note that it is the low order
1291 bit of the result!!! */
1292 CONDITIONAL_SET_FLAG(res
& 0x80, F_CF
);
1297 /****************************************************************************
1299 Implements the ROR instruction and side effects.
1300 ****************************************************************************/
1302 ror_word(u16 d
, u8 s
)
1304 register unsigned int res
, cnt
, mask
;
1307 if ((cnt
= s
% 16) != 0) {
1308 res
= (d
<< (16 - cnt
));
1309 mask
= (1 << (16 - cnt
)) - 1;
1310 res
|= (d
>> (cnt
)) & mask
;
1311 CONDITIONAL_SET_FLAG(res
& 0x8000, F_CF
);
1312 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 14), F_OF
);
1315 /* set the new carry flag, Note that it is the low order
1316 bit of the result!!! */
1317 CONDITIONAL_SET_FLAG(res
& 0x8000, F_CF
);
1322 /****************************************************************************
1324 Implements the ROR instruction and side effects.
1325 ****************************************************************************/
1327 ror_long(u32 d
, u8 s
)
1329 register u32 res
, cnt
, mask
;
1332 if ((cnt
= s
% 32) != 0) {
1333 res
= (d
<< (32 - cnt
));
1334 mask
= (1 << (32 - cnt
)) - 1;
1335 res
|= (d
>> (cnt
)) & mask
;
1336 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_CF
);
1337 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 30), F_OF
);
1340 /* set the new carry flag, Note that it is the low order
1341 bit of the result!!! */
1342 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_CF
);
1347 /****************************************************************************
1349 Implements the SHL instruction and side effects.
1350 ****************************************************************************/
1352 shl_byte(u8 d
, u8 s
)
1354 unsigned int cnt
, res
, cf
;
1359 /* last bit shifted out goes into carry flag */
1362 cf
= d
& (1 << (8 - cnt
));
1363 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1364 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1365 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1366 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1373 /* Needs simplification. */
1374 CONDITIONAL_SET_FLAG((((res
& 0x80) == 0x80) ^
1375 (ACCESS_FLAG(F_CF
) != 0)),
1376 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1385 CONDITIONAL_SET_FLAG((d
<< (s
- 1)) & 0x80, F_CF
);
1394 /****************************************************************************
1396 Implements the SHL instruction and side effects.
1397 ****************************************************************************/
1399 shl_word(u16 d
, u8 s
)
1401 unsigned int cnt
, res
, cf
;
1407 cf
= d
& (1 << (16 - cnt
));
1408 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1409 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1410 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1411 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1418 CONDITIONAL_SET_FLAG((((res
& 0x8000) == 0x8000) ^
1419 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1427 CONDITIONAL_SET_FLAG((d
<< (s
- 1)) & 0x8000, F_CF
);
1436 /****************************************************************************
1438 Implements the SHL instruction and side effects.
1439 ****************************************************************************/
1441 shl_long(u32 d
, u8 s
)
1443 unsigned int cnt
, res
, cf
;
1449 cf
= d
& (1 << (32 - cnt
));
1450 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1451 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1452 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1453 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1459 CONDITIONAL_SET_FLAG((((res
& 0x80000000) == 0x80000000) ^
1460 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1468 CONDITIONAL_SET_FLAG((d
<< (s
- 1)) & 0x80000000, F_CF
);
1477 /****************************************************************************
1479 Implements the SHR instruction and side effects.
1480 ****************************************************************************/
1482 shr_byte(u8 d
, u8 s
)
1484 unsigned int cnt
, res
, cf
;
1489 cf
= d
& (1 << (cnt
- 1));
1491 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1492 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1493 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1494 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1501 CONDITIONAL_SET_FLAG(XOR2(res
>> 6), F_OF
);
1509 CONDITIONAL_SET_FLAG((d
>> (s
- 1)) & 0x1, F_CF
);
1518 /****************************************************************************
1520 Implements the SHR instruction and side effects.
1521 ****************************************************************************/
1523 shr_word(u16 d
, u8 s
)
1525 unsigned int cnt
, res
, cf
;
1530 cf
= d
& (1 << (cnt
- 1));
1532 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1533 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1534 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1535 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1542 CONDITIONAL_SET_FLAG(XOR2(res
>> 14), F_OF
);
1559 /****************************************************************************
1561 Implements the SHR instruction and side effects.
1562 ****************************************************************************/
1564 shr_long(u32 d
, u8 s
)
1566 unsigned int cnt
, res
, cf
;
1571 cf
= d
& (1 << (cnt
- 1));
1573 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1574 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1575 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1576 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1582 CONDITIONAL_SET_FLAG(XOR2(res
>> 30), F_OF
);
1599 /****************************************************************************
1601 Implements the SAR instruction and side effects.
1602 ****************************************************************************/
1604 sar_byte(u8 d
, u8 s
)
1606 unsigned int cnt
, res
, cf
, mask
, sf
;
1611 if (cnt
> 0 && cnt
< 8) {
1612 mask
= (1 << (8 - cnt
)) - 1;
1613 cf
= d
& (1 << (cnt
- 1));
1614 res
= (d
>> cnt
) & mask
;
1615 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1619 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1620 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1621 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1623 else if (cnt
>= 8) {
1642 /****************************************************************************
1644 Implements the SAR instruction and side effects.
1645 ****************************************************************************/
1647 sar_word(u16 d
, u8 s
)
1649 unsigned int cnt
, res
, cf
, mask
, sf
;
1654 if (cnt
> 0 && cnt
< 16) {
1655 mask
= (1 << (16 - cnt
)) - 1;
1656 cf
= d
& (1 << (cnt
- 1));
1657 res
= (d
>> cnt
) & mask
;
1658 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1662 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1663 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1664 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1666 else if (cnt
>= 16) {
1685 /****************************************************************************
1687 Implements the SAR instruction and side effects.
1688 ****************************************************************************/
1690 sar_long(u32 d
, u8 s
)
1692 u32 cnt
, res
, cf
, mask
, sf
;
1694 sf
= d
& 0x80000000;
1697 if (cnt
> 0 && cnt
< 32) {
1698 mask
= (1 << (32 - cnt
)) - 1;
1699 cf
= d
& (1 << (cnt
- 1));
1700 res
= (d
>> cnt
) & mask
;
1701 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1705 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1706 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1707 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1709 else if (cnt
>= 32) {
1728 /****************************************************************************
1730 Implements the SHLD instruction and side effects.
1731 ****************************************************************************/
1733 shld_word(u16 d
, u16 fill
, u8 s
)
1735 unsigned int cnt
, res
, cf
;
1740 res
= (d
<< cnt
) | (fill
>> (16 - cnt
));
1741 cf
= d
& (1 << (16 - cnt
));
1742 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1743 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1744 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1745 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1751 CONDITIONAL_SET_FLAG((((res
& 0x8000) == 0x8000) ^
1752 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1760 CONDITIONAL_SET_FLAG((d
<< (s
- 1)) & 0x8000, F_CF
);
1769 /****************************************************************************
1771 Implements the SHLD instruction and side effects.
1772 ****************************************************************************/
1774 shld_long(u32 d
, u32 fill
, u8 s
)
1776 unsigned int cnt
, res
, cf
;
1781 res
= (d
<< cnt
) | (fill
>> (32 - cnt
));
1782 cf
= d
& (1 << (32 - cnt
));
1783 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1784 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1785 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1786 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1792 CONDITIONAL_SET_FLAG((((res
& 0x80000000) == 0x80000000) ^
1793 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1801 CONDITIONAL_SET_FLAG((d
<< (s
- 1)) & 0x80000000, F_CF
);
1810 /****************************************************************************
1812 Implements the SHRD instruction and side effects.
1813 ****************************************************************************/
1815 shrd_word(u16 d
, u16 fill
, u8 s
)
1817 unsigned int cnt
, res
, cf
;
1822 cf
= d
& (1 << (cnt
- 1));
1823 res
= (d
>> cnt
) | (fill
<< (16 - cnt
));
1824 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1825 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1826 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1827 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1834 CONDITIONAL_SET_FLAG(XOR2(res
>> 14), F_OF
);
1851 /****************************************************************************
1853 Implements the SHRD instruction and side effects.
1854 ****************************************************************************/
1856 shrd_long(u32 d
, u32 fill
, u8 s
)
1858 unsigned int cnt
, res
, cf
;
1863 cf
= d
& (1 << (cnt
- 1));
1864 res
= (d
>> cnt
) | (fill
<< (32 - cnt
));
1865 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1866 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1867 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1868 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1874 CONDITIONAL_SET_FLAG(XOR2(res
>> 30), F_OF
);
1891 /****************************************************************************
1893 Implements the SBB instruction and side effects.
1894 ****************************************************************************/
1896 sbb_byte(u8 d
, u8 s
)
1898 register u32 res
; /* all operands in native machine order */
1901 if (ACCESS_FLAG(F_CF
))
1905 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1906 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1907 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1909 /* calculate the borrow chain. See note at top */
1910 bc
= (res
& (~d
| s
)) | (~d
& s
);
1911 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
1912 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
1913 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1917 /****************************************************************************
1919 Implements the SBB instruction and side effects.
1920 ****************************************************************************/
1922 sbb_word(u16 d
, u16 s
)
1924 register u32 res
; /* all operands in native machine order */
1927 if (ACCESS_FLAG(F_CF
))
1931 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1932 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1933 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1935 /* calculate the borrow chain. See note at top */
1936 bc
= (res
& (~d
| s
)) | (~d
& s
);
1937 CONDITIONAL_SET_FLAG(bc
& 0x8000, F_CF
);
1938 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
1939 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1943 /****************************************************************************
1945 Implements the SBB instruction and side effects.
1946 ****************************************************************************/
1948 sbb_long(u32 d
, u32 s
)
1950 register u32 res
; /* all operands in native machine order */
1953 if (ACCESS_FLAG(F_CF
))
1957 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1958 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1959 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1961 /* calculate the borrow chain. See note at top */
1962 bc
= (res
& (~d
| s
)) | (~d
& s
);
1963 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
1964 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
1965 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1969 /****************************************************************************
1971 Implements the SUB instruction and side effects.
1972 ****************************************************************************/
1974 sub_byte(u8 d
, u8 s
)
1976 register u32 res
; /* all operands in native machine order */
1980 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1981 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1982 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1984 /* calculate the borrow chain. See note at top */
1985 bc
= (res
& (~d
| s
)) | (~d
& s
);
1986 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
1987 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
1988 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1992 /****************************************************************************
1994 Implements the SUB instruction and side effects.
1995 ****************************************************************************/
1997 sub_word(u16 d
, u16 s
)
1999 register u32 res
; /* all operands in native machine order */
2003 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
2004 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
2005 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2007 /* calculate the borrow chain. See note at top */
2008 bc
= (res
& (~d
| s
)) | (~d
& s
);
2009 CONDITIONAL_SET_FLAG(bc
& 0x8000, F_CF
);
2010 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
2011 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
2015 /****************************************************************************
2017 Implements the SUB instruction and side effects.
2018 ****************************************************************************/
2020 sub_long(u32 d
, u32 s
)
2022 register u32 res
; /* all operands in native machine order */
2026 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
2027 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
2028 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2030 /* calculate the borrow chain. See note at top */
2031 bc
= (res
& (~d
| s
)) | (~d
& s
);
2032 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
2033 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
2034 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
2038 /****************************************************************************
2040 Implements the TEST instruction and side effects.
2041 ****************************************************************************/
2043 test_byte(u8 d
, u8 s
)
2045 register u32 res
; /* all operands in native machine order */
2050 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
2051 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2052 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2053 /* AF == dont care */
2057 /****************************************************************************
2059 Implements the TEST instruction and side effects.
2060 ****************************************************************************/
2062 test_word(u16 d
, u16 s
)
2064 register u32 res
; /* all operands in native machine order */
2069 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
2070 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2071 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2072 /* AF == dont care */
2076 /****************************************************************************
2078 Implements the TEST instruction and side effects.
2079 ****************************************************************************/
2081 test_long(u32 d
, u32 s
)
2083 register u32 res
; /* all operands in native machine order */
2088 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
2089 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2090 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2091 /* AF == dont care */
2095 /****************************************************************************
2097 Implements the XOR instruction and side effects.
2098 ****************************************************************************/
2100 xor_byte(u8 d
, u8 s
)
2102 register u8 res
; /* all operands in native machine order */
2106 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
2107 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2108 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
2114 /****************************************************************************
2116 Implements the XOR instruction and side effects.
2117 ****************************************************************************/
2119 xor_word(u16 d
, u16 s
)
2121 register u16 res
; /* all operands in native machine order */
2125 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
2126 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2127 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2133 /****************************************************************************
2135 Implements the XOR instruction and side effects.
2136 ****************************************************************************/
2138 xor_long(u32 d
, u32 s
)
2140 register u32 res
; /* all operands in native machine order */
2144 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
2145 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2146 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2152 /****************************************************************************
2154 Implements the IMUL instruction and side effects.
2155 ****************************************************************************/
2159 s16 res
= (s16
) ((s8
) M
.x86
.R_AL
* (s8
) s
);
2162 if (((M
.x86
.R_AL
& 0x80) == 0 && M
.x86
.R_AH
== 0x00) ||
2163 ((M
.x86
.R_AL
& 0x80) != 0 && M
.x86
.R_AH
== 0xFF)) {
2173 /****************************************************************************
2175 Implements the IMUL instruction and side effects.
2176 ****************************************************************************/
2180 s32 res
= (s16
) M
.x86
.R_AX
* (s16
) s
;
2182 M
.x86
.R_AX
= (u16
) res
;
2183 M
.x86
.R_DX
= (u16
) (res
>> 16);
2184 if (((M
.x86
.R_AX
& 0x8000) == 0 && M
.x86
.R_DX
== 0x00) ||
2185 ((M
.x86
.R_AX
& 0x8000) != 0 && M
.x86
.R_DX
== 0xFF)) {
2195 /****************************************************************************
2197 Implements the IMUL instruction and side effects.
2198 ****************************************************************************/
2200 imul_long_direct(u32
* res_lo
, u32
* res_hi
, u32 d
, u32 s
)
2202 #ifdef __HAS_LONG_LONG__
2203 s64 res
= (s64
) (s32
) d
* (s32
) s
;
2205 *res_lo
= (u32
) res
;
2206 *res_hi
= (u32
) (res
>> 32);
2208 u32 d_lo
, d_hi
, d_sign
;
2209 u32 s_lo
, s_hi
, s_sign
;
2210 u32 rlo_lo
, rlo_hi
, rhi_lo
;
2212 if ((d_sign
= d
& 0x80000000) != 0)
2216 if ((s_sign
= s
& 0x80000000) != 0)
2220 rlo_lo
= d_lo
* s_lo
;
2221 rlo_hi
= (d_hi
* s_lo
+ d_lo
* s_hi
) + (rlo_lo
>> 16);
2222 rhi_lo
= d_hi
* s_hi
+ (rlo_hi
>> 16);
2223 *res_lo
= (rlo_hi
<< 16) | (rlo_lo
& 0xFFFF);
2225 if (d_sign
!= s_sign
) {
2227 s
= (((d
& 0xFFFF) + 1) >> 16) + (d
>> 16);
2228 *res_lo
= ~*res_lo
+ 1;
2229 *res_hi
= ~*res_hi
+ (s
>> 16);
2234 /****************************************************************************
2236 Implements the IMUL instruction and side effects.
2237 ****************************************************************************/
2241 imul_long_direct(&M
.x86
.R_EAX
, &M
.x86
.R_EDX
, M
.x86
.R_EAX
, s
);
2242 if (((M
.x86
.R_EAX
& 0x80000000) == 0 && M
.x86
.R_EDX
== 0x00) ||
2243 ((M
.x86
.R_EAX
& 0x80000000) != 0 && M
.x86
.R_EDX
== 0xFF)) {
2253 /****************************************************************************
2255 Implements the MUL instruction and side effects.
2256 ****************************************************************************/
2260 u16 res
= (u16
) (M
.x86
.R_AL
* s
);
2263 if (M
.x86
.R_AH
== 0) {
2273 /****************************************************************************
2275 Implements the MUL instruction and side effects.
2276 ****************************************************************************/
2280 u32 res
= M
.x86
.R_AX
* s
;
2282 M
.x86
.R_AX
= (u16
) res
;
2283 M
.x86
.R_DX
= (u16
) (res
>> 16);
2284 if (M
.x86
.R_DX
== 0) {
2294 /****************************************************************************
2296 Implements the MUL instruction and side effects.
2297 ****************************************************************************/
2301 #ifdef __HAS_LONG_LONG__
2302 u64 res
= (u64
) M
.x86
.R_EAX
* s
;
2304 M
.x86
.R_EAX
= (u32
) res
;
2305 M
.x86
.R_EDX
= (u32
) (res
>> 32);
2309 u32 rlo_lo
, rlo_hi
, rhi_lo
;
2316 rlo_lo
= a_lo
* s_lo
;
2317 rlo_hi
= (a_hi
* s_lo
+ a_lo
* s_hi
) + (rlo_lo
>> 16);
2318 rhi_lo
= a_hi
* s_hi
+ (rlo_hi
>> 16);
2319 M
.x86
.R_EAX
= (rlo_hi
<< 16) | (rlo_lo
& 0xFFFF);
2320 M
.x86
.R_EDX
= rhi_lo
;
2323 if (M
.x86
.R_EDX
== 0) {
2333 /****************************************************************************
2335 Implements the IDIV instruction and side effects.
2336 ****************************************************************************/
2342 dvd
= (s16
) M
.x86
.R_AX
;
2344 x86emu_intr_raise(0);
2349 if (abs(div
) > 0x7f) {
2350 x86emu_intr_raise(0);
2353 M
.x86
.R_AL
= (s8
) div
;
2354 M
.x86
.R_AH
= (s8
) mod
;
2357 /****************************************************************************
2359 Implements the IDIV instruction and side effects.
2360 ****************************************************************************/
2366 dvd
= (((s32
) M
.x86
.R_DX
) << 16) | M
.x86
.R_AX
;
2368 x86emu_intr_raise(0);
2371 div
= dvd
/ (s16
) s
;
2372 mod
= dvd
% (s16
) s
;
2373 if (abs(div
) > 0x7fff) {
2374 x86emu_intr_raise(0);
2379 CONDITIONAL_SET_FLAG(div
== 0, F_ZF
);
2380 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2382 M
.x86
.R_AX
= (u16
) div
;
2383 M
.x86
.R_DX
= (u16
) mod
;
2386 /****************************************************************************
2388 Implements the IDIV instruction and side effects.
2389 ****************************************************************************/
2393 #ifdef __HAS_LONG_LONG__
2396 dvd
= (((s64
) M
.x86
.R_EDX
) << 32) | M
.x86
.R_EAX
;
2398 x86emu_intr_raise(0);
2401 div
= dvd
/ (s32
) s
;
2402 mod
= dvd
% (s32
) s
;
2403 if (abs(div
) > 0x7fffffff) {
2404 x86emu_intr_raise(0);
2409 s32 h_dvd
= M
.x86
.R_EDX
;
2410 u32 l_dvd
= M
.x86
.R_EAX
;
2411 u32 abs_s
= s
& 0x7FFFFFFF;
2412 u32 abs_h_dvd
= h_dvd
& 0x7FFFFFFF;
2413 u32 h_s
= abs_s
>> 1;
2414 u32 l_s
= abs_s
<< 31;
2419 x86emu_intr_raise(0);
2424 carry
= (l_dvd
>= l_s
) ? 0 : 1;
2426 if (abs_h_dvd
< (h_s
+ carry
)) {
2428 l_s
= abs_s
<< (--counter
);
2432 abs_h_dvd
-= (h_s
+ carry
);
2433 l_dvd
= carry
? ((0xFFFFFFFF - l_s
) + l_dvd
+ 1)
2436 l_s
= abs_s
<< (--counter
);
2441 } while (counter
> -1);
2443 if (abs_h_dvd
|| (l_dvd
> abs_s
)) {
2444 x86emu_intr_raise(0);
2448 div
|= ((h_dvd
& 0x10000000) ^ (s
& 0x10000000));
2456 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2458 M
.x86
.R_EAX
= (u32
) div
;
2459 M
.x86
.R_EDX
= (u32
) mod
;
2462 /****************************************************************************
2464 Implements the DIV instruction and side effects.
2465 ****************************************************************************/
2473 x86emu_intr_raise(0);
2478 if (abs(div
) > 0xff) {
2479 x86emu_intr_raise(0);
2482 M
.x86
.R_AL
= (u8
) div
;
2483 M
.x86
.R_AH
= (u8
) mod
;
2486 /****************************************************************************
2488 Implements the DIV instruction and side effects.
2489 ****************************************************************************/
2495 dvd
= (((u32
) M
.x86
.R_DX
) << 16) | M
.x86
.R_AX
;
2497 x86emu_intr_raise(0);
2500 div
= dvd
/ (u16
) s
;
2501 mod
= dvd
% (u16
) s
;
2502 if (abs(div
) > 0xffff) {
2503 x86emu_intr_raise(0);
2508 CONDITIONAL_SET_FLAG(div
== 0, F_ZF
);
2509 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2511 M
.x86
.R_AX
= (u16
) div
;
2512 M
.x86
.R_DX
= (u16
) mod
;
2515 /****************************************************************************
2517 Implements the DIV instruction and side effects.
2518 ****************************************************************************/
2522 #ifdef __HAS_LONG_LONG__
2525 dvd
= (((u64
) M
.x86
.R_EDX
) << 32) | M
.x86
.R_EAX
;
2527 x86emu_intr_raise(0);
2530 div
= dvd
/ (u32
) s
;
2531 mod
= dvd
% (u32
) s
;
2532 if (abs(div
) > 0xffffffff) {
2533 x86emu_intr_raise(0);
2538 s32 h_dvd
= M
.x86
.R_EDX
;
2539 u32 l_dvd
= M
.x86
.R_EAX
;
2547 x86emu_intr_raise(0);
2552 carry
= (l_dvd
>= l_s
) ? 0 : 1;
2554 if (h_dvd
< (h_s
+ carry
)) {
2556 l_s
= s
<< (--counter
);
2560 h_dvd
-= (h_s
+ carry
);
2561 l_dvd
= carry
? ((0xFFFFFFFF - l_s
) + l_dvd
+ 1)
2564 l_s
= s
<< (--counter
);
2569 } while (counter
> -1);
2571 if (h_dvd
|| (l_dvd
> s
)) {
2572 x86emu_intr_raise(0);
2581 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2583 M
.x86
.R_EAX
= (u32
) div
;
2584 M
.x86
.R_EDX
= (u32
) mod
;
2587 /****************************************************************************
2589 Implements the IN string instruction and side effects.
2590 ****************************************************************************/
2596 if (ACCESS_FLAG(F_DF
)) {
2599 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2600 /* dont care whether REPE or REPNE */
2601 /* in until CX is ZERO. */
2602 u32 count
= ((M
.x86
.mode
& SYSMODE_PREFIX_DATA
) ?
2603 M
.x86
.R_ECX
: M
.x86
.R_CX
);
2607 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2608 (*sys_inb
) (M
.x86
.R_DX
));
2615 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2616 (*sys_inw
) (M
.x86
.R_DX
));
2622 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2623 (*sys_inl
) (M
.x86
.R_DX
));
2629 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2632 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2637 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2638 (*sys_inb
) (M
.x86
.R_DX
));
2641 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2642 (*sys_inw
) (M
.x86
.R_DX
));
2645 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2646 (*sys_inl
) (M
.x86
.R_DX
));
2653 /****************************************************************************
2655 Implements the OUT string instruction and side effects.
2656 ****************************************************************************/
2662 if (ACCESS_FLAG(F_DF
)) {
2665 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2666 /* dont care whether REPE or REPNE */
2667 /* out until CX is ZERO. */
2668 u32 count
= ((M
.x86
.mode
& SYSMODE_PREFIX_DATA
) ?
2669 M
.x86
.R_ECX
: M
.x86
.R_CX
);
2673 (*sys_outb
) (M
.x86
.R_DX
,
2674 fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2681 (*sys_outw
) (M
.x86
.R_DX
,
2682 fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2688 (*sys_outl
) (M
.x86
.R_DX
,
2689 fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2695 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2698 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2703 (*sys_outb
) (M
.x86
.R_DX
,
2704 fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2707 (*sys_outw
) (M
.x86
.R_DX
,
2708 fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2711 (*sys_outl
) (M
.x86
.R_DX
,
2712 fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2719 /****************************************************************************
2721 addr - Address to fetch word from
2724 Fetches a word from emulator memory using an absolute address.
2725 ****************************************************************************/
2727 mem_access_word(int addr
)
2729 DB(if (CHECK_MEM_ACCESS())
2730 x86emu_check_mem_access(addr
);)
2731 return (*sys_rdw
) (addr
);
2734 /****************************************************************************
2736 Pushes a word onto the stack.
2738 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2739 ****************************************************************************/
2743 DB(if (CHECK_SP_ACCESS())
2744 x86emu_check_sp_access();)
2746 (*sys_wrw
) (((u32
) M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
, w
);
2749 /****************************************************************************
2751 Pushes a long onto the stack.
2753 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2754 ****************************************************************************/
2758 DB(if (CHECK_SP_ACCESS())
2759 x86emu_check_sp_access();)
2761 (*sys_wrl
) (((u32
) M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
, w
);
2764 /****************************************************************************
2766 Pops a word from the stack.
2768 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2769 ****************************************************************************/
2775 DB(if (CHECK_SP_ACCESS())
2776 x86emu_check_sp_access();)
2777 res
= (*sys_rdw
) (((u32
) M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
);
2782 /****************************************************************************
2784 Pops a long from the stack.
2786 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2787 ****************************************************************************/
2793 DB(if (CHECK_SP_ACCESS())
2794 x86emu_check_sp_access();)
2795 res
= (*sys_rdl
) (((u32
) M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
);
2800 /****************************************************************************
2802 CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
2803 ****************************************************************************/
2807 u32 feature
= M
.x86
.R_EAX
;
2809 #ifdef X86EMU_HAS_HW_CPUID
2810 /* If the platform allows it, we will base our values on the real
2811 * results from the CPUID instruction. We limit support to the
2812 * first two features, and the results of those are sanitized.
2815 hw_cpuid(&M
.x86
.R_EAX
, &M
.x86
.R_EBX
, &M
.x86
.R_ECX
, &M
.x86
.R_EDX
);
2820 /* Regardless if we have real data from the hardware, the emulator
2821 * will only support upto feature 1, which we set in register EAX.
2822 * Registers EBX:EDX:ECX contain a string identifying the CPU.
2825 #ifndef X86EMU_HAS_HW_CPUID
2826 /* EBX:EDX:ECX = "GenuineIntel" */
2827 M
.x86
.R_EBX
= 0x756e6547;
2828 M
.x86
.R_EDX
= 0x49656e69;
2829 M
.x86
.R_ECX
= 0x6c65746e;
2833 #ifndef X86EMU_HAS_HW_CPUID
2834 /* If we don't have x86 compatible hardware, we return values from an
2835 * Intel 486dx4; which was one of the first processors to have CPUID.
2837 M
.x86
.R_EAX
= 0x00000480;
2838 M
.x86
.R_EBX
= 0x00000000;
2839 M
.x86
.R_ECX
= 0x00000000;
2840 M
.x86
.R_EDX
= 0x00000002; /* VME */
2842 /* In the case that we have hardware CPUID instruction, we make sure
2843 * that the features reported are limited to TSC and VME.
2845 M
.x86
.R_EDX
&= 0x00000012;
2849 /* Finally, we don't support any additional features. Most CPUs
2850 * return all zeros when queried for invalid or unsupported feature