GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / x86emu / prim_ops.c
blobdca16cd07e8c22e6d310af2f26c76d05a2fede74
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 * ========================================================================
31 * Language: ANSI C
32 * Environment: Any
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.
51 * a b cin r cout
52 * 0 0 0 0 0
53 * 0 0 1 1 0
54 * 0 1 0 1 0
55 * 0 1 1 0 1
56 * 1 0 0 1 0
57 * 1 0 1 0 1
58 * 1 1 0 0 1
59 * 1 1 1 1 1
61 * Construction of table for cout:
63 * ab
64 * r \ 00 01 11 10
65 * |------------------
66 * 0 | 0 1 1 1
67 * 1 | 0 0 1 0
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.
78 * a b bin r bout
79 * 0 0 0 0 0
80 * 0 0 1 1 1
81 * 0 1 0 1 1
82 * 0 1 1 0 1
83 * 1 0 0 1 0
84 * 1 0 1 0 0
85 * 1 1 0 0 0
86 * 1 1 1 1 1
88 * Construction of table for cout:
90 * ab
91 * r \ 00 01 11 10
92 * |------------------
93 * 0 | 0 1 0 0
94 * 1 | 1 1 1 0
96 * By inspection, one gets: bc = a'b + r(a' + b)
98 ****************************************************************************/
100 #define PRIM_OPS_NO_REDEFINE_ASM
101 #include "x86emu/x86emui.h"
103 /*------------------------- Global Variables ------------------------------*/
105 #ifndef __HAVE_INLINE_ASSEMBLER__
107 static u32 x86emu_parity_tab[8] =
109 0x96696996,
110 0x69969669,
111 0x69969669,
112 0x96696996,
113 0x69969669,
114 0x96696996,
115 0x96696996,
116 0x69969669,
119 #endif
121 #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
122 #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
124 /*----------------------------- Implementation ----------------------------*/
126 #ifndef __HAVE_INLINE_ASSEMBLER__
128 /****************************************************************************
129 REMARKS:
130 Implements the AAA instruction and side effects.
131 ****************************************************************************/
132 u16 aaa_word(u16 d)
134 u16 res;
135 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
136 d += 0x6;
137 d += 0x100;
138 SET_FLAG(F_AF);
139 SET_FLAG(F_CF);
140 } else {
141 CLEAR_FLAG(F_CF);
142 CLEAR_FLAG(F_AF);
144 res = (u16)(d & 0xFF0F);
145 CLEAR_FLAG(F_SF);
146 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
147 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
148 return res;
151 /****************************************************************************
152 REMARKS:
153 Implements the AAA instruction and side effects.
154 ****************************************************************************/
155 u16 aas_word(u16 d)
157 u16 res;
158 if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
159 d -= 0x6;
160 d -= 0x100;
161 SET_FLAG(F_AF);
162 SET_FLAG(F_CF);
163 } else {
164 CLEAR_FLAG(F_CF);
165 CLEAR_FLAG(F_AF);
167 res = (u16)(d & 0xFF0F);
168 CLEAR_FLAG(F_SF);
169 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
170 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
171 return res;
174 /****************************************************************************
175 REMARKS:
176 Implements the AAD instruction and side effects.
177 ****************************************************************************/
178 u16 aad_word(u16 d)
180 u16 l;
181 u8 hb, lb;
183 hb = (u8)((d >> 8) & 0xff);
184 lb = (u8)((d & 0xff));
185 l = (u16)((lb + 10 * hb) & 0xFF);
187 CLEAR_FLAG(F_CF);
188 CLEAR_FLAG(F_AF);
189 CLEAR_FLAG(F_OF);
190 CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
191 CONDITIONAL_SET_FLAG(l == 0, F_ZF);
192 CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
193 return l;
196 /****************************************************************************
197 REMARKS:
198 Implements the AAM instruction and side effects.
199 ****************************************************************************/
200 u16 aam_word(u8 d)
202 u16 h, l;
204 h = (u16)(d / 10);
205 l = (u16)(d % 10);
206 l |= (u16)(h << 8);
208 CLEAR_FLAG(F_CF);
209 CLEAR_FLAG(F_AF);
210 CLEAR_FLAG(F_OF);
211 CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
212 CONDITIONAL_SET_FLAG(l == 0, F_ZF);
213 CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
214 return l;
217 /****************************************************************************
218 REMARKS:
219 Implements the ADC instruction and side effects.
220 ****************************************************************************/
221 u8 adc_byte(u8 d, u8 s)
223 register u32 res; /* all operands in native machine order */
224 register u32 cc;
226 if (ACCESS_FLAG(F_CF))
227 res = 1 + d + s;
228 else
229 res = d + s;
231 CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
232 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
233 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
234 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
236 /* calculate the carry chain SEE NOTE AT TOP. */
237 cc = (s & d) | ((~res) & (s | d));
238 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
239 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
240 return (u8)res;
243 /****************************************************************************
244 REMARKS:
245 Implements the ADC instruction and side effects.
246 ****************************************************************************/
247 u16 adc_word(u16 d, u16 s)
249 register u32 res; /* all operands in native machine order */
250 register u32 cc;
252 if (ACCESS_FLAG(F_CF))
253 res = 1 + d + s;
254 else
255 res = d + s;
257 CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
258 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
259 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
260 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
262 /* calculate the carry chain SEE NOTE AT TOP. */
263 cc = (s & d) | ((~res) & (s | d));
264 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
265 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
266 return (u16)res;
269 /****************************************************************************
270 REMARKS:
271 Implements the ADC instruction and side effects.
272 ****************************************************************************/
273 u32 adc_long(u32 d, u32 s)
275 register u32 lo; /* all operands in native machine order */
276 register u32 hi;
277 register u32 res;
278 register u32 cc;
280 if (ACCESS_FLAG(F_CF)) {
281 lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
282 res = 1 + d + s;
284 else {
285 lo = (d & 0xFFFF) + (s & 0xFFFF);
286 res = d + s;
288 hi = (lo >> 16) + (d >> 16) + (s >> 16);
290 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
291 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
292 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
293 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
295 /* calculate the carry chain SEE NOTE AT TOP. */
296 cc = (s & d) | ((~res) & (s | d));
297 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
298 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
299 return res;
302 /****************************************************************************
303 REMARKS:
304 Implements the ADD instruction and side effects.
305 ****************************************************************************/
306 u8 add_byte(u8 d, u8 s)
308 register u32 res; /* all operands in native machine order */
309 register u32 cc;
311 res = d + s;
312 CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
313 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
314 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
315 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
317 /* calculate the carry chain SEE NOTE AT TOP. */
318 cc = (s & d) | ((~res) & (s | d));
319 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
320 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
321 return (u8)res;
324 /****************************************************************************
325 REMARKS:
326 Implements the ADD instruction and side effects.
327 ****************************************************************************/
328 u16 add_word(u16 d, u16 s)
330 register u32 res; /* all operands in native machine order */
331 register u32 cc;
333 res = d + s;
334 CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
335 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
336 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
337 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
339 /* calculate the carry chain SEE NOTE AT TOP. */
340 cc = (s & d) | ((~res) & (s | d));
341 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
342 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
343 return (u16)res;
346 /****************************************************************************
347 REMARKS:
348 Implements the ADD instruction and side effects.
349 ****************************************************************************/
350 u32 add_long(u32 d, u32 s)
352 register u32 lo; /* all operands in native machine order */
353 register u32 hi;
354 register u32 res;
355 register u32 cc;
357 lo = (d & 0xFFFF) + (s & 0xFFFF);
358 res = d + s;
359 hi = (lo >> 16) + (d >> 16) + (s >> 16);
361 CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
362 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
363 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
364 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
366 /* calculate the carry chain SEE NOTE AT TOP. */
367 cc = (s & d) | ((~res) & (s | d));
368 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
369 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
371 return res;
374 /****************************************************************************
375 REMARKS:
376 Implements the AND instruction and side effects.
377 ****************************************************************************/
378 u8 and_byte(u8 d, u8 s)
380 register u8 res; /* all operands in native machine order */
382 res = d & s;
384 /* set the flags */
385 CLEAR_FLAG(F_OF);
386 CLEAR_FLAG(F_CF);
387 CLEAR_FLAG(F_AF);
388 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
389 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
390 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
391 return res;
394 /****************************************************************************
395 REMARKS:
396 Implements the AND instruction and side effects.
397 ****************************************************************************/
398 u16 and_word(u16 d, u16 s)
400 register u16 res; /* all operands in native machine order */
402 res = d & s;
404 /* set the flags */
405 CLEAR_FLAG(F_OF);
406 CLEAR_FLAG(F_CF);
407 CLEAR_FLAG(F_AF);
408 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
409 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
410 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
411 return res;
414 /****************************************************************************
415 REMARKS:
416 Implements the AND instruction and side effects.
417 ****************************************************************************/
418 u32 and_long(u32 d, u32 s)
420 register u32 res; /* all operands in native machine order */
422 res = d & s;
424 /* set the flags */
425 CLEAR_FLAG(F_OF);
426 CLEAR_FLAG(F_CF);
427 CLEAR_FLAG(F_AF);
428 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
429 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
430 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
431 return res;
434 /****************************************************************************
435 REMARKS:
436 Implements the CMP instruction and side effects.
437 ****************************************************************************/
438 u8 cmp_byte(u8 d, u8 s)
440 register u32 res; /* all operands in native machine order */
441 register u32 bc;
443 res = d - s;
444 CLEAR_FLAG(F_CF);
445 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
446 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
447 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
449 /* calculate the borrow chain. See note at top */
450 bc = (res & (~d | s)) | (~d & s);
451 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
452 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
453 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
454 return d;
457 /****************************************************************************
458 REMARKS:
459 Implements the CMP instruction and side effects.
460 ****************************************************************************/
461 u16 cmp_word(u16 d, u16 s)
463 register u32 res; /* all operands in native machine order */
464 register u32 bc;
466 res = d - s;
467 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
468 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
469 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
471 /* calculate the borrow chain. See note at top */
472 bc = (res & (~d | s)) | (~d & s);
473 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
474 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
475 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
476 return d;
479 /****************************************************************************
480 REMARKS:
481 Implements the CMP instruction and side effects.
482 ****************************************************************************/
483 u32 cmp_long(u32 d, u32 s)
485 register u32 res; /* all operands in native machine order */
486 register u32 bc;
488 res = d - s;
489 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
490 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
491 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
493 /* calculate the borrow chain. See note at top */
494 bc = (res & (~d | s)) | (~d & s);
495 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
496 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
497 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
498 return d;
501 /****************************************************************************
502 REMARKS:
503 Implements the DAA instruction and side effects.
504 ****************************************************************************/
505 u8 daa_byte(u8 d)
507 u32 res = d;
508 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
509 res += 6;
510 SET_FLAG(F_AF);
512 if (res > 0x9F || ACCESS_FLAG(F_CF)) {
513 res += 0x60;
514 SET_FLAG(F_CF);
516 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
517 CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
518 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
519 return (u8)res;
522 /****************************************************************************
523 REMARKS:
524 Implements the DAS instruction and side effects.
525 ****************************************************************************/
526 u8 das_byte(u8 d)
528 if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
529 d -= 6;
530 SET_FLAG(F_AF);
532 if (d > 0x9F || ACCESS_FLAG(F_CF)) {
533 d -= 0x60;
534 SET_FLAG(F_CF);
536 CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
537 CONDITIONAL_SET_FLAG(d == 0, F_ZF);
538 CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
539 return d;
542 /****************************************************************************
543 REMARKS:
544 Implements the DEC instruction and side effects.
545 ****************************************************************************/
546 u8 dec_byte(u8 d)
548 register u32 res; /* all operands in native machine order */
549 register u32 bc;
551 res = d - 1;
552 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
553 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
554 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
556 /* calculate the borrow chain. See note at top */
557 /* based on sub_byte, uses s==1. */
558 bc = (res & (~d | 1)) | (~d & 1);
559 /* carry flag unchanged */
560 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
561 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
562 return (u8)res;
565 /****************************************************************************
566 REMARKS:
567 Implements the DEC instruction and side effects.
568 ****************************************************************************/
569 u16 dec_word(u16 d)
571 register u32 res; /* all operands in native machine order */
572 register u32 bc;
574 res = d - 1;
575 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
576 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
577 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
579 /* calculate the borrow chain. See note at top */
580 /* based on the sub_byte routine, with s==1 */
581 bc = (res & (~d | 1)) | (~d & 1);
582 /* carry flag unchanged */
583 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
584 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
585 return (u16)res;
588 /****************************************************************************
589 REMARKS:
590 Implements the DEC instruction and side effects.
591 ****************************************************************************/
592 u32 dec_long(u32 d)
594 register u32 res; /* all operands in native machine order */
595 register u32 bc;
597 res = d - 1;
599 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
600 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
601 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
603 /* calculate the borrow chain. See note at top */
604 bc = (res & (~d | 1)) | (~d & 1);
605 /* carry flag unchanged */
606 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
607 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
608 return res;
611 /****************************************************************************
612 REMARKS:
613 Implements the INC instruction and side effects.
614 ****************************************************************************/
615 u8 inc_byte(u8 d)
617 register u32 res; /* all operands in native machine order */
618 register u32 cc;
620 res = d + 1;
621 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
622 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
623 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
625 /* calculate the carry chain SEE NOTE AT TOP. */
626 cc = ((1 & d) | (~res)) & (1 | d);
627 CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
628 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
629 return (u8)res;
632 /****************************************************************************
633 REMARKS:
634 Implements the INC instruction and side effects.
635 ****************************************************************************/
636 u16 inc_word(u16 d)
638 register u32 res; /* all operands in native machine order */
639 register u32 cc;
641 res = d + 1;
642 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
643 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
644 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
646 /* calculate the carry chain SEE NOTE AT TOP. */
647 cc = (1 & d) | ((~res) & (1 | d));
648 CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
649 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
650 return (u16)res;
653 /****************************************************************************
654 REMARKS:
655 Implements the INC instruction and side effects.
656 ****************************************************************************/
657 u32 inc_long(u32 d)
659 register u32 res; /* all operands in native machine order */
660 register u32 cc;
662 res = d + 1;
663 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
664 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
665 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
667 /* calculate the carry chain SEE NOTE AT TOP. */
668 cc = (1 & d) | ((~res) & (1 | d));
669 CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
670 CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
671 return res;
674 /****************************************************************************
675 REMARKS:
676 Implements the OR instruction and side effects.
677 ****************************************************************************/
678 u8 or_byte(u8 d, u8 s)
680 register u8 res; /* all operands in native machine order */
682 res = d | s;
683 CLEAR_FLAG(F_OF);
684 CLEAR_FLAG(F_CF);
685 CLEAR_FLAG(F_AF);
686 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
687 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
688 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
689 return res;
692 /****************************************************************************
693 REMARKS:
694 Implements the OR instruction and side effects.
695 ****************************************************************************/
696 u16 or_word(u16 d, u16 s)
698 register u16 res; /* all operands in native machine order */
700 res = d | s;
701 /* set the carry flag to be bit 8 */
702 CLEAR_FLAG(F_OF);
703 CLEAR_FLAG(F_CF);
704 CLEAR_FLAG(F_AF);
705 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
706 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
707 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
708 return res;
711 /****************************************************************************
712 REMARKS:
713 Implements the OR instruction and side effects.
714 ****************************************************************************/
715 u32 or_long(u32 d, u32 s)
717 register u32 res; /* all operands in native machine order */
719 res = d | s;
721 /* set the carry flag to be bit 8 */
722 CLEAR_FLAG(F_OF);
723 CLEAR_FLAG(F_CF);
724 CLEAR_FLAG(F_AF);
725 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
726 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
727 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
728 return res;
731 /****************************************************************************
732 REMARKS:
733 Implements the OR instruction and side effects.
734 ****************************************************************************/
735 u8 neg_byte(u8 s)
737 register u8 res;
738 register u8 bc;
740 CONDITIONAL_SET_FLAG(s != 0, F_CF);
741 res = (u8)-s;
742 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
743 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
744 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
745 /* calculate the borrow chain --- modified such that d=0.
746 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
747 (the one used for sub) and simplifying, since ~d=0xff...,
748 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
749 ~d&s == s. So the simplified result is: */
750 bc = res | s;
751 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
752 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
753 return res;
756 /****************************************************************************
757 REMARKS:
758 Implements the OR instruction and side effects.
759 ****************************************************************************/
760 u16 neg_word(u16 s)
762 register u16 res;
763 register u16 bc;
765 CONDITIONAL_SET_FLAG(s != 0, F_CF);
766 res = (u16)-s;
767 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
768 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
769 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
771 /* calculate the borrow chain --- modified such that d=0.
772 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
773 (the one used for sub) and simplifying, since ~d=0xff...,
774 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
775 ~d&s == s. So the simplified result is: */
776 bc = res | s;
777 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
778 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
779 return res;
782 /****************************************************************************
783 REMARKS:
784 Implements the OR instruction and side effects.
785 ****************************************************************************/
786 u32 neg_long(u32 s)
788 register u32 res;
789 register u32 bc;
791 CONDITIONAL_SET_FLAG(s != 0, F_CF);
792 res = (u32)-s;
793 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
794 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
795 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
797 /* calculate the borrow chain --- modified such that d=0.
798 substitutiing d=0 into bc= res&(~d|s)|(~d&s);
799 (the one used for sub) and simplifying, since ~d=0xff...,
800 ~d|s == 0xffff..., and res&0xfff... == res. Similarly
801 ~d&s == s. So the simplified result is: */
802 bc = res | s;
803 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
804 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
805 return res;
808 /****************************************************************************
809 REMARKS:
810 Implements the NOT instruction and side effects.
811 ****************************************************************************/
812 u8 not_byte(u8 s)
814 return ~s;
817 /****************************************************************************
818 REMARKS:
819 Implements the NOT instruction and side effects.
820 ****************************************************************************/
821 u16 not_word(u16 s)
823 return ~s;
826 /****************************************************************************
827 REMARKS:
828 Implements the NOT instruction and side effects.
829 ****************************************************************************/
830 u32 not_long(u32 s)
832 return ~s;
835 /****************************************************************************
836 REMARKS:
837 Implements the RCL instruction and side effects.
838 ****************************************************************************/
839 u8 rcl_byte(u8 d, u8 s)
841 register unsigned int res, cnt, mask, cf;
843 /* s is the rotate distance. It varies from 0 - 8. */
844 /* have
846 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
848 want to rotate through the carry by "s" bits. We could
849 loop, but that's inefficient. So the width is 9,
850 and we split into three parts:
852 The new carry flag (was B_n)
853 the stuff in B_n-1 .. B_0
854 the stuff in B_7 .. B_n+1
856 The new rotate is done mod 9, and given this,
857 for a rotation of n bits (mod 9) the new carry flag is
858 then located n bits from the MSB. The low part is
859 then shifted up cnt bits, and the high part is or'd
860 in. Using CAPS for new values, and lowercase for the
861 original values, this can be expressed as:
863 IF n > 0
864 1) CF <- b_(8-n)
865 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
866 3) B_(n-1) <- cf
867 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1))
869 res = d;
870 if ((cnt = s % 9) != 0) {
871 /* extract the new CARRY FLAG. */
872 /* CF <- b_(8-n) */
873 cf = (d >> (8 - cnt)) & 0x1;
875 /* get the low stuff which rotated
876 into the range B_7 .. B_cnt */
877 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
878 /* note that the right hand side done by the mask */
879 res = (d << cnt) & 0xff;
881 /* now the high stuff which rotated around
882 into the positions B_cnt-2 .. B_0 */
883 /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
884 /* shift it downward, 7-(n-2) = 9-n positions.
885 and mask off the result before or'ing in.
887 mask = (1 << (cnt - 1)) - 1;
888 res |= (d >> (9 - cnt)) & mask;
890 /* if the carry flag was set, or it in. */
891 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
892 /* B_(n-1) <- cf */
893 res |= 1 << (cnt - 1);
895 /* set the new carry flag, based on the variable "cf" */
896 CONDITIONAL_SET_FLAG(cf, F_CF);
897 /* OVERFLOW is set *IFF* cnt==1, then it is the
898 xor of CF and the most significant bit. Blecck. */
899 /* parenthesized this expression since it appears to
900 be causing OF to be misset */
901 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
902 F_OF);
905 return (u8)res;
908 /****************************************************************************
909 REMARKS:
910 Implements the RCL instruction and side effects.
911 ****************************************************************************/
912 u16 rcl_word(u16 d, u8 s)
914 register unsigned int res, cnt, mask, cf;
916 res = d;
917 if ((cnt = s % 17) != 0) {
918 cf = (d >> (16 - cnt)) & 0x1;
919 res = (d << cnt) & 0xffff;
920 mask = (1 << (cnt - 1)) - 1;
921 res |= (d >> (17 - cnt)) & mask;
922 if (ACCESS_FLAG(F_CF)) {
923 res |= 1 << (cnt - 1);
925 CONDITIONAL_SET_FLAG(cf, F_CF);
926 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
927 F_OF);
929 return (u16)res;
932 /****************************************************************************
933 REMARKS:
934 Implements the RCL instruction and side effects.
935 ****************************************************************************/
936 u32 rcl_long(u32 d, u8 s)
938 register u32 res, cnt, mask, cf;
940 res = d;
941 if ((cnt = s % 33) != 0) {
942 cf = (d >> (32 - cnt)) & 0x1;
943 res = (d << cnt) & 0xffffffff;
944 mask = (1 << (cnt - 1)) - 1;
945 res |= (d >> (33 - cnt)) & mask;
946 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
947 res |= 1 << (cnt - 1);
949 CONDITIONAL_SET_FLAG(cf, F_CF);
950 CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
951 F_OF);
953 return res;
956 /****************************************************************************
957 REMARKS:
958 Implements the RCR instruction and side effects.
959 ****************************************************************************/
960 u8 rcr_byte(u8 d, u8 s)
962 u32 res, cnt;
963 u32 mask, cf, ocf = 0;
965 /* rotate right through carry */
967 s is the rotate distance. It varies from 0 - 8.
968 d is the byte object rotated.
970 have
972 CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
974 The new rotate is done mod 9, and given this,
975 for a rotation of n bits (mod 9) the new carry flag is
976 then located n bits from the LSB. The low part is
977 then shifted up cnt bits, and the high part is or'd
978 in. Using CAPS for new values, and lowercase for the
979 original values, this can be expressed as:
981 IF n > 0
982 1) CF <- b_(n-1)
983 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
984 3) B_(8-n) <- cf
985 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0)
987 res = d;
988 if ((cnt = s % 9) != 0) {
989 /* extract the new CARRY FLAG. */
990 /* CF <- b_(n-1) */
991 if (cnt == 1) {
992 cf = d & 0x1;
993 /* note hackery here. Access_flag(..) evaluates to either
994 0 if flag not set
995 non-zero if flag is set.
996 doing access_flag(..) != 0 casts that into either
997 0..1 in any representation of the flags register
998 (i.e. packed bit array or unpacked.)
1000 ocf = ACCESS_FLAG(F_CF) != 0;
1001 } else
1002 cf = (d >> (cnt - 1)) & 0x1;
1004 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
1005 /* note that the right hand side done by the mask
1006 This is effectively done by shifting the
1007 object to the right. The result must be masked,
1008 in case the object came in and was treated
1009 as a negative number. Needed??? */
1011 mask = (1 << (8 - cnt)) - 1;
1012 res = (d >> cnt) & mask;
1014 /* now the high stuff which rotated around
1015 into the positions B_cnt-2 .. B_0 */
1016 /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
1017 /* shift it downward, 7-(n-2) = 9-n positions.
1018 and mask off the result before or'ing in.
1020 res |= (d << (9 - cnt));
1022 /* if the carry flag was set, or it in. */
1023 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1024 /* B_(8-n) <- cf */
1025 res |= 1 << (8 - cnt);
1027 /* set the new carry flag, based on the variable "cf" */
1028 CONDITIONAL_SET_FLAG(cf, F_CF);
1029 /* OVERFLOW is set *IFF* cnt==1, then it is the
1030 xor of CF and the most significant bit. Blecck. */
1031 /* parenthesized... */
1032 if (cnt == 1) {
1033 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
1034 F_OF);
1037 return (u8)res;
1040 /****************************************************************************
1041 REMARKS:
1042 Implements the RCR instruction and side effects.
1043 ****************************************************************************/
1044 u16 rcr_word(u16 d, u8 s)
1046 u32 res, cnt;
1047 u32 mask, cf, ocf = 0;
1049 /* rotate right through carry */
1050 res = d;
1051 if ((cnt = s % 17) != 0) {
1052 if (cnt == 1) {
1053 cf = d & 0x1;
1054 ocf = ACCESS_FLAG(F_CF) != 0;
1055 } else
1056 cf = (d >> (cnt - 1)) & 0x1;
1057 mask = (1 << (16 - cnt)) - 1;
1058 res = (d >> cnt) & mask;
1059 res |= (d << (17 - cnt));
1060 if (ACCESS_FLAG(F_CF)) {
1061 res |= 1 << (16 - cnt);
1063 CONDITIONAL_SET_FLAG(cf, F_CF);
1064 if (cnt == 1) {
1065 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
1066 F_OF);
1069 return (u16)res;
1072 /****************************************************************************
1073 REMARKS:
1074 Implements the RCR instruction and side effects.
1075 ****************************************************************************/
1076 u32 rcr_long(u32 d, u8 s)
1078 u32 res, cnt;
1079 u32 mask, cf, ocf = 0;
1081 /* rotate right through carry */
1082 res = d;
1083 if ((cnt = s % 33) != 0) {
1084 if (cnt == 1) {
1085 cf = d & 0x1;
1086 ocf = ACCESS_FLAG(F_CF) != 0;
1087 } else
1088 cf = (d >> (cnt - 1)) & 0x1;
1089 mask = (1 << (32 - cnt)) - 1;
1090 res = (d >> cnt) & mask;
1091 if (cnt != 1)
1092 res |= (d << (33 - cnt));
1093 if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
1094 res |= 1 << (32 - cnt);
1096 CONDITIONAL_SET_FLAG(cf, F_CF);
1097 if (cnt == 1) {
1098 CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
1099 F_OF);
1102 return res;
1105 /****************************************************************************
1106 REMARKS:
1107 Implements the ROL instruction and side effects.
1108 ****************************************************************************/
1109 u8 rol_byte(u8 d, u8 s)
1111 register unsigned int res, cnt, mask;
1113 /* rotate left */
1115 s is the rotate distance. It varies from 0 - 8.
1116 d is the byte object rotated.
1118 have
1120 CF B_7 ... B_0
1122 The new rotate is done mod 8.
1123 Much simpler than the "rcl" or "rcr" operations.
1125 IF n > 0
1126 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0)
1127 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n)
1129 res = d;
1130 if ((cnt = s % 8) != 0) {
1131 /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
1132 res = (d << cnt);
1134 /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
1135 mask = (1 << cnt) - 1;
1136 res |= (d >> (8 - cnt)) & mask;
1138 /* set the new carry flag, Note that it is the low order
1139 bit of the result!!! */
1140 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1141 /* OVERFLOW is set *IFF* s==1, then it is the
1142 xor of CF and the most significant bit. Blecck. */
1143 CONDITIONAL_SET_FLAG(s == 1 &&
1144 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1145 F_OF);
1146 } if (s != 0) {
1147 /* set the new carry flag, Note that it is the low order
1148 bit of the result!!! */
1149 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1151 return (u8)res;
1154 /****************************************************************************
1155 REMARKS:
1156 Implements the ROL instruction and side effects.
1157 ****************************************************************************/
1158 u16 rol_word(u16 d, u8 s)
1160 register unsigned int res, cnt, mask;
1162 res = d;
1163 if ((cnt = s % 16) != 0) {
1164 res = (d << cnt);
1165 mask = (1 << cnt) - 1;
1166 res |= (d >> (16 - cnt)) & mask;
1167 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1168 CONDITIONAL_SET_FLAG(s == 1 &&
1169 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1170 F_OF);
1171 } if (s != 0) {
1172 /* set the new carry flag, Note that it is the low order
1173 bit of the result!!! */
1174 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1176 return (u16)res;
1179 /****************************************************************************
1180 REMARKS:
1181 Implements the ROL instruction and side effects.
1182 ****************************************************************************/
1183 u32 rol_long(u32 d, u8 s)
1185 register u32 res, cnt, mask;
1187 res = d;
1188 if ((cnt = s % 32) != 0) {
1189 res = (d << cnt);
1190 mask = (1 << cnt) - 1;
1191 res |= (d >> (32 - cnt)) & mask;
1192 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1193 CONDITIONAL_SET_FLAG(s == 1 &&
1194 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1195 F_OF);
1196 } if (s != 0) {
1197 /* set the new carry flag, Note that it is the low order
1198 bit of the result!!! */
1199 CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1201 return res;
1204 /****************************************************************************
1205 REMARKS:
1206 Implements the ROR instruction and side effects.
1207 ****************************************************************************/
1208 u8 ror_byte(u8 d, u8 s)
1210 register unsigned int res, cnt, mask;
1212 /* rotate right */
1214 s is the rotate distance. It varies from 0 - 8.
1215 d is the byte object rotated.
1217 have
1219 B_7 ... B_0
1221 The rotate is done mod 8.
1223 IF n > 0
1224 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
1225 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0)
1227 res = d;
1228 if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
1229 /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
1230 res = (d << (8 - cnt));
1232 /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
1233 mask = (1 << (8 - cnt)) - 1;
1234 res |= (d >> (cnt)) & mask;
1236 /* set the new carry flag, Note that it is the low order
1237 bit of the result!!! */
1238 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1239 /* OVERFLOW is set *IFF* s==1, then it is the
1240 xor of the two most significant bits. Blecck. */
1241 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1242 } else if (s != 0) {
1243 /* set the new carry flag, Note that it is the low order
1244 bit of the result!!! */
1245 CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1247 return (u8)res;
1250 /****************************************************************************
1251 REMARKS:
1252 Implements the ROR instruction and side effects.
1253 ****************************************************************************/
1254 u16 ror_word(u16 d, u8 s)
1256 register unsigned int res, cnt, mask;
1258 res = d;
1259 if ((cnt = s % 16) != 0) {
1260 res = (d << (16 - cnt));
1261 mask = (1 << (16 - cnt)) - 1;
1262 res |= (d >> (cnt)) & mask;
1263 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1264 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1265 } else if (s != 0) {
1266 /* set the new carry flag, Note that it is the low order
1267 bit of the result!!! */
1268 CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1270 return (u16)res;
1273 /****************************************************************************
1274 REMARKS:
1275 Implements the ROR instruction and side effects.
1276 ****************************************************************************/
1277 u32 ror_long(u32 d, u8 s)
1279 register u32 res, cnt, mask;
1281 res = d;
1282 if ((cnt = s % 32) != 0) {
1283 res = (d << (32 - cnt));
1284 mask = (1 << (32 - cnt)) - 1;
1285 res |= (d >> (cnt)) & mask;
1286 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1287 CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1288 } else if (s != 0) {
1289 /* set the new carry flag, Note that it is the low order
1290 bit of the result!!! */
1291 CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1293 return res;
1296 /****************************************************************************
1297 REMARKS:
1298 Implements the SHL instruction and side effects.
1299 ****************************************************************************/
1300 u8 shl_byte(u8 d, u8 s)
1302 unsigned int cnt, res, cf;
1304 if (s < 8) {
1305 cnt = s % 8;
1307 /* last bit shifted out goes into carry flag */
1308 if (cnt > 0) {
1309 res = d << cnt;
1310 cf = d & (1 << (8 - cnt));
1311 CONDITIONAL_SET_FLAG(cf, F_CF);
1312 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1313 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1314 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1315 } else {
1316 res = (u8) d;
1319 if (cnt == 1) {
1320 /* Needs simplification. */
1321 CONDITIONAL_SET_FLAG(
1322 (((res & 0x80) == 0x80) ^
1323 (ACCESS_FLAG(F_CF) != 0)),
1324 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
1325 F_OF);
1326 } else {
1327 CLEAR_FLAG(F_OF);
1329 } else {
1330 res = 0;
1331 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1332 CLEAR_FLAG(F_OF);
1333 CLEAR_FLAG(F_SF);
1334 SET_FLAG(F_PF);
1335 SET_FLAG(F_ZF);
1337 return (u8)res;
1340 /****************************************************************************
1341 REMARKS:
1342 Implements the SHL instruction and side effects.
1343 ****************************************************************************/
1344 u16 shl_word(u16 d, u8 s)
1346 unsigned int cnt, res, cf;
1348 if (s < 16) {
1349 cnt = s % 16;
1350 if (cnt > 0) {
1351 res = d << cnt;
1352 cf = d & (1 << (16 - cnt));
1353 CONDITIONAL_SET_FLAG(cf, F_CF);
1354 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1355 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1356 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1357 } else {
1358 res = (u16) d;
1361 if (cnt == 1) {
1362 CONDITIONAL_SET_FLAG(
1363 (((res & 0x8000) == 0x8000) ^
1364 (ACCESS_FLAG(F_CF) != 0)),
1365 F_OF);
1366 } else {
1367 CLEAR_FLAG(F_OF);
1369 } else {
1370 res = 0;
1371 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1372 CLEAR_FLAG(F_OF);
1373 CLEAR_FLAG(F_SF);
1374 SET_FLAG(F_PF);
1375 SET_FLAG(F_ZF);
1377 return (u16)res;
1380 /****************************************************************************
1381 REMARKS:
1382 Implements the SHL instruction and side effects.
1383 ****************************************************************************/
1384 u32 shl_long(u32 d, u8 s)
1386 unsigned int cnt, res, cf;
1388 if (s < 32) {
1389 cnt = s % 32;
1390 if (cnt > 0) {
1391 res = d << cnt;
1392 cf = d & (1 << (32 - cnt));
1393 CONDITIONAL_SET_FLAG(cf, F_CF);
1394 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1395 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1396 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1397 } else {
1398 res = d;
1400 if (cnt == 1) {
1401 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1402 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1403 } else {
1404 CLEAR_FLAG(F_OF);
1406 } else {
1407 res = 0;
1408 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1409 CLEAR_FLAG(F_OF);
1410 CLEAR_FLAG(F_SF);
1411 SET_FLAG(F_PF);
1412 SET_FLAG(F_ZF);
1414 return res;
1417 /****************************************************************************
1418 REMARKS:
1419 Implements the SHR instruction and side effects.
1420 ****************************************************************************/
1421 u8 shr_byte(u8 d, u8 s)
1423 unsigned int cnt, res, cf;
1425 if (s < 8) {
1426 cnt = s % 8;
1427 if (cnt > 0) {
1428 cf = d & (1 << (cnt - 1));
1429 res = d >> cnt;
1430 CONDITIONAL_SET_FLAG(cf, F_CF);
1431 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1432 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1433 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1434 } else {
1435 res = (u8) d;
1438 if (cnt == 1) {
1439 CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1440 } else {
1441 CLEAR_FLAG(F_OF);
1443 } else {
1444 res = 0;
1445 CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1446 CLEAR_FLAG(F_OF);
1447 CLEAR_FLAG(F_SF);
1448 SET_FLAG(F_PF);
1449 SET_FLAG(F_ZF);
1451 return (u8)res;
1454 /****************************************************************************
1455 REMARKS:
1456 Implements the SHR instruction and side effects.
1457 ****************************************************************************/
1458 u16 shr_word(u16 d, u8 s)
1460 unsigned int cnt, res, cf;
1462 if (s < 16) {
1463 cnt = s % 16;
1464 if (cnt > 0) {
1465 cf = d & (1 << (cnt - 1));
1466 res = d >> cnt;
1467 CONDITIONAL_SET_FLAG(cf, F_CF);
1468 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1469 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1470 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1471 } else {
1472 res = d;
1475 if (cnt == 1) {
1476 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1477 } else {
1478 CLEAR_FLAG(F_OF);
1480 } else {
1481 res = 0;
1482 CLEAR_FLAG(F_CF);
1483 CLEAR_FLAG(F_OF);
1484 SET_FLAG(F_ZF);
1485 CLEAR_FLAG(F_SF);
1486 CLEAR_FLAG(F_PF);
1488 return (u16)res;
1491 /****************************************************************************
1492 REMARKS:
1493 Implements the SHR instruction and side effects.
1494 ****************************************************************************/
1495 u32 shr_long(u32 d, u8 s)
1497 unsigned int cnt, res, cf;
1499 if (s < 32) {
1500 cnt = s % 32;
1501 if (cnt > 0) {
1502 cf = d & (1 << (cnt - 1));
1503 res = d >> cnt;
1504 CONDITIONAL_SET_FLAG(cf, F_CF);
1505 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1506 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1507 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1508 } else {
1509 res = d;
1511 if (cnt == 1) {
1512 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1513 } else {
1514 CLEAR_FLAG(F_OF);
1516 } else {
1517 res = 0;
1518 CLEAR_FLAG(F_CF);
1519 CLEAR_FLAG(F_OF);
1520 SET_FLAG(F_ZF);
1521 CLEAR_FLAG(F_SF);
1522 CLEAR_FLAG(F_PF);
1524 return res;
1527 /****************************************************************************
1528 REMARKS:
1529 Implements the SAR instruction and side effects.
1530 ****************************************************************************/
1531 u8 sar_byte(u8 d, u8 s)
1533 unsigned int cnt, res, cf, mask, sf;
1535 res = d;
1536 sf = d & 0x80;
1537 cnt = s % 8;
1538 if (cnt > 0 && cnt < 8) {
1539 mask = (1 << (8 - cnt)) - 1;
1540 cf = d & (1 << (cnt - 1));
1541 res = (d >> cnt) & mask;
1542 CONDITIONAL_SET_FLAG(cf, F_CF);
1543 if (sf) {
1544 res |= ~mask;
1546 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1547 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1548 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1549 } else if (cnt >= 8) {
1550 if (sf) {
1551 res = 0xff;
1552 SET_FLAG(F_CF);
1553 CLEAR_FLAG(F_ZF);
1554 SET_FLAG(F_SF);
1555 SET_FLAG(F_PF);
1556 } else {
1557 res = 0;
1558 CLEAR_FLAG(F_CF);
1559 SET_FLAG(F_ZF);
1560 CLEAR_FLAG(F_SF);
1561 CLEAR_FLAG(F_PF);
1564 return (u8)res;
1567 /****************************************************************************
1568 REMARKS:
1569 Implements the SAR instruction and side effects.
1570 ****************************************************************************/
1571 u16 sar_word(u16 d, u8 s)
1573 unsigned int cnt, res, cf, mask, sf;
1575 sf = d & 0x8000;
1576 cnt = s % 16;
1577 res = d;
1578 if (cnt > 0 && cnt < 16) {
1579 mask = (1 << (16 - cnt)) - 1;
1580 cf = d & (1 << (cnt - 1));
1581 res = (d >> cnt) & mask;
1582 CONDITIONAL_SET_FLAG(cf, F_CF);
1583 if (sf) {
1584 res |= ~mask;
1586 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1587 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1588 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1589 } else if (cnt >= 16) {
1590 if (sf) {
1591 res = 0xffff;
1592 SET_FLAG(F_CF);
1593 CLEAR_FLAG(F_ZF);
1594 SET_FLAG(F_SF);
1595 SET_FLAG(F_PF);
1596 } else {
1597 res = 0;
1598 CLEAR_FLAG(F_CF);
1599 SET_FLAG(F_ZF);
1600 CLEAR_FLAG(F_SF);
1601 CLEAR_FLAG(F_PF);
1604 return (u16)res;
1607 /****************************************************************************
1608 REMARKS:
1609 Implements the SAR instruction and side effects.
1610 ****************************************************************************/
1611 u32 sar_long(u32 d, u8 s)
1613 u32 cnt, res, cf, mask, sf;
1615 sf = d & 0x80000000;
1616 cnt = s % 32;
1617 res = d;
1618 if (cnt > 0 && cnt < 32) {
1619 mask = (1 << (32 - cnt)) - 1;
1620 cf = d & (1 << (cnt - 1));
1621 res = (d >> cnt) & mask;
1622 CONDITIONAL_SET_FLAG(cf, F_CF);
1623 if (sf) {
1624 res |= ~mask;
1626 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1627 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1628 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1629 } else if (cnt >= 32) {
1630 if (sf) {
1631 res = 0xffffffff;
1632 SET_FLAG(F_CF);
1633 CLEAR_FLAG(F_ZF);
1634 SET_FLAG(F_SF);
1635 SET_FLAG(F_PF);
1636 } else {
1637 res = 0;
1638 CLEAR_FLAG(F_CF);
1639 SET_FLAG(F_ZF);
1640 CLEAR_FLAG(F_SF);
1641 CLEAR_FLAG(F_PF);
1644 return res;
1647 /****************************************************************************
1648 REMARKS:
1649 Implements the SHLD instruction and side effects.
1650 ****************************************************************************/
1651 u16 shld_word (u16 d, u16 fill, u8 s)
1653 unsigned int cnt, res, cf;
1655 if (s < 16) {
1656 cnt = s % 16;
1657 if (cnt > 0) {
1658 res = (d << cnt) | (fill >> (16-cnt));
1659 cf = d & (1 << (16 - cnt));
1660 CONDITIONAL_SET_FLAG(cf, F_CF);
1661 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1662 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1663 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1664 } else {
1665 res = d;
1667 if (cnt == 1) {
1668 CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1669 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1670 } else {
1671 CLEAR_FLAG(F_OF);
1673 } else {
1674 res = 0;
1675 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1676 CLEAR_FLAG(F_OF);
1677 CLEAR_FLAG(F_SF);
1678 SET_FLAG(F_PF);
1679 SET_FLAG(F_ZF);
1681 return (u16)res;
1684 /****************************************************************************
1685 REMARKS:
1686 Implements the SHLD instruction and side effects.
1687 ****************************************************************************/
1688 u32 shld_long (u32 d, u32 fill, u8 s)
1690 unsigned int cnt, res, cf;
1692 if (s < 32) {
1693 cnt = s % 32;
1694 if (cnt > 0) {
1695 res = (d << cnt) | (fill >> (32-cnt));
1696 cf = d & (1 << (32 - cnt));
1697 CONDITIONAL_SET_FLAG(cf, F_CF);
1698 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1699 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1700 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1701 } else {
1702 res = d;
1704 if (cnt == 1) {
1705 CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1706 (ACCESS_FLAG(F_CF) != 0)), F_OF);
1707 } else {
1708 CLEAR_FLAG(F_OF);
1710 } else {
1711 res = 0;
1712 CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1713 CLEAR_FLAG(F_OF);
1714 CLEAR_FLAG(F_SF);
1715 SET_FLAG(F_PF);
1716 SET_FLAG(F_ZF);
1718 return res;
1721 /****************************************************************************
1722 REMARKS:
1723 Implements the SHRD instruction and side effects.
1724 ****************************************************************************/
1725 u16 shrd_word (u16 d, u16 fill, u8 s)
1727 unsigned int cnt, res, cf;
1729 if (s < 16) {
1730 cnt = s % 16;
1731 if (cnt > 0) {
1732 cf = d & (1 << (cnt - 1));
1733 res = (d >> cnt) | (fill << (16 - cnt));
1734 CONDITIONAL_SET_FLAG(cf, F_CF);
1735 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1736 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1737 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1738 } else {
1739 res = d;
1742 if (cnt == 1) {
1743 CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1744 } else {
1745 CLEAR_FLAG(F_OF);
1747 } else {
1748 res = 0;
1749 CLEAR_FLAG(F_CF);
1750 CLEAR_FLAG(F_OF);
1751 SET_FLAG(F_ZF);
1752 CLEAR_FLAG(F_SF);
1753 CLEAR_FLAG(F_PF);
1755 return (u16)res;
1758 /****************************************************************************
1759 REMARKS:
1760 Implements the SHRD instruction and side effects.
1761 ****************************************************************************/
1762 u32 shrd_long (u32 d, u32 fill, u8 s)
1764 unsigned int cnt, res, cf;
1766 if (s < 32) {
1767 cnt = s % 32;
1768 if (cnt > 0) {
1769 cf = d & (1 << (cnt - 1));
1770 res = (d >> cnt) | (fill << (32 - cnt));
1771 CONDITIONAL_SET_FLAG(cf, F_CF);
1772 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1773 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1774 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1775 } else {
1776 res = d;
1778 if (cnt == 1) {
1779 CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1780 } else {
1781 CLEAR_FLAG(F_OF);
1783 } else {
1784 res = 0;
1785 CLEAR_FLAG(F_CF);
1786 CLEAR_FLAG(F_OF);
1787 SET_FLAG(F_ZF);
1788 CLEAR_FLAG(F_SF);
1789 CLEAR_FLAG(F_PF);
1791 return res;
1794 /****************************************************************************
1795 REMARKS:
1796 Implements the SBB instruction and side effects.
1797 ****************************************************************************/
1798 u8 sbb_byte(u8 d, u8 s)
1800 register u32 res; /* all operands in native machine order */
1801 register u32 bc;
1803 if (ACCESS_FLAG(F_CF))
1804 res = d - s - 1;
1805 else
1806 res = d - s;
1807 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1808 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1809 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1811 /* calculate the borrow chain. See note at top */
1812 bc = (res & (~d | s)) | (~d & s);
1813 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1814 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1815 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1816 return (u8)res;
1819 /****************************************************************************
1820 REMARKS:
1821 Implements the SBB instruction and side effects.
1822 ****************************************************************************/
1823 u16 sbb_word(u16 d, u16 s)
1825 register u32 res; /* all operands in native machine order */
1826 register u32 bc;
1828 if (ACCESS_FLAG(F_CF))
1829 res = d - s - 1;
1830 else
1831 res = d - s;
1832 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1833 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1834 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1836 /* calculate the borrow chain. See note at top */
1837 bc = (res & (~d | s)) | (~d & s);
1838 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1839 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1840 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1841 return (u16)res;
1844 /****************************************************************************
1845 REMARKS:
1846 Implements the SBB instruction and side effects.
1847 ****************************************************************************/
1848 u32 sbb_long(u32 d, u32 s)
1850 register u32 res; /* all operands in native machine order */
1851 register u32 bc;
1853 if (ACCESS_FLAG(F_CF))
1854 res = d - s - 1;
1855 else
1856 res = d - s;
1857 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1858 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1859 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1861 /* calculate the borrow chain. See note at top */
1862 bc = (res & (~d | s)) | (~d & s);
1863 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1864 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1865 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1866 return res;
1869 /****************************************************************************
1870 REMARKS:
1871 Implements the SUB instruction and side effects.
1872 ****************************************************************************/
1873 u8 sub_byte(u8 d, u8 s)
1875 register u32 res; /* all operands in native machine order */
1876 register u32 bc;
1878 res = d - s;
1879 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1880 CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1881 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1883 /* calculate the borrow chain. See note at top */
1884 bc = (res & (~d | s)) | (~d & s);
1885 CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1886 CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1887 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1888 return (u8)res;
1891 /****************************************************************************
1892 REMARKS:
1893 Implements the SUB instruction and side effects.
1894 ****************************************************************************/
1895 u16 sub_word(u16 d, u16 s)
1897 register u32 res; /* all operands in native machine order */
1898 register u32 bc;
1900 res = d - s;
1901 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1902 CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1903 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1905 /* calculate the borrow chain. See note at top */
1906 bc = (res & (~d | s)) | (~d & s);
1907 CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1908 CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1909 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1910 return (u16)res;
1913 /****************************************************************************
1914 REMARKS:
1915 Implements the SUB instruction and side effects.
1916 ****************************************************************************/
1917 u32 sub_long(u32 d, u32 s)
1919 register u32 res; /* all operands in native machine order */
1920 register u32 bc;
1922 res = d - s;
1923 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1924 CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1925 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1927 /* calculate the borrow chain. See note at top */
1928 bc = (res & (~d | s)) | (~d & s);
1929 CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1930 CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1931 CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1932 return res;
1935 /****************************************************************************
1936 REMARKS:
1937 Implements the TEST instruction and side effects.
1938 ****************************************************************************/
1939 void test_byte(u8 d, u8 s)
1941 register u32 res; /* all operands in native machine order */
1943 res = d & s;
1945 CLEAR_FLAG(F_OF);
1946 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1947 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1948 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1949 /* AF == dont care */
1950 CLEAR_FLAG(F_CF);
1953 /****************************************************************************
1954 REMARKS:
1955 Implements the TEST instruction and side effects.
1956 ****************************************************************************/
1957 void test_word(u16 d, u16 s)
1959 register u32 res; /* all operands in native machine order */
1961 res = d & s;
1963 CLEAR_FLAG(F_OF);
1964 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1965 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1966 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1967 /* AF == dont care */
1968 CLEAR_FLAG(F_CF);
1971 /****************************************************************************
1972 REMARKS:
1973 Implements the TEST instruction and side effects.
1974 ****************************************************************************/
1975 void test_long(u32 d, u32 s)
1977 register u32 res; /* all operands in native machine order */
1979 res = d & s;
1981 CLEAR_FLAG(F_OF);
1982 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1983 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1984 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1985 /* AF == dont care */
1986 CLEAR_FLAG(F_CF);
1989 /****************************************************************************
1990 REMARKS:
1991 Implements the XOR instruction and side effects.
1992 ****************************************************************************/
1993 u8 xor_byte(u8 d, u8 s)
1995 register u8 res; /* all operands in native machine order */
1997 res = d ^ s;
1998 CLEAR_FLAG(F_OF);
1999 CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
2000 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2001 CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
2002 CLEAR_FLAG(F_CF);
2003 CLEAR_FLAG(F_AF);
2004 return res;
2007 /****************************************************************************
2008 REMARKS:
2009 Implements the XOR instruction and side effects.
2010 ****************************************************************************/
2011 u16 xor_word(u16 d, u16 s)
2013 register u16 res; /* all operands in native machine order */
2015 res = d ^ s;
2016 CLEAR_FLAG(F_OF);
2017 CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
2018 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2019 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2020 CLEAR_FLAG(F_CF);
2021 CLEAR_FLAG(F_AF);
2022 return res;
2025 /****************************************************************************
2026 REMARKS:
2027 Implements the XOR instruction and side effects.
2028 ****************************************************************************/
2029 u32 xor_long(u32 d, u32 s)
2031 register u32 res; /* all operands in native machine order */
2033 res = d ^ s;
2034 CLEAR_FLAG(F_OF);
2035 CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
2036 CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2037 CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2038 CLEAR_FLAG(F_CF);
2039 CLEAR_FLAG(F_AF);
2040 return res;
2043 /****************************************************************************
2044 REMARKS:
2045 Implements the IMUL instruction and side effects.
2046 ****************************************************************************/
2047 void imul_byte(u8 s)
2049 s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
2051 M.x86.R_AX = res;
2052 if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
2053 ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
2054 CLEAR_FLAG(F_CF);
2055 CLEAR_FLAG(F_OF);
2056 } else {
2057 SET_FLAG(F_CF);
2058 SET_FLAG(F_OF);
2062 /****************************************************************************
2063 REMARKS:
2064 Implements the IMUL instruction and side effects.
2065 ****************************************************************************/
2066 void imul_word(u16 s)
2068 s32 res = (s16)M.x86.R_AX * (s16)s;
2070 M.x86.R_AX = (u16)res;
2071 M.x86.R_DX = (u16)(res >> 16);
2072 if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
2073 ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
2074 CLEAR_FLAG(F_CF);
2075 CLEAR_FLAG(F_OF);
2076 } else {
2077 SET_FLAG(F_CF);
2078 SET_FLAG(F_OF);
2082 /****************************************************************************
2083 REMARKS:
2084 Implements the IMUL instruction and side effects.
2085 ****************************************************************************/
2086 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2088 #ifdef __HAS_LONG_LONG__
2089 s64 res = (s32)d * (s32)s;
2091 *res_lo = (u32)res;
2092 *res_hi = (u32)(res >> 32);
2093 #else
2094 u32 d_lo,d_hi,d_sign;
2095 u32 s_lo,s_hi,s_sign;
2096 u32 rlo_lo,rlo_hi,rhi_lo;
2098 if ((d_sign = d & 0x80000000) != 0)
2099 d = -d;
2100 d_lo = d & 0xFFFF;
2101 d_hi = d >> 16;
2102 if ((s_sign = s & 0x80000000) != 0)
2103 s = -s;
2104 s_lo = s & 0xFFFF;
2105 s_hi = s >> 16;
2106 rlo_lo = d_lo * s_lo;
2107 rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
2108 rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
2109 *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2110 *res_hi = rhi_lo;
2111 if (d_sign != s_sign) {
2112 d = ~*res_lo;
2113 s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
2114 *res_lo = ~*res_lo+1;
2115 *res_hi = ~*res_hi+(s >> 16);
2117 #endif
2120 /****************************************************************************
2121 REMARKS:
2122 Implements the IMUL instruction and side effects.
2123 ****************************************************************************/
2124 void imul_long(u32 s)
2126 imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
2127 if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
2128 ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
2129 CLEAR_FLAG(F_CF);
2130 CLEAR_FLAG(F_OF);
2131 } else {
2132 SET_FLAG(F_CF);
2133 SET_FLAG(F_OF);
2137 /****************************************************************************
2138 REMARKS:
2139 Implements the MUL instruction and side effects.
2140 ****************************************************************************/
2141 void mul_byte(u8 s)
2143 u16 res = (u16)(M.x86.R_AL * s);
2145 M.x86.R_AX = res;
2146 if (M.x86.R_AH == 0) {
2147 CLEAR_FLAG(F_CF);
2148 CLEAR_FLAG(F_OF);
2149 } else {
2150 SET_FLAG(F_CF);
2151 SET_FLAG(F_OF);
2155 /****************************************************************************
2156 REMARKS:
2157 Implements the MUL instruction and side effects.
2158 ****************************************************************************/
2159 void mul_word(u16 s)
2161 u32 res = M.x86.R_AX * s;
2163 M.x86.R_AX = (u16)res;
2164 M.x86.R_DX = (u16)(res >> 16);
2165 if (M.x86.R_DX == 0) {
2166 CLEAR_FLAG(F_CF);
2167 CLEAR_FLAG(F_OF);
2168 } else {
2169 SET_FLAG(F_CF);
2170 SET_FLAG(F_OF);
2174 /****************************************************************************
2175 REMARKS:
2176 Implements the MUL instruction and side effects.
2177 ****************************************************************************/
2178 void mul_long(u32 s)
2180 #ifdef __HAS_LONG_LONG__
2181 u64 res = (u32)M.x86.R_EAX * (u32)s;
2183 M.x86.R_EAX = (u32)res;
2184 M.x86.R_EDX = (u32)(res >> 32);
2185 #else
2186 u32 a,a_lo,a_hi;
2187 u32 s_lo,s_hi;
2188 u32 rlo_lo,rlo_hi,rhi_lo;
2190 a = M.x86.R_EAX;
2191 a_lo = a & 0xFFFF;
2192 a_hi = a >> 16;
2193 s_lo = s & 0xFFFF;
2194 s_hi = s >> 16;
2195 rlo_lo = a_lo * s_lo;
2196 rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2197 rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2198 M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2199 M.x86.R_EDX = rhi_lo;
2200 #endif
2202 if (M.x86.R_EDX == 0) {
2203 CLEAR_FLAG(F_CF);
2204 CLEAR_FLAG(F_OF);
2205 } else {
2206 SET_FLAG(F_CF);
2207 SET_FLAG(F_OF);
2211 /****************************************************************************
2212 REMARKS:
2213 Implements the IDIV instruction and side effects.
2214 ****************************************************************************/
2215 #define abs(a) (((a) < 0) ? -(a) : (a))
2216 void idiv_byte(u8 s)
2218 s32 dvd, div, mod;
2220 dvd = (s16)M.x86.R_AX;
2221 if (s == 0) {
2222 x86emu_intr_raise(0);
2223 return;
2225 div = dvd / (s8)s;
2226 mod = dvd % (s8)s;
2227 if (abs(div) > 0x7f) {
2228 x86emu_intr_raise(0);
2229 return;
2231 M.x86.R_AL = (s8) div;
2232 M.x86.R_AH = (s8) mod;
2235 /****************************************************************************
2236 REMARKS:
2237 Implements the IDIV instruction and side effects.
2238 ****************************************************************************/
2239 void idiv_word(u16 s)
2241 s32 dvd, div, mod;
2243 dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2244 if (s == 0) {
2245 x86emu_intr_raise(0);
2246 return;
2248 div = dvd / (s16)s;
2249 mod = dvd % (s16)s;
2250 if (abs(div) > 0x7fff) {
2251 x86emu_intr_raise(0);
2252 return;
2254 CLEAR_FLAG(F_CF);
2255 CLEAR_FLAG(F_SF);
2256 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2257 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2259 M.x86.R_AX = (u16)div;
2260 M.x86.R_DX = (u16)mod;
2263 /****************************************************************************
2264 REMARKS:
2265 Implements the IDIV instruction and side effects.
2266 ****************************************************************************/
2267 void idiv_long(u32 s)
2269 #ifdef __HAS_LONG_LONG__
2270 s64 dvd, div, mod;
2272 dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2273 if (s == 0) {
2274 x86emu_intr_raise(0);
2275 return;
2277 div = dvd / (s32)s;
2278 mod = dvd % (s32)s;
2279 if (abs(div) > 0x7fffffff) {
2280 x86emu_intr_raise(0);
2281 return;
2283 #else
2284 s32 div = 0, mod;
2285 s32 h_dvd = M.x86.R_EDX;
2286 u32 l_dvd = M.x86.R_EAX;
2287 u32 abs_s = s & 0x7FFFFFFF;
2288 u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2289 u32 h_s = abs_s >> 1;
2290 u32 l_s = abs_s << 31;
2291 int counter = 31;
2292 int carry;
2294 if (s == 0) {
2295 x86emu_intr_raise(0);
2296 return;
2298 do {
2299 div <<= 1;
2300 carry = (l_dvd >= l_s) ? 0 : 1;
2302 if (abs_h_dvd < (h_s + carry)) {
2303 h_s >>= 1;
2304 l_s = abs_s << (--counter);
2305 continue;
2306 } else {
2307 abs_h_dvd -= (h_s + carry);
2308 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2309 : (l_dvd - l_s);
2310 h_s >>= 1;
2311 l_s = abs_s << (--counter);
2312 div |= 1;
2313 continue;
2316 } while (counter > -1);
2317 /* overflow */
2318 if (abs_h_dvd || (l_dvd > abs_s)) {
2319 x86emu_intr_raise(0);
2320 return;
2322 /* sign */
2323 div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2324 mod = l_dvd;
2326 #endif
2327 CLEAR_FLAG(F_CF);
2328 CLEAR_FLAG(F_AF);
2329 CLEAR_FLAG(F_SF);
2330 SET_FLAG(F_ZF);
2331 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2333 M.x86.R_EAX = (u32)div;
2334 M.x86.R_EDX = (u32)mod;
2337 /****************************************************************************
2338 REMARKS:
2339 Implements the DIV instruction and side effects.
2340 ****************************************************************************/
2341 void div_byte(u8 s)
2343 u32 dvd, div, mod;
2345 dvd = M.x86.R_AX;
2346 if (s == 0) {
2347 x86emu_intr_raise(0);
2348 return;
2350 div = dvd / (u8)s;
2351 mod = dvd % (u8)s;
2352 if (abs(div) > 0xff) {
2353 x86emu_intr_raise(0);
2354 return;
2356 M.x86.R_AL = (u8)div;
2357 M.x86.R_AH = (u8)mod;
2360 /****************************************************************************
2361 REMARKS:
2362 Implements the DIV instruction and side effects.
2363 ****************************************************************************/
2364 void div_word(u16 s)
2366 u32 dvd, div, mod;
2368 dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2369 if (s == 0) {
2370 x86emu_intr_raise(0);
2371 return;
2373 div = dvd / (u16)s;
2374 mod = dvd % (u16)s;
2375 if (abs(div) > 0xffff) {
2376 x86emu_intr_raise(0);
2377 return;
2379 CLEAR_FLAG(F_CF);
2380 CLEAR_FLAG(F_SF);
2381 CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2382 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2384 M.x86.R_AX = (u16)div;
2385 M.x86.R_DX = (u16)mod;
2388 /****************************************************************************
2389 REMARKS:
2390 Implements the DIV instruction and side effects.
2391 ****************************************************************************/
2392 void div_long(u32 s)
2394 #ifdef __HAS_LONG_LONG__
2395 u64 dvd, div, mod;
2397 dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2398 if (s == 0) {
2399 x86emu_intr_raise(0);
2400 return;
2402 div = dvd / (u32)s;
2403 mod = dvd % (u32)s;
2404 if (abs(div) > 0xffffffff) {
2405 x86emu_intr_raise(0);
2406 return;
2408 #else
2409 s32 div = 0, mod;
2410 s32 h_dvd = M.x86.R_EDX;
2411 u32 l_dvd = M.x86.R_EAX;
2413 u32 h_s = s;
2414 u32 l_s = 0;
2415 int counter = 32;
2416 int carry;
2418 if (s == 0) {
2419 x86emu_intr_raise(0);
2420 return;
2422 do {
2423 div <<= 1;
2424 carry = (l_dvd >= l_s) ? 0 : 1;
2426 if (h_dvd < (h_s + carry)) {
2427 h_s >>= 1;
2428 l_s = s << (--counter);
2429 continue;
2430 } else {
2431 h_dvd -= (h_s + carry);
2432 l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2433 : (l_dvd - l_s);
2434 h_s >>= 1;
2435 l_s = s << (--counter);
2436 div |= 1;
2437 continue;
2440 } while (counter > -1);
2441 /* overflow */
2442 if (h_dvd || (l_dvd > s)) {
2443 x86emu_intr_raise(0);
2444 return;
2446 mod = l_dvd;
2447 #endif
2448 CLEAR_FLAG(F_CF);
2449 CLEAR_FLAG(F_AF);
2450 CLEAR_FLAG(F_SF);
2451 SET_FLAG(F_ZF);
2452 CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2454 M.x86.R_EAX = (u32)div;
2455 M.x86.R_EDX = (u32)mod;
2458 #endif /* __HAVE_INLINE_ASSEMBLER__ */
2460 /****************************************************************************
2461 REMARKS:
2462 Implements the IN string instruction and side effects.
2463 ****************************************************************************/
2464 void ins(int size)
2466 int inc = size;
2468 if (ACCESS_FLAG(F_DF)) {
2469 inc = -size;
2471 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2472 /* dont care whether REPE or REPNE */
2473 /* in until CX is ZERO. */
2474 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2475 M.x86.R_ECX : M.x86.R_CX);
2476 switch (size) {
2477 case 1:
2478 while (count--) {
2479 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2480 (*sys_inb)(M.x86.R_DX));
2481 M.x86.R_DI += inc;
2483 break;
2485 case 2:
2486 while (count--) {
2487 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2488 (*sys_inw)(M.x86.R_DX));
2489 M.x86.R_DI += inc;
2491 break;
2492 case 4:
2493 while (count--) {
2494 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2495 (*sys_inl)(M.x86.R_DX));
2496 M.x86.R_DI += inc;
2497 break;
2500 M.x86.R_CX = 0;
2501 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2502 M.x86.R_ECX = 0;
2504 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2505 } else {
2506 switch (size) {
2507 case 1:
2508 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2509 (*sys_inb)(M.x86.R_DX));
2510 break;
2511 case 2:
2512 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2513 (*sys_inw)(M.x86.R_DX));
2514 break;
2515 case 4:
2516 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2517 (*sys_inl)(M.x86.R_DX));
2518 break;
2520 M.x86.R_DI += inc;
2524 /****************************************************************************
2525 REMARKS:
2526 Implements the OUT string instruction and side effects.
2527 ****************************************************************************/
2528 void outs(int size)
2530 int inc = size;
2532 if (ACCESS_FLAG(F_DF)) {
2533 inc = -size;
2535 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2536 /* dont care whether REPE or REPNE */
2537 /* out until CX is ZERO. */
2538 u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2539 M.x86.R_ECX : M.x86.R_CX);
2540 switch (size) {
2541 case 1:
2542 while (count--) {
2543 (*sys_outb)(M.x86.R_DX,
2544 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2545 M.x86.R_SI += inc;
2547 break;
2549 case 2:
2550 while (count--) {
2551 (*sys_outw)(M.x86.R_DX,
2552 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2553 M.x86.R_SI += inc;
2555 break;
2556 case 4:
2557 while (count--) {
2558 (*sys_outl)(M.x86.R_DX,
2559 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2560 M.x86.R_SI += inc;
2561 break;
2564 M.x86.R_CX = 0;
2565 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2566 M.x86.R_ECX = 0;
2568 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2569 } else {
2570 switch (size) {
2571 case 1:
2572 (*sys_outb)(M.x86.R_DX,
2573 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2574 break;
2575 case 2:
2576 (*sys_outw)(M.x86.R_DX,
2577 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2578 break;
2579 case 4:
2580 (*sys_outl)(M.x86.R_DX,
2581 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2582 break;
2584 M.x86.R_SI += inc;
2588 /****************************************************************************
2589 PARAMETERS:
2590 addr - Address to fetch word from
2592 REMARKS:
2593 Fetches a word from emulator memory using an absolute address.
2594 ****************************************************************************/
2595 u16 mem_access_word(int addr)
2597 DB( if (CHECK_MEM_ACCESS())
2598 x86emu_check_mem_access(addr);)
2599 return (*sys_rdw)(addr);
2602 /****************************************************************************
2603 REMARKS:
2604 Pushes a word onto the stack.
2606 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2607 ****************************************************************************/
2608 void push_word(u16 w)
2610 DB( if (CHECK_SP_ACCESS())
2611 x86emu_check_sp_access();)
2612 M.x86.R_SP -= 2;
2613 (*sys_wrw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2616 /****************************************************************************
2617 REMARKS:
2618 Pushes a long onto the stack.
2620 NOTE: Do not inline this, as (*sys_wrX) is already inline!
2621 ****************************************************************************/
2622 void push_long(u32 w)
2624 DB( if (CHECK_SP_ACCESS())
2625 x86emu_check_sp_access();)
2626 M.x86.R_SP -= 4;
2627 (*sys_wrl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP, w);
2630 /****************************************************************************
2631 REMARKS:
2632 Pops a word from the stack.
2634 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2635 ****************************************************************************/
2636 u16 pop_word(void)
2638 register u16 res;
2640 DB( if (CHECK_SP_ACCESS())
2641 x86emu_check_sp_access();)
2642 res = (*sys_rdw)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2643 M.x86.R_SP += 2;
2644 return res;
2647 /****************************************************************************
2648 REMARKS:
2649 Pops a long from the stack.
2651 NOTE: Do not inline this, as (*sys_rdX) is already inline!
2652 ****************************************************************************/
2653 u32 pop_long(void)
2655 register u32 res;
2657 DB( if (CHECK_SP_ACCESS())
2658 x86emu_check_sp_access();)
2659 res = (*sys_rdl)(((u32)M.x86.R_SS << 4) + M.x86.R_SP);
2660 M.x86.R_SP += 4;
2661 return res;
2664 #ifdef __HAVE_INLINE_ASSEMBLER__
2666 u16 aaa_word (u16 d)
2667 { return aaa_word_asm(&M.x86.R_EFLG,d); }
2669 u16 aas_word (u16 d)
2670 { return aas_word_asm(&M.x86.R_EFLG,d); }
2672 u16 aad_word (u16 d)
2673 { return aad_word_asm(&M.x86.R_EFLG,d); }
2675 u16 aam_word (u8 d)
2676 { return aam_word_asm(&M.x86.R_EFLG,d); }
2678 u8 adc_byte (u8 d, u8 s)
2679 { return adc_byte_asm(&M.x86.R_EFLG,d,s); }
2681 u16 adc_word (u16 d, u16 s)
2682 { return adc_word_asm(&M.x86.R_EFLG,d,s); }
2684 u32 adc_long (u32 d, u32 s)
2685 { return adc_long_asm(&M.x86.R_EFLG,d,s); }
2687 u8 add_byte (u8 d, u8 s)
2688 { return add_byte_asm(&M.x86.R_EFLG,d,s); }
2690 u16 add_word (u16 d, u16 s)
2691 { return add_word_asm(&M.x86.R_EFLG,d,s); }
2693 u32 add_long (u32 d, u32 s)
2694 { return add_long_asm(&M.x86.R_EFLG,d,s); }
2696 u8 and_byte (u8 d, u8 s)
2697 { return and_byte_asm(&M.x86.R_EFLG,d,s); }
2699 u16 and_word (u16 d, u16 s)
2700 { return and_word_asm(&M.x86.R_EFLG,d,s); }
2702 u32 and_long (u32 d, u32 s)
2703 { return and_long_asm(&M.x86.R_EFLG,d,s); }
2705 u8 cmp_byte (u8 d, u8 s)
2706 { return cmp_byte_asm(&M.x86.R_EFLG,d,s); }
2708 u16 cmp_word (u16 d, u16 s)
2709 { return cmp_word_asm(&M.x86.R_EFLG,d,s); }
2711 u32 cmp_long (u32 d, u32 s)
2712 { return cmp_long_asm(&M.x86.R_EFLG,d,s); }
2714 u8 daa_byte (u8 d)
2715 { return daa_byte_asm(&M.x86.R_EFLG,d); }
2717 u8 das_byte (u8 d)
2718 { return das_byte_asm(&M.x86.R_EFLG,d); }
2720 u8 dec_byte (u8 d)
2721 { return dec_byte_asm(&M.x86.R_EFLG,d); }
2723 u16 dec_word (u16 d)
2724 { return dec_word_asm(&M.x86.R_EFLG,d); }
2726 u32 dec_long (u32 d)
2727 { return dec_long_asm(&M.x86.R_EFLG,d); }
2729 u8 inc_byte (u8 d)
2730 { return inc_byte_asm(&M.x86.R_EFLG,d); }
2732 u16 inc_word (u16 d)
2733 { return inc_word_asm(&M.x86.R_EFLG,d); }
2735 u32 inc_long (u32 d)
2736 { return inc_long_asm(&M.x86.R_EFLG,d); }
2738 u8 or_byte (u8 d, u8 s)
2739 { return or_byte_asm(&M.x86.R_EFLG,d,s); }
2741 u16 or_word (u16 d, u16 s)
2742 { return or_word_asm(&M.x86.R_EFLG,d,s); }
2744 u32 or_long (u32 d, u32 s)
2745 { return or_long_asm(&M.x86.R_EFLG,d,s); }
2747 u8 neg_byte (u8 s)
2748 { return neg_byte_asm(&M.x86.R_EFLG,s); }
2750 u16 neg_word (u16 s)
2751 { return neg_word_asm(&M.x86.R_EFLG,s); }
2753 u32 neg_long (u32 s)
2754 { return neg_long_asm(&M.x86.R_EFLG,s); }
2756 u8 not_byte (u8 s)
2757 { return not_byte_asm(&M.x86.R_EFLG,s); }
2759 u16 not_word (u16 s)
2760 { return not_word_asm(&M.x86.R_EFLG,s); }
2762 u32 not_long (u32 s)
2763 { return not_long_asm(&M.x86.R_EFLG,s); }
2765 u8 rcl_byte (u8 d, u8 s)
2766 { return rcl_byte_asm(&M.x86.R_EFLG,d,s); }
2768 u16 rcl_word (u16 d, u8 s)
2769 { return rcl_word_asm(&M.x86.R_EFLG,d,s); }
2771 u32 rcl_long (u32 d, u8 s)
2772 { return rcl_long_asm(&M.x86.R_EFLG,d,s); }
2774 u8 rcr_byte (u8 d, u8 s)
2775 { return rcr_byte_asm(&M.x86.R_EFLG,d,s); }
2777 u16 rcr_word (u16 d, u8 s)
2778 { return rcr_word_asm(&M.x86.R_EFLG,d,s); }
2780 u32 rcr_long (u32 d, u8 s)
2781 { return rcr_long_asm(&M.x86.R_EFLG,d,s); }
2783 u8 rol_byte (u8 d, u8 s)
2784 { return rol_byte_asm(&M.x86.R_EFLG,d,s); }
2786 u16 rol_word (u16 d, u8 s)
2787 { return rol_word_asm(&M.x86.R_EFLG,d,s); }
2789 u32 rol_long (u32 d, u8 s)
2790 { return rol_long_asm(&M.x86.R_EFLG,d,s); }
2792 u8 ror_byte (u8 d, u8 s)
2793 { return ror_byte_asm(&M.x86.R_EFLG,d,s); }
2795 u16 ror_word (u16 d, u8 s)
2796 { return ror_word_asm(&M.x86.R_EFLG,d,s); }
2798 u32 ror_long (u32 d, u8 s)
2799 { return ror_long_asm(&M.x86.R_EFLG,d,s); }
2801 u8 shl_byte (u8 d, u8 s)
2802 { return shl_byte_asm(&M.x86.R_EFLG,d,s); }
2804 u16 shl_word (u16 d, u8 s)
2805 { return shl_word_asm(&M.x86.R_EFLG,d,s); }
2807 u32 shl_long (u32 d, u8 s)
2808 { return shl_long_asm(&M.x86.R_EFLG,d,s); }
2810 u8 shr_byte (u8 d, u8 s)
2811 { return shr_byte_asm(&M.x86.R_EFLG,d,s); }
2813 u16 shr_word (u16 d, u8 s)
2814 { return shr_word_asm(&M.x86.R_EFLG,d,s); }
2816 u32 shr_long (u32 d, u8 s)
2817 { return shr_long_asm(&M.x86.R_EFLG,d,s); }
2819 u8 sar_byte (u8 d, u8 s)
2820 { return sar_byte_asm(&M.x86.R_EFLG,d,s); }
2822 u16 sar_word (u16 d, u8 s)
2823 { return sar_word_asm(&M.x86.R_EFLG,d,s); }
2825 u32 sar_long (u32 d, u8 s)
2826 { return sar_long_asm(&M.x86.R_EFLG,d,s); }
2828 u16 shld_word (u16 d, u16 fill, u8 s)
2829 { return shld_word_asm(&M.x86.R_EFLG,d,fill,s); }
2831 u32 shld_long (u32 d, u32 fill, u8 s)
2832 { return shld_long_asm(&M.x86.R_EFLG,d,fill,s); }
2834 u16 shrd_word (u16 d, u16 fill, u8 s)
2835 { return shrd_word_asm(&M.x86.R_EFLG,d,fill,s); }
2837 u32 shrd_long (u32 d, u32 fill, u8 s)
2838 { return shrd_long_asm(&M.x86.R_EFLG,d,fill,s); }
2840 u8 sbb_byte (u8 d, u8 s)
2841 { return sbb_byte_asm(&M.x86.R_EFLG,d,s); }
2843 u16 sbb_word (u16 d, u16 s)
2844 { return sbb_word_asm(&M.x86.R_EFLG,d,s); }
2846 u32 sbb_long (u32 d, u32 s)
2847 { return sbb_long_asm(&M.x86.R_EFLG,d,s); }
2849 u8 sub_byte (u8 d, u8 s)
2850 { return sub_byte_asm(&M.x86.R_EFLG,d,s); }
2852 u16 sub_word (u16 d, u16 s)
2853 { return sub_word_asm(&M.x86.R_EFLG,d,s); }
2855 u32 sub_long (u32 d, u32 s)
2856 { return sub_long_asm(&M.x86.R_EFLG,d,s); }
2858 void test_byte (u8 d, u8 s)
2859 { test_byte_asm(&M.x86.R_EFLG,d,s); }
2861 void test_word (u16 d, u16 s)
2862 { test_word_asm(&M.x86.R_EFLG,d,s); }
2864 void test_long (u32 d, u32 s)
2865 { test_long_asm(&M.x86.R_EFLG,d,s); }
2867 u8 xor_byte (u8 d, u8 s)
2868 { return xor_byte_asm(&M.x86.R_EFLG,d,s); }
2870 u16 xor_word (u16 d, u16 s)
2871 { return xor_word_asm(&M.x86.R_EFLG,d,s); }
2873 u32 xor_long (u32 d, u32 s)
2874 { return xor_long_asm(&M.x86.R_EFLG,d,s); }
2876 void imul_byte (u8 s)
2877 { imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2879 void imul_word (u16 s)
2880 { imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2882 void imul_long (u32 s)
2883 { imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2885 void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2886 { imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s); }
2888 void mul_byte (u8 s)
2889 { mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2891 void mul_word (u16 s)
2892 { mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2894 void mul_long (u32 s)
2895 { mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2897 void idiv_byte (u8 s)
2898 { idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2900 void idiv_word (u16 s)
2901 { idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2903 void idiv_long (u32 s)
2904 { idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
2906 void div_byte (u8 s)
2907 { div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2909 void div_word (u16 s)
2910 { div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2912 void div_long (u32 s)
2913 { div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
2915 #endif