]>
git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/hwinfo/src/x86emu/prim_ops.c
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 static u32 x86emu_parity_tab
[8] =
117 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
118 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
120 /*----------------------------- Implementation ----------------------------*/
122 /****************************************************************************
124 Implements the AAA instruction and side effects.
125 ****************************************************************************/
129 if ((d
& 0xf) > 0x9 || ACCESS_FLAG(F_AF
)) {
138 res
= (u16
)(d
& 0xFF0F);
140 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
141 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
145 /****************************************************************************
147 Implements the AAA instruction and side effects.
148 ****************************************************************************/
152 if ((d
& 0xf) > 0x9 || ACCESS_FLAG(F_AF
)) {
161 res
= (u16
)(d
& 0xFF0F);
163 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
164 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
168 /****************************************************************************
170 Implements the AAD instruction and side effects.
171 ****************************************************************************/
177 hb
= (u8
)((d
>> 8) & 0xff);
178 lb
= (u8
)((d
& 0xff));
179 l
= (u16
)((lb
+ 10 * hb
) & 0xFF);
184 CONDITIONAL_SET_FLAG(l
& 0x80, F_SF
);
185 CONDITIONAL_SET_FLAG(l
== 0, F_ZF
);
186 CONDITIONAL_SET_FLAG(PARITY(l
& 0xff), F_PF
);
190 /****************************************************************************
192 Implements the AAM instruction and side effects.
193 ****************************************************************************/
205 CONDITIONAL_SET_FLAG(l
& 0x80, F_SF
);
206 CONDITIONAL_SET_FLAG(l
== 0, F_ZF
);
207 CONDITIONAL_SET_FLAG(PARITY(l
& 0xff), F_PF
);
211 /****************************************************************************
213 Implements the ADC instruction and side effects.
214 ****************************************************************************/
215 u8
adc_byte(u8 d
, u8 s
)
217 register u32 res
; /* all operands in native machine order */
220 if (ACCESS_FLAG(F_CF
))
225 CONDITIONAL_SET_FLAG(res
& 0x100, F_CF
);
226 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
227 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
228 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
230 /* calculate the carry chain SEE NOTE AT TOP. */
231 cc
= (s
& d
) | ((~res
) & (s
| d
));
232 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
233 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
237 /****************************************************************************
239 Implements the ADC instruction and side effects.
240 ****************************************************************************/
241 u16
adc_word(u16 d
, u16 s
)
243 register u32 res
; /* all operands in native machine order */
246 if (ACCESS_FLAG(F_CF
))
251 CONDITIONAL_SET_FLAG(res
& 0x10000, F_CF
);
252 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
253 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
254 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
256 /* calculate the carry chain SEE NOTE AT TOP. */
257 cc
= (s
& d
) | ((~res
) & (s
| d
));
258 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
259 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
263 /****************************************************************************
265 Implements the ADC instruction and side effects.
266 ****************************************************************************/
267 u32
adc_long(u32 d
, u32 s
)
269 register u32 lo
; /* all operands in native machine order */
274 if (ACCESS_FLAG(F_CF
)) {
275 lo
= 1 + (d
& 0xFFFF) + (s
& 0xFFFF);
279 lo
= (d
& 0xFFFF) + (s
& 0xFFFF);
282 hi
= (lo
>> 16) + (d
>> 16) + (s
>> 16);
284 CONDITIONAL_SET_FLAG(hi
& 0x10000, F_CF
);
285 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
286 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
287 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
289 /* calculate the carry chain SEE NOTE AT TOP. */
290 cc
= (s
& d
) | ((~res
) & (s
| d
));
291 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
292 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
296 /****************************************************************************
298 Implements the ADD instruction and side effects.
299 ****************************************************************************/
300 u8
add_byte(u8 d
, u8 s
)
302 register u32 res
; /* all operands in native machine order */
306 CONDITIONAL_SET_FLAG(res
& 0x100, F_CF
);
307 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
308 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
309 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
311 /* calculate the carry chain SEE NOTE AT TOP. */
312 cc
= (s
& d
) | ((~res
) & (s
| d
));
313 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
314 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
318 /****************************************************************************
320 Implements the ADD instruction and side effects.
321 ****************************************************************************/
322 u16
add_word(u16 d
, u16 s
)
324 register u32 res
; /* all operands in native machine order */
328 CONDITIONAL_SET_FLAG(res
& 0x10000, F_CF
);
329 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
330 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
331 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
333 /* calculate the carry chain SEE NOTE AT TOP. */
334 cc
= (s
& d
) | ((~res
) & (s
| d
));
335 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
336 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
340 /****************************************************************************
342 Implements the ADD instruction and side effects.
343 ****************************************************************************/
344 u32
add_long(u32 d
, u32 s
)
346 register u32 lo
; /* all operands in native machine order */
351 lo
= (d
& 0xFFFF) + (s
& 0xFFFF);
353 hi
= (lo
>> 16) + (d
>> 16) + (s
>> 16);
355 CONDITIONAL_SET_FLAG(hi
& 0x10000, F_CF
);
356 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
357 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
358 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
360 /* calculate the carry chain SEE NOTE AT TOP. */
361 cc
= (s
& d
) | ((~res
) & (s
| d
));
362 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
363 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
368 /****************************************************************************
370 Implements the AND instruction and side effects.
371 ****************************************************************************/
372 u8
and_byte(u8 d
, u8 s
)
374 register u8 res
; /* all operands in native machine order */
382 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
383 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
384 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
388 /****************************************************************************
390 Implements the AND instruction and side effects.
391 ****************************************************************************/
392 u16
and_word(u16 d
, u16 s
)
394 register u16 res
; /* all operands in native machine order */
402 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
403 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
404 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
408 /****************************************************************************
410 Implements the AND instruction and side effects.
411 ****************************************************************************/
412 u32
and_long(u32 d
, u32 s
)
414 register u32 res
; /* all operands in native machine order */
422 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
423 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
424 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
428 /****************************************************************************
430 Implements the CMP instruction and side effects.
431 ****************************************************************************/
432 u8
cmp_byte(u8 d
, u8 s
)
434 register u32 res
; /* all operands in native machine order */
439 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
440 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
441 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
443 /* calculate the borrow chain. See note at top */
444 bc
= (res
& (~d
| s
)) | (~d
& s
);
445 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
446 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
447 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
451 /****************************************************************************
453 Implements the CMP instruction and side effects.
454 ****************************************************************************/
455 u16
cmp_word(u16 d
, u16 s
)
457 register u32 res
; /* all operands in native machine order */
461 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
462 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
463 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
465 /* calculate the borrow chain. See note at top */
466 bc
= (res
& (~d
| s
)) | (~d
& s
);
467 CONDITIONAL_SET_FLAG(bc
& 0x8000, F_CF
);
468 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
469 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
473 /****************************************************************************
475 Implements the CMP instruction and side effects.
476 ****************************************************************************/
477 u32
cmp_long(u32 d
, u32 s
)
479 register u32 res
; /* all operands in native machine order */
483 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
484 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
485 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
487 /* calculate the borrow chain. See note at top */
488 bc
= (res
& (~d
| s
)) | (~d
& s
);
489 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
490 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
491 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
495 /****************************************************************************
497 Implements the DAA instruction and side effects.
498 ****************************************************************************/
502 if ((d
& 0xf) > 9 || ACCESS_FLAG(F_AF
)) {
506 if (res
> 0x9F || ACCESS_FLAG(F_CF
)) {
510 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
511 CONDITIONAL_SET_FLAG((res
& 0xFF) == 0, F_ZF
);
512 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
516 /****************************************************************************
518 Implements the DAS instruction and side effects.
519 ****************************************************************************/
522 if ((d
& 0xf) > 9 || ACCESS_FLAG(F_AF
)) {
526 if (d
> 0x9F || ACCESS_FLAG(F_CF
)) {
530 CONDITIONAL_SET_FLAG(d
& 0x80, F_SF
);
531 CONDITIONAL_SET_FLAG(d
== 0, F_ZF
);
532 CONDITIONAL_SET_FLAG(PARITY(d
& 0xff), F_PF
);
536 /****************************************************************************
538 Implements the DEC instruction and side effects.
539 ****************************************************************************/
542 register u32 res
; /* all operands in native machine order */
546 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
547 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
548 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
550 /* calculate the borrow chain. See note at top */
551 /* based on sub_byte, uses s==1. */
552 bc
= (res
& (~d
| 1)) | (~d
& 1);
553 /* carry flag unchanged */
554 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
555 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
559 /****************************************************************************
561 Implements the DEC instruction and side effects.
562 ****************************************************************************/
565 register u32 res
; /* all operands in native machine order */
569 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
570 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
571 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
573 /* calculate the borrow chain. See note at top */
574 /* based on the sub_byte routine, with s==1 */
575 bc
= (res
& (~d
| 1)) | (~d
& 1);
576 /* carry flag unchanged */
577 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
578 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
582 /****************************************************************************
584 Implements the DEC instruction and side effects.
585 ****************************************************************************/
588 register u32 res
; /* all operands in native machine order */
593 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
594 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
595 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
597 /* calculate the borrow chain. See note at top */
598 bc
= (res
& (~d
| 1)) | (~d
& 1);
599 /* carry flag unchanged */
600 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
601 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
605 /****************************************************************************
607 Implements the INC instruction and side effects.
608 ****************************************************************************/
611 register u32 res
; /* all operands in native machine order */
615 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
616 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
617 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
619 /* calculate the carry chain SEE NOTE AT TOP. */
620 cc
= ((1 & d
) | (~res
)) & (1 | d
);
621 CONDITIONAL_SET_FLAG(XOR2(cc
>> 6), F_OF
);
622 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
626 /****************************************************************************
628 Implements the INC instruction and side effects.
629 ****************************************************************************/
632 register u32 res
; /* all operands in native machine order */
636 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
637 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
638 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
640 /* calculate the carry chain SEE NOTE AT TOP. */
641 cc
= (1 & d
) | ((~res
) & (1 | d
));
642 CONDITIONAL_SET_FLAG(XOR2(cc
>> 14), F_OF
);
643 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
647 /****************************************************************************
649 Implements the INC instruction and side effects.
650 ****************************************************************************/
653 register u32 res
; /* all operands in native machine order */
657 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
658 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
659 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
661 /* calculate the carry chain SEE NOTE AT TOP. */
662 cc
= (1 & d
) | ((~res
) & (1 | d
));
663 CONDITIONAL_SET_FLAG(XOR2(cc
>> 30), F_OF
);
664 CONDITIONAL_SET_FLAG(cc
& 0x8, F_AF
);
668 /****************************************************************************
670 Implements the OR instruction and side effects.
671 ****************************************************************************/
672 u8
or_byte(u8 d
, u8 s
)
674 register u8 res
; /* all operands in native machine order */
680 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
681 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
682 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
686 /****************************************************************************
688 Implements the OR instruction and side effects.
689 ****************************************************************************/
690 u16
or_word(u16 d
, u16 s
)
692 register u16 res
; /* all operands in native machine order */
695 /* set the carry flag to be bit 8 */
699 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
700 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
701 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
705 /****************************************************************************
707 Implements the OR instruction and side effects.
708 ****************************************************************************/
709 u32
or_long(u32 d
, u32 s
)
711 register u32 res
; /* all operands in native machine order */
715 /* set the carry flag to be bit 8 */
719 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
720 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
721 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
725 /****************************************************************************
727 Implements the OR instruction and side effects.
728 ****************************************************************************/
734 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
736 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
737 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
738 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
739 /* calculate the borrow chain --- modified such that d=0.
740 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
741 (the one used for sub) and simplifying, since ~d=0xff...,
742 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
743 ~d&s == s. So the simplified result is: */
745 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
746 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
750 /****************************************************************************
752 Implements the OR instruction and side effects.
753 ****************************************************************************/
759 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
761 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
762 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
763 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
765 /* calculate the borrow chain --- modified such that d=0.
766 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
767 (the one used for sub) and simplifying, since ~d=0xff...,
768 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
769 ~d&s == s. So the simplified result is: */
771 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
772 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
776 /****************************************************************************
778 Implements the OR instruction and side effects.
779 ****************************************************************************/
785 CONDITIONAL_SET_FLAG(s
!= 0, F_CF
);
787 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
788 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
789 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
791 /* calculate the borrow chain --- modified such that d=0.
792 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
793 (the one used for sub) and simplifying, since ~d=0xff...,
794 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
795 ~d&s == s. So the simplified result is: */
797 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
798 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
802 /****************************************************************************
804 Implements the NOT instruction and side effects.
805 ****************************************************************************/
811 /****************************************************************************
813 Implements the NOT instruction and side effects.
814 ****************************************************************************/
820 /****************************************************************************
822 Implements the NOT instruction and side effects.
823 ****************************************************************************/
829 /****************************************************************************
831 Implements the RCL instruction and side effects.
832 ****************************************************************************/
833 u8
rcl_byte(u8 d
, u8 s
)
835 register unsigned int res
, cnt
, mask
, cf
;
837 /* s is the rotate distance. It varies from 0 - 8. */
840 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
842 want to rotate through the carry by "s" bits. We could
843 loop, but that's inefficient. So the width is 9,
844 and we split into three parts:
846 The new carry flag (was B_n)
847 the stuff in B_n-1 .. B_0
848 the stuff in B_7 .. B_n+1
850 The new rotate is done mod 9, and given this,
851 for a rotation of n bits (mod 9) the new carry flag is
852 then located n bits from the MSB. The low part is
853 then shifted up cnt bits, and the high part is or'd
854 in. Using CAPS for new values, and lowercase for the
855 original values, this can be expressed as:
859 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
861 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
864 if ((cnt
= s
% 9) != 0) {
865 /* extract the new CARRY FLAG. */
867 cf
= (d
>> (8 - cnt
)) & 0x1;
869 /* get the low stuff which rotated
870 into the range B_7 .. B_cnt */
871 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
872 /* note that the right hand side done by the mask */
873 res
= (d
<< cnt
) & 0xff;
875 /* now the high stuff which rotated around
876 into the positions B_cnt-2 .. B_0 */
877 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
878 /* shift it downward, 7-(n-2) = 9-n positions.
879 and mask off the result before or'ing in.
881 mask
= (1 << (cnt
- 1)) - 1;
882 res
|= (d
>> (9 - cnt
)) & mask
;
884 /* if the carry flag was set, or it in. */
885 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
887 res
|= 1 << (cnt
- 1);
889 /* set the new carry flag, based on the variable "cf" */
890 CONDITIONAL_SET_FLAG(cf
, F_CF
);
891 /* OVERFLOW is set *IFF* cnt==1, then it is the
892 xor of CF and the most significant bit. Blecck. */
893 /* parenthesized this expression since it appears to
894 be causing OF to be misset */
895 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 6) & 0x2)),
902 /****************************************************************************
904 Implements the RCL instruction and side effects.
905 ****************************************************************************/
906 u16
rcl_word(u16 d
, u8 s
)
908 register unsigned int res
, cnt
, mask
, cf
;
911 if ((cnt
= s
% 17) != 0) {
912 cf
= (d
>> (16 - cnt
)) & 0x1;
913 res
= (d
<< cnt
) & 0xffff;
914 mask
= (1 << (cnt
- 1)) - 1;
915 res
|= (d
>> (17 - cnt
)) & mask
;
916 if (ACCESS_FLAG(F_CF
)) {
917 res
|= 1 << (cnt
- 1);
919 CONDITIONAL_SET_FLAG(cf
, F_CF
);
920 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 14) & 0x2)),
926 /****************************************************************************
928 Implements the RCL instruction and side effects.
929 ****************************************************************************/
930 u32
rcl_long(u32 d
, u8 s
)
932 register u32 res
, cnt
, mask
, cf
;
935 if ((cnt
= s
% 33) != 0) {
936 cf
= (d
>> (32 - cnt
)) & 0x1;
937 res
= (d
<< cnt
) & 0xffffffff;
938 mask
= (1 << (cnt
- 1)) - 1;
939 res
|= (d
>> (33 - cnt
)) & mask
;
940 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
941 res
|= 1 << (cnt
- 1);
943 CONDITIONAL_SET_FLAG(cf
, F_CF
);
944 CONDITIONAL_SET_FLAG(cnt
== 1 && XOR2(cf
+ ((res
>> 30) & 0x2)),
950 /****************************************************************************
952 Implements the RCR instruction and side effects.
953 ****************************************************************************/
954 u8
rcr_byte(u8 d
, u8 s
)
957 u32 mask
, cf
, ocf
= 0;
959 /* rotate right through carry */
961 s is the rotate distance. It varies from 0 - 8.
962 d is the byte object rotated.
966 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
968 The new rotate is done mod 9, and given this,
969 for a rotation of n bits (mod 9) the new carry flag is
970 then located n bits from the LSB. The low part is
971 then shifted up cnt bits, and the high part is or'd
972 in. Using CAPS for new values, and lowercase for the
973 original values, this can be expressed as:
977 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
979 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
982 if ((cnt
= s
% 9) != 0) {
983 /* extract the new CARRY FLAG. */
987 /* note hackery here. Access_flag(..) evaluates to either
989 non-zero if flag is set.
990 doing access_flag(..) != 0 casts that into either
991 0..1 in any representation of the flags register
992 (i.e. packed bit array or unpacked.)
994 ocf
= ACCESS_FLAG(F_CF
) != 0;
996 cf
= (d
>> (cnt
- 1)) & 0x1;
998 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
999 /* note that the right hand side done by the mask
1000 This is effectively done by shifting the
1001 object to the right. The result must be masked,
1002 in case the object came in and was treated
1003 as a negative number. Needed??? */
1005 mask
= (1 << (8 - cnt
)) - 1;
1006 res
= (d
>> cnt
) & mask
;
1008 /* now the high stuff which rotated around
1009 into the positions B_cnt-2 .. B_0 */
1010 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
1011 /* shift it downward, 7-(n-2) = 9-n positions.
1012 and mask off the result before or'ing in.
1014 res
|= (d
<< (9 - cnt
));
1016 /* if the carry flag was set, or it in. */
1017 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
1019 res
|= 1 << (8 - cnt
);
1021 /* set the new carry flag, based on the variable "cf" */
1022 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1023 /* OVERFLOW is set *IFF* cnt==1, then it is the
1024 xor of CF and the most significant bit. Blecck. */
1025 /* parenthesized... */
1027 CONDITIONAL_SET_FLAG(XOR2(ocf
+ ((d
>> 6) & 0x2)),
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)),
1066 /****************************************************************************
1068 Implements the RCR instruction and side effects.
1069 ****************************************************************************/
1070 u32
rcr_long(u32 d
, u8 s
)
1073 u32 mask
, cf
, ocf
= 0;
1075 /* rotate right through carry */
1077 if ((cnt
= s
% 33) != 0) {
1080 ocf
= ACCESS_FLAG(F_CF
) != 0;
1082 cf
= (d
>> (cnt
- 1)) & 0x1;
1083 mask
= (1 << (32 - cnt
)) - 1;
1084 res
= (d
>> cnt
) & mask
;
1086 res
|= (d
<< (33 - cnt
));
1087 if (ACCESS_FLAG(F_CF
)) { /* carry flag is set */
1088 res
|= 1 << (32 - cnt
);
1090 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1092 CONDITIONAL_SET_FLAG(XOR2(ocf
+ ((d
>> 30) & 0x2)),
1099 /****************************************************************************
1101 Implements the ROL instruction and side effects.
1102 ****************************************************************************/
1103 u8
rol_byte(u8 d
, u8 s
)
1105 register unsigned int res
, cnt
, mask
;
1109 s is the rotate distance. It varies from 0 - 8.
1110 d is the byte object rotated.
1116 The new rotate is done mod 8.
1117 Much simpler than the "rcl" or "rcr" operations.
1120 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1121 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1124 if ((cnt
= s
% 8) != 0) {
1125 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1128 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1129 mask
= (1 << cnt
) - 1;
1130 res
|= (d
>> (8 - cnt
)) & mask
;
1132 /* set the new carry flag, Note that it is the low order
1133 bit of the result!!! */
1134 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1135 /* OVERFLOW is set *IFF* s==1, then it is the
1136 xor of CF and the most significant bit. Blecck. */
1137 CONDITIONAL_SET_FLAG(s
== 1 &&
1138 XOR2((res
& 0x1) + ((res
>> 6) & 0x2)),
1141 /* set the new carry flag, Note that it is the low order
1142 bit of the result!!! */
1143 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1148 /****************************************************************************
1150 Implements the ROL instruction and side effects.
1151 ****************************************************************************/
1152 u16
rol_word(u16 d
, u8 s
)
1154 register unsigned int res
, cnt
, mask
;
1157 if ((cnt
= s
% 16) != 0) {
1159 mask
= (1 << cnt
) - 1;
1160 res
|= (d
>> (16 - cnt
)) & mask
;
1161 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1162 CONDITIONAL_SET_FLAG(s
== 1 &&
1163 XOR2((res
& 0x1) + ((res
>> 14) & 0x2)),
1166 /* set the new carry flag, Note that it is the low order
1167 bit of the result!!! */
1168 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1173 /****************************************************************************
1175 Implements the ROL instruction and side effects.
1176 ****************************************************************************/
1177 u32
rol_long(u32 d
, u8 s
)
1179 register u32 res
, cnt
, mask
;
1182 if ((cnt
= s
% 32) != 0) {
1184 mask
= (1 << cnt
) - 1;
1185 res
|= (d
>> (32 - cnt
)) & mask
;
1186 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1187 CONDITIONAL_SET_FLAG(s
== 1 &&
1188 XOR2((res
& 0x1) + ((res
>> 30) & 0x2)),
1191 /* set the new carry flag, Note that it is the low order
1192 bit of the result!!! */
1193 CONDITIONAL_SET_FLAG(res
& 0x1, F_CF
);
1198 /****************************************************************************
1200 Implements the ROR instruction and side effects.
1201 ****************************************************************************/
1202 u8
ror_byte(u8 d
, u8 s
)
1204 register unsigned int res
, cnt
, mask
;
1208 s is the rotate distance. It varies from 0 - 8.
1209 d is the byte object rotated.
1215 The rotate is done mod 8.
1218 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1219 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1222 if ((cnt
= s
% 8) != 0) { /* not a typo, do nada if cnt==0 */
1223 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1224 res
= (d
<< (8 - cnt
));
1226 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1227 mask
= (1 << (8 - cnt
)) - 1;
1228 res
|= (d
>> (cnt
)) & mask
;
1230 /* set the new carry flag, Note that it is the low order
1231 bit of the result!!! */
1232 CONDITIONAL_SET_FLAG(res
& 0x80, F_CF
);
1233 /* OVERFLOW is set *IFF* s==1, then it is the
1234 xor of the two most significant bits. Blecck. */
1235 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 6), F_OF
);
1236 } else if (s
!= 0) {
1237 /* set the new carry flag, Note that it is the low order
1238 bit of the result!!! */
1239 CONDITIONAL_SET_FLAG(res
& 0x80, F_CF
);
1244 /****************************************************************************
1246 Implements the ROR instruction and side effects.
1247 ****************************************************************************/
1248 u16
ror_word(u16 d
, u8 s
)
1250 register unsigned int res
, cnt
, mask
;
1253 if ((cnt
= s
% 16) != 0) {
1254 res
= (d
<< (16 - cnt
));
1255 mask
= (1 << (16 - cnt
)) - 1;
1256 res
|= (d
>> (cnt
)) & mask
;
1257 CONDITIONAL_SET_FLAG(res
& 0x8000, F_CF
);
1258 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 14), F_OF
);
1259 } else if (s
!= 0) {
1260 /* set the new carry flag, Note that it is the low order
1261 bit of the result!!! */
1262 CONDITIONAL_SET_FLAG(res
& 0x8000, F_CF
);
1267 /****************************************************************************
1269 Implements the ROR instruction and side effects.
1270 ****************************************************************************/
1271 u32
ror_long(u32 d
, u8 s
)
1273 register u32 res
, cnt
, mask
;
1276 if ((cnt
= s
% 32) != 0) {
1277 res
= (d
<< (32 - cnt
));
1278 mask
= (1 << (32 - cnt
)) - 1;
1279 res
|= (d
>> (cnt
)) & mask
;
1280 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_CF
);
1281 CONDITIONAL_SET_FLAG(s
== 1 && XOR2(res
>> 30), F_OF
);
1282 } else if (s
!= 0) {
1283 /* set the new carry flag, Note that it is the low order
1284 bit of the result!!! */
1285 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_CF
);
1290 /****************************************************************************
1292 Implements the SHL instruction and side effects.
1293 ****************************************************************************/
1294 u8
shl_byte(u8 d
, u8 s
)
1296 unsigned int cnt
, res
, cf
;
1301 /* last bit shifted out goes into carry flag */
1304 cf
= d
& (1 << (8 - cnt
));
1305 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1306 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1307 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1308 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1314 /* Needs simplification. */
1315 CONDITIONAL_SET_FLAG(
1316 (((res
& 0x80) == 0x80) ^
1317 (ACCESS_FLAG(F_CF
) != 0)),
1318 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1325 CONDITIONAL_SET_FLAG((d
<< (s
-1)) & 0x80, F_CF
);
1334 /****************************************************************************
1336 Implements the SHL instruction and side effects.
1337 ****************************************************************************/
1338 u16
shl_word(u16 d
, u8 s
)
1340 unsigned int cnt
, res
, cf
;
1346 cf
= d
& (1 << (16 - cnt
));
1347 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1348 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1349 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1350 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1356 CONDITIONAL_SET_FLAG(
1357 (((res
& 0x8000) == 0x8000) ^
1358 (ACCESS_FLAG(F_CF
) != 0)),
1365 CONDITIONAL_SET_FLAG((d
<< (s
-1)) & 0x8000, F_CF
);
1374 /****************************************************************************
1376 Implements the SHL instruction and side effects.
1377 ****************************************************************************/
1378 u32
shl_long(u32 d
, u8 s
)
1380 unsigned int cnt
, res
, cf
;
1386 cf
= d
& (1 << (32 - cnt
));
1387 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1388 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1389 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1390 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1395 CONDITIONAL_SET_FLAG((((res
& 0x80000000) == 0x80000000) ^
1396 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1402 CONDITIONAL_SET_FLAG((d
<< (s
-1)) & 0x80000000, F_CF
);
1411 /****************************************************************************
1413 Implements the SHR instruction and side effects.
1414 ****************************************************************************/
1415 u8
shr_byte(u8 d
, u8 s
)
1417 unsigned int cnt
, res
, cf
;
1422 cf
= d
& (1 << (cnt
- 1));
1424 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1425 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1426 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1427 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1433 CONDITIONAL_SET_FLAG(XOR2(res
>> 6), F_OF
);
1439 CONDITIONAL_SET_FLAG((d
>> (s
-1)) & 0x1, F_CF
);
1448 /****************************************************************************
1450 Implements the SHR instruction and side effects.
1451 ****************************************************************************/
1452 u16
shr_word(u16 d
, u8 s
)
1454 unsigned int cnt
, res
, cf
;
1459 cf
= d
& (1 << (cnt
- 1));
1461 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1462 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1463 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1464 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1470 CONDITIONAL_SET_FLAG(XOR2(res
>> 14), F_OF
);
1485 /****************************************************************************
1487 Implements the SHR instruction and side effects.
1488 ****************************************************************************/
1489 u32
shr_long(u32 d
, u8 s
)
1491 unsigned int cnt
, res
, cf
;
1496 cf
= d
& (1 << (cnt
- 1));
1498 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1499 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1500 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1501 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1506 CONDITIONAL_SET_FLAG(XOR2(res
>> 30), F_OF
);
1521 /****************************************************************************
1523 Implements the SAR instruction and side effects.
1524 ****************************************************************************/
1525 u8
sar_byte(u8 d
, u8 s
)
1527 unsigned int cnt
, res
, cf
, mask
, sf
;
1532 if (cnt
> 0 && cnt
< 8) {
1533 mask
= (1 << (8 - cnt
)) - 1;
1534 cf
= d
& (1 << (cnt
- 1));
1535 res
= (d
>> cnt
) & mask
;
1536 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1540 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1541 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1542 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1543 } else if (cnt
>= 8) {
1561 /****************************************************************************
1563 Implements the SAR instruction and side effects.
1564 ****************************************************************************/
1565 u16
sar_word(u16 d
, u8 s
)
1567 unsigned int cnt
, res
, cf
, mask
, sf
;
1572 if (cnt
> 0 && cnt
< 16) {
1573 mask
= (1 << (16 - cnt
)) - 1;
1574 cf
= d
& (1 << (cnt
- 1));
1575 res
= (d
>> cnt
) & mask
;
1576 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1580 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1581 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1582 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1583 } else if (cnt
>= 16) {
1601 /****************************************************************************
1603 Implements the SAR instruction and side effects.
1604 ****************************************************************************/
1605 u32
sar_long(u32 d
, u8 s
)
1607 u32 cnt
, res
, cf
, mask
, sf
;
1609 sf
= d
& 0x80000000;
1612 if (cnt
> 0 && cnt
< 32) {
1613 mask
= (1 << (32 - cnt
)) - 1;
1614 cf
= d
& (1 << (cnt
- 1));
1615 res
= (d
>> cnt
) & mask
;
1616 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1620 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1621 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1622 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1623 } else if (cnt
>= 32) {
1641 /****************************************************************************
1643 Implements the SHLD instruction and side effects.
1644 ****************************************************************************/
1645 u16
shld_word (u16 d
, u16 fill
, u8 s
)
1647 unsigned int cnt
, res
, cf
;
1652 res
= (d
<< cnt
) | (fill
>> (16-cnt
));
1653 cf
= d
& (1 << (16 - cnt
));
1654 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1655 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1656 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1657 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1662 CONDITIONAL_SET_FLAG((((res
& 0x8000) == 0x8000) ^
1663 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1669 CONDITIONAL_SET_FLAG((d
<< (s
-1)) & 0x8000, F_CF
);
1678 /****************************************************************************
1680 Implements the SHLD instruction and side effects.
1681 ****************************************************************************/
1682 u32
shld_long (u32 d
, u32 fill
, u8 s
)
1684 unsigned int cnt
, res
, cf
;
1689 res
= (d
<< cnt
) | (fill
>> (32-cnt
));
1690 cf
= d
& (1 << (32 - cnt
));
1691 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1692 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1693 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1694 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1699 CONDITIONAL_SET_FLAG((((res
& 0x80000000) == 0x80000000) ^
1700 (ACCESS_FLAG(F_CF
) != 0)), F_OF
);
1706 CONDITIONAL_SET_FLAG((d
<< (s
-1)) & 0x80000000, F_CF
);
1715 /****************************************************************************
1717 Implements the SHRD instruction and side effects.
1718 ****************************************************************************/
1719 u16
shrd_word (u16 d
, u16 fill
, u8 s
)
1721 unsigned int cnt
, res
, cf
;
1726 cf
= d
& (1 << (cnt
- 1));
1727 res
= (d
>> cnt
) | (fill
<< (16 - cnt
));
1728 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1729 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1730 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1731 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1737 CONDITIONAL_SET_FLAG(XOR2(res
>> 14), F_OF
);
1752 /****************************************************************************
1754 Implements the SHRD instruction and side effects.
1755 ****************************************************************************/
1756 u32
shrd_long (u32 d
, u32 fill
, u8 s
)
1758 unsigned int cnt
, res
, cf
;
1763 cf
= d
& (1 << (cnt
- 1));
1764 res
= (d
>> cnt
) | (fill
<< (32 - cnt
));
1765 CONDITIONAL_SET_FLAG(cf
, F_CF
);
1766 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1767 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1768 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1773 CONDITIONAL_SET_FLAG(XOR2(res
>> 30), F_OF
);
1788 /****************************************************************************
1790 Implements the SBB instruction and side effects.
1791 ****************************************************************************/
1792 u8
sbb_byte(u8 d
, u8 s
)
1794 register u32 res
; /* all operands in native machine order */
1797 if (ACCESS_FLAG(F_CF
))
1801 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1802 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1803 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1805 /* calculate the borrow chain. See note at top */
1806 bc
= (res
& (~d
| s
)) | (~d
& s
);
1807 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
1808 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
1809 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1813 /****************************************************************************
1815 Implements the SBB instruction and side effects.
1816 ****************************************************************************/
1817 u16
sbb_word(u16 d
, u16 s
)
1819 register u32 res
; /* all operands in native machine order */
1822 if (ACCESS_FLAG(F_CF
))
1826 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1827 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1828 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1830 /* calculate the borrow chain. See note at top */
1831 bc
= (res
& (~d
| s
)) | (~d
& s
);
1832 CONDITIONAL_SET_FLAG(bc
& 0x8000, F_CF
);
1833 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
1834 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1838 /****************************************************************************
1840 Implements the SBB instruction and side effects.
1841 ****************************************************************************/
1842 u32
sbb_long(u32 d
, u32 s
)
1844 register u32 res
; /* all operands in native machine order */
1847 if (ACCESS_FLAG(F_CF
))
1851 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1852 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1853 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1855 /* calculate the borrow chain. See note at top */
1856 bc
= (res
& (~d
| s
)) | (~d
& s
);
1857 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
1858 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
1859 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1863 /****************************************************************************
1865 Implements the SUB instruction and side effects.
1866 ****************************************************************************/
1867 u8
sub_byte(u8 d
, u8 s
)
1869 register u32 res
; /* all operands in native machine order */
1873 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1874 CONDITIONAL_SET_FLAG((res
& 0xff) == 0, F_ZF
);
1875 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1877 /* calculate the borrow chain. See note at top */
1878 bc
= (res
& (~d
| s
)) | (~d
& s
);
1879 CONDITIONAL_SET_FLAG(bc
& 0x80, F_CF
);
1880 CONDITIONAL_SET_FLAG(XOR2(bc
>> 6), F_OF
);
1881 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1885 /****************************************************************************
1887 Implements the SUB instruction and side effects.
1888 ****************************************************************************/
1889 u16
sub_word(u16 d
, u16 s
)
1891 register u32 res
; /* all operands in native machine order */
1895 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1896 CONDITIONAL_SET_FLAG((res
& 0xffff) == 0, F_ZF
);
1897 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1899 /* calculate the borrow chain. See note at top */
1900 bc
= (res
& (~d
| s
)) | (~d
& s
);
1901 CONDITIONAL_SET_FLAG(bc
& 0x8000, F_CF
);
1902 CONDITIONAL_SET_FLAG(XOR2(bc
>> 14), F_OF
);
1903 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1907 /****************************************************************************
1909 Implements the SUB instruction and side effects.
1910 ****************************************************************************/
1911 u32
sub_long(u32 d
, u32 s
)
1913 register u32 res
; /* all operands in native machine order */
1917 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1918 CONDITIONAL_SET_FLAG((res
& 0xffffffff) == 0, F_ZF
);
1919 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1921 /* calculate the borrow chain. See note at top */
1922 bc
= (res
& (~d
| s
)) | (~d
& s
);
1923 CONDITIONAL_SET_FLAG(bc
& 0x80000000, F_CF
);
1924 CONDITIONAL_SET_FLAG(XOR2(bc
>> 30), F_OF
);
1925 CONDITIONAL_SET_FLAG(bc
& 0x8, F_AF
);
1929 /****************************************************************************
1931 Implements the TEST instruction and side effects.
1932 ****************************************************************************/
1933 void test_byte(u8 d
, u8 s
)
1935 register u32 res
; /* all operands in native machine order */
1940 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1941 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
1942 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1943 /* AF == dont care */
1947 /****************************************************************************
1949 Implements the TEST instruction and side effects.
1950 ****************************************************************************/
1951 void test_word(u16 d
, u16 s
)
1953 register u32 res
; /* all operands in native machine order */
1958 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
1959 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
1960 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1961 /* AF == dont care */
1965 /****************************************************************************
1967 Implements the TEST instruction and side effects.
1968 ****************************************************************************/
1969 void test_long(u32 d
, u32 s
)
1971 register u32 res
; /* all operands in native machine order */
1976 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
1977 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
1978 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
1979 /* AF == dont care */
1983 /****************************************************************************
1985 Implements the XOR instruction and side effects.
1986 ****************************************************************************/
1987 u8
xor_byte(u8 d
, u8 s
)
1989 register u8 res
; /* all operands in native machine order */
1993 CONDITIONAL_SET_FLAG(res
& 0x80, F_SF
);
1994 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
1995 CONDITIONAL_SET_FLAG(PARITY(res
), F_PF
);
2001 /****************************************************************************
2003 Implements the XOR instruction and side effects.
2004 ****************************************************************************/
2005 u16
xor_word(u16 d
, u16 s
)
2007 register u16 res
; /* all operands in native machine order */
2011 CONDITIONAL_SET_FLAG(res
& 0x8000, F_SF
);
2012 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2013 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2019 /****************************************************************************
2021 Implements the XOR instruction and side effects.
2022 ****************************************************************************/
2023 u32
xor_long(u32 d
, u32 s
)
2025 register u32 res
; /* all operands in native machine order */
2029 CONDITIONAL_SET_FLAG(res
& 0x80000000, F_SF
);
2030 CONDITIONAL_SET_FLAG(res
== 0, F_ZF
);
2031 CONDITIONAL_SET_FLAG(PARITY(res
& 0xff), F_PF
);
2037 /****************************************************************************
2039 Implements the IMUL instruction and side effects.
2040 ****************************************************************************/
2041 void imul_byte(u8 s
)
2043 s16 res
= (s16
)((s8
)M
.x86
.R_AL
* (s8
)s
);
2046 if (((M
.x86
.R_AL
& 0x80) == 0 && M
.x86
.R_AH
== 0x00) ||
2047 ((M
.x86
.R_AL
& 0x80) != 0 && M
.x86
.R_AH
== 0xFF)) {
2056 /****************************************************************************
2058 Implements the IMUL instruction and side effects.
2059 ****************************************************************************/
2060 void imul_word(u16 s
)
2062 s32 res
= (s16
)M
.x86
.R_AX
* (s16
)s
;
2064 M
.x86
.R_AX
= (u16
)res
;
2065 M
.x86
.R_DX
= (u16
)(res
>> 16);
2066 if (((M
.x86
.R_AX
& 0x8000) == 0 && M
.x86
.R_DX
== 0x00) ||
2067 ((M
.x86
.R_AX
& 0x8000) != 0 && M
.x86
.R_DX
== 0xFF)) {
2076 /****************************************************************************
2078 Implements the IMUL instruction and side effects.
2079 ****************************************************************************/
2080 void imul_long_direct(u32
*res_lo
, u32
* res_hi
,u32 d
, u32 s
)
2082 #ifdef __HAS_LONG_LONG__
2083 s64 res
= (s32
)d
* (s32
)s
;
2086 *res_hi
= (u32
)(res
>> 32);
2088 u32 d_lo
,d_hi
,d_sign
;
2089 u32 s_lo
,s_hi
,s_sign
;
2090 u32 rlo_lo
,rlo_hi
,rhi_lo
;
2092 if ((d_sign
= d
& 0x80000000) != 0)
2096 if ((s_sign
= s
& 0x80000000) != 0)
2100 rlo_lo
= d_lo
* s_lo
;
2101 rlo_hi
= (d_hi
* s_lo
+ d_lo
* s_hi
) + (rlo_lo
>> 16);
2102 rhi_lo
= d_hi
* s_hi
+ (rlo_hi
>> 16);
2103 *res_lo
= (rlo_hi
<< 16) | (rlo_lo
& 0xFFFF);
2105 if (d_sign
!= s_sign
) {
2107 s
= (((d
& 0xFFFF) + 1) >> 16) + (d
>> 16);
2108 *res_lo
= ~*res_lo
+1;
2109 *res_hi
= ~*res_hi
+(s
>> 16);
2114 /****************************************************************************
2116 Implements the IMUL instruction and side effects.
2117 ****************************************************************************/
2118 void imul_long(u32 s
)
2120 imul_long_direct(&M
.x86
.R_EAX
,&M
.x86
.R_EDX
,M
.x86
.R_EAX
,s
);
2121 if (((M
.x86
.R_EAX
& 0x80000000) == 0 && M
.x86
.R_EDX
== 0x00) ||
2122 ((M
.x86
.R_EAX
& 0x80000000) != 0 && M
.x86
.R_EDX
== 0xFF)) {
2131 /****************************************************************************
2133 Implements the MUL instruction and side effects.
2134 ****************************************************************************/
2137 u16 res
= (u16
)(M
.x86
.R_AL
* s
);
2140 if (M
.x86
.R_AH
== 0) {
2149 /****************************************************************************
2151 Implements the MUL instruction and side effects.
2152 ****************************************************************************/
2153 void mul_word(u16 s
)
2155 u32 res
= M
.x86
.R_AX
* s
;
2157 M
.x86
.R_AX
= (u16
)res
;
2158 M
.x86
.R_DX
= (u16
)(res
>> 16);
2159 if (M
.x86
.R_DX
== 0) {
2168 /****************************************************************************
2170 Implements the MUL instruction and side effects.
2171 ****************************************************************************/
2172 void mul_long(u32 s
)
2174 #ifdef __HAS_LONG_LONG__
2175 u64 res
= (u32
)M
.x86
.R_EAX
* (u32
)s
;
2177 M
.x86
.R_EAX
= (u32
)res
;
2178 M
.x86
.R_EDX
= (u32
)(res
>> 32);
2182 u32 rlo_lo
,rlo_hi
,rhi_lo
;
2189 rlo_lo
= a_lo
* s_lo
;
2190 rlo_hi
= (a_hi
* s_lo
+ a_lo
* s_hi
) + (rlo_lo
>> 16);
2191 rhi_lo
= a_hi
* s_hi
+ (rlo_hi
>> 16);
2192 M
.x86
.R_EAX
= (rlo_hi
<< 16) | (rlo_lo
& 0xFFFF);
2193 M
.x86
.R_EDX
= rhi_lo
;
2196 if (M
.x86
.R_EDX
== 0) {
2205 /****************************************************************************
2207 Implements the IDIV instruction and side effects.
2208 ****************************************************************************/
2209 void idiv_byte(u8 s
)
2213 dvd
= (s16
)M
.x86
.R_AX
;
2215 x86emu_intr_raise(0);
2220 if (abs(div
) > 0x7f) {
2221 x86emu_intr_raise(0);
2224 M
.x86
.R_AL
= (s8
) div
;
2225 M
.x86
.R_AH
= (s8
) mod
;
2228 /****************************************************************************
2230 Implements the IDIV instruction and side effects.
2231 ****************************************************************************/
2232 void idiv_word(u16 s
)
2236 dvd
= (((s32
)M
.x86
.R_DX
) << 16) | M
.x86
.R_AX
;
2238 x86emu_intr_raise(0);
2243 if (abs(div
) > 0x7fff) {
2244 x86emu_intr_raise(0);
2249 CONDITIONAL_SET_FLAG(div
== 0, F_ZF
);
2250 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2252 M
.x86
.R_AX
= (u16
)div
;
2253 M
.x86
.R_DX
= (u16
)mod
;
2256 /****************************************************************************
2258 Implements the IDIV instruction and side effects.
2259 ****************************************************************************/
2260 void idiv_long(u32 s
)
2262 #ifdef __HAS_LONG_LONG__
2265 dvd
= (((s64
)M
.x86
.R_EDX
) << 32) | M
.x86
.R_EAX
;
2267 x86emu_intr_raise(0);
2272 if (abs(div
) > 0x7fffffff) {
2273 x86emu_intr_raise(0);
2278 s32 h_dvd
= M
.x86
.R_EDX
;
2279 u32 l_dvd
= M
.x86
.R_EAX
;
2280 u32 abs_s
= s
& 0x7FFFFFFF;
2281 u32 abs_h_dvd
= h_dvd
& 0x7FFFFFFF;
2282 u32 h_s
= abs_s
>> 1;
2283 u32 l_s
= abs_s
<< 31;
2288 x86emu_intr_raise(0);
2293 carry
= (l_dvd
>= l_s
) ? 0 : 1;
2295 if (abs_h_dvd
< (h_s
+ carry
)) {
2297 l_s
= abs_s
<< (--counter
);
2300 abs_h_dvd
-= (h_s
+ carry
);
2301 l_dvd
= carry
? ((0xFFFFFFFF - l_s
) + l_dvd
+ 1)
2304 l_s
= abs_s
<< (--counter
);
2309 } while (counter
> -1);
2311 if (abs_h_dvd
|| (l_dvd
> abs_s
)) {
2312 x86emu_intr_raise(0);
2316 div
|= ((h_dvd
& 0x10000000) ^ (s
& 0x10000000));
2324 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2326 M
.x86
.R_EAX
= (u32
)div
;
2327 M
.x86
.R_EDX
= (u32
)mod
;
2330 /****************************************************************************
2332 Implements the DIV instruction and side effects.
2333 ****************************************************************************/
2340 x86emu_intr_raise(0);
2345 if (abs(div
) > 0xff) {
2346 x86emu_intr_raise(0);
2349 M
.x86
.R_AL
= (u8
)div
;
2350 M
.x86
.R_AH
= (u8
)mod
;
2353 /****************************************************************************
2355 Implements the DIV instruction and side effects.
2356 ****************************************************************************/
2357 void div_word(u16 s
)
2361 dvd
= (((u32
)M
.x86
.R_DX
) << 16) | M
.x86
.R_AX
;
2363 x86emu_intr_raise(0);
2368 if (abs(div
) > 0xffff) {
2369 x86emu_intr_raise(0);
2374 CONDITIONAL_SET_FLAG(div
== 0, F_ZF
);
2375 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2377 M
.x86
.R_AX
= (u16
)div
;
2378 M
.x86
.R_DX
= (u16
)mod
;
2381 /****************************************************************************
2383 Implements the DIV instruction and side effects.
2384 ****************************************************************************/
2385 void div_long(u32 s
)
2387 #ifdef __HAS_LONG_LONG__
2390 dvd
= (((u64
)M
.x86
.R_EDX
) << 32) | M
.x86
.R_EAX
;
2392 x86emu_intr_raise(0);
2397 if (abs(div
) > 0xffffffff) {
2398 x86emu_intr_raise(0);
2403 s32 h_dvd
= M
.x86
.R_EDX
;
2404 u32 l_dvd
= M
.x86
.R_EAX
;
2412 x86emu_intr_raise(0);
2417 carry
= (l_dvd
>= l_s
) ? 0 : 1;
2419 if (h_dvd
< (h_s
+ carry
)) {
2421 l_s
= s
<< (--counter
);
2424 h_dvd
-= (h_s
+ carry
);
2425 l_dvd
= carry
? ((0xFFFFFFFF - l_s
) + l_dvd
+ 1)
2428 l_s
= s
<< (--counter
);
2433 } while (counter
> -1);
2435 if (h_dvd
|| (l_dvd
> s
)) {
2436 x86emu_intr_raise(0);
2445 CONDITIONAL_SET_FLAG(PARITY(mod
& 0xff), F_PF
);
2447 M
.x86
.R_EAX
= (u32
)div
;
2448 M
.x86
.R_EDX
= (u32
)mod
;
2451 /****************************************************************************
2453 Implements the IN string instruction and side effects.
2454 ****************************************************************************/
2459 if (ACCESS_FLAG(F_DF
)) {
2462 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2463 /* dont care whether REPE or REPNE */
2464 /* in until CX is ZERO. */
2465 u32 count
= ((M
.x86
.mode
& SYSMODE_PREFIX_DATA
) ?
2466 M
.x86
.R_ECX
: M
.x86
.R_CX
);
2470 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2471 (*sys_inb
)(M
.x86
.R_DX
));
2478 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2479 (*sys_inw
)(M
.x86
.R_DX
));
2485 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2486 (*sys_inl
)(M
.x86
.R_DX
));
2492 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2495 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2499 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2500 (*sys_inb
)(M
.x86
.R_DX
));
2503 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2504 (*sys_inw
)(M
.x86
.R_DX
));
2507 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
,
2508 (*sys_inl
)(M
.x86
.R_DX
));
2515 /****************************************************************************
2517 Implements the OUT string instruction and side effects.
2518 ****************************************************************************/
2523 if (ACCESS_FLAG(F_DF
)) {
2526 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2527 /* dont care whether REPE or REPNE */
2528 /* out until CX is ZERO. */
2529 u32 count
= ((M
.x86
.mode
& SYSMODE_PREFIX_DATA
) ?
2530 M
.x86
.R_ECX
: M
.x86
.R_CX
);
2534 (*sys_outb
)(M
.x86
.R_DX
,
2535 fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2542 (*sys_outw
)(M
.x86
.R_DX
,
2543 fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2549 (*sys_outl
)(M
.x86
.R_DX
,
2550 fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2556 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2559 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2563 (*sys_outb
)(M
.x86
.R_DX
,
2564 fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2567 (*sys_outw
)(M
.x86
.R_DX
,
2568 fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2571 (*sys_outl
)(M
.x86
.R_DX
,
2572 fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_SI
));
2579 /****************************************************************************
2581 addr - Address to fetch word from
2584 Fetches a word from emulator memory using an absolute address.
2585 ****************************************************************************/
2586 u16
mem_access_word(int addr
)
2588 DB( if (CHECK_MEM_ACCESS())
2589 x86emu_check_mem_access(addr
);)
2590 return (*sys_rdw
)(addr
);
2593 /****************************************************************************
2595 Pushes a word onto the stack.
2597 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2598 ****************************************************************************/
2599 void push_word(u16 w
)
2601 DB( if (CHECK_SP_ACCESS())
2602 x86emu_check_sp_access();)
2604 (*sys_wrw
)(((u32
)M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
, w
);
2607 /****************************************************************************
2609 Pushes a long onto the stack.
2611 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2612 ****************************************************************************/
2613 void push_long(u32 w
)
2615 DB( if (CHECK_SP_ACCESS())
2616 x86emu_check_sp_access();)
2618 (*sys_wrl
)(((u32
)M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
, w
);
2621 /****************************************************************************
2623 Pops a word from the stack.
2625 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2626 ****************************************************************************/
2631 DB( if (CHECK_SP_ACCESS())
2632 x86emu_check_sp_access();)
2633 res
= (*sys_rdw
)(((u32
)M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
);
2638 /****************************************************************************
2640 Pops a long from the stack.
2642 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2643 ****************************************************************************/
2648 DB( if (CHECK_SP_ACCESS())
2649 x86emu_check_sp_access();)
2650 res
= (*sys_rdl
)(((u32
)M
.x86
.R_SS
<< 4) + M
.x86
.R_SP
);