xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

prim_ops.c (82813B)


      1 /****************************************************************************
      2 *
      3 *						Realmode X86 Emulator Library
      4 *
      5 *            	Copyright (C) 1996-1999 SciTech Software, Inc.
      6 * 				     Copyright (C) David Mosberger-Tang
      7 * 					   Copyright (C) 1999 Egbert Eich
      8 *
      9 *  ========================================================================
     10 *
     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.
     20 *
     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.
     28 *
     29 *  ========================================================================
     30 *
     31 * Language:		ANSI C
     32 * Environment:	Any
     33 * Developer:    Kendall Bennett
     34 *
     35 * Description:  This file contains the code to implement the primitive
     36 *				machine operations used by the emulation code in ops.c
     37 *
     38 * Carry Chain Calculation
     39 *
     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.
     47 *
     48 * So, given the following table, which represents the addition of two
     49 * bits, we can derive a formula for the carry chain.
     50 *
     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
     60 *
     61 * Construction of table for cout:
     62 *
     63 * ab
     64 * r  \  00   01   11  10
     65 * |------------------
     66 * 0  |   0    1    1   1
     67 * 1  |   0    0    1   0
     68 *
     69 * By inspection, one gets:  cc = ab +  r'(a + b)
     70 *
     71 * That represents a lot of operations, but NO CHOICE....
     72 *
     73 * Borrow Chain Calculation.
     74 *
     75 * The following table represents the subtraction of two bits, from
     76 * which we can derive a formula for the borrow chain.
     77 *
     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
     87 *
     88 * Construction of table for cout:
     89 *
     90 * ab
     91 * r  \  00   01   11  10
     92 * |------------------
     93 * 0  |   0    1    0   0
     94 * 1  |   1    1    1   0
     95 *
     96 * By inspection, one gets:  bc = a'b +  r(a' + b)
     97 *
     98 ****************************************************************************/
     99 
    100 #include <stdlib.h>
    101 
    102 #define	PRIM_OPS_NO_REDEFINE_ASM
    103 #include "x86emu/x86emui.h"
    104 
    105 #if defined(__GNUC__)
    106 #if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__)
    107 #include "x86emu/prim_x86_gcc.h"
    108 #endif
    109 #endif
    110 
    111 /*------------------------- Global Variables ------------------------------*/
    112 
    113 static u32 x86emu_parity_tab[8] = {
    114     0x96696996,
    115     0x69969669,
    116     0x69969669,
    117     0x96696996,
    118     0x69969669,
    119     0x96696996,
    120     0x96696996,
    121     0x69969669,
    122 };
    123 
    124 #define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
    125 #define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)
    126 
    127 /*----------------------------- Implementation ----------------------------*/
    128 
    129 /****************************************************************************
    130 REMARKS:
    131 Implements the AAA instruction and side effects.
    132 ****************************************************************************/
    133 u16
    134 aaa_word(u16 d)
    135 {
    136     u16 res;
    137 
    138     if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
    139         d += 0x6;
    140         d += 0x100;
    141         SET_FLAG(F_AF);
    142         SET_FLAG(F_CF);
    143     }
    144     else {
    145         CLEAR_FLAG(F_CF);
    146         CLEAR_FLAG(F_AF);
    147     }
    148     res = (u16) (d & 0xFF0F);
    149     CLEAR_FLAG(F_SF);
    150     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    151     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    152     return res;
    153 }
    154 
    155 /****************************************************************************
    156 REMARKS:
    157 Implements the AAA instruction and side effects.
    158 ****************************************************************************/
    159 u16
    160 aas_word(u16 d)
    161 {
    162     u16 res;
    163 
    164     if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
    165         d -= 0x6;
    166         d -= 0x100;
    167         SET_FLAG(F_AF);
    168         SET_FLAG(F_CF);
    169     }
    170     else {
    171         CLEAR_FLAG(F_CF);
    172         CLEAR_FLAG(F_AF);
    173     }
    174     res = (u16) (d & 0xFF0F);
    175     CLEAR_FLAG(F_SF);
    176     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    177     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    178     return res;
    179 }
    180 
    181 /****************************************************************************
    182 REMARKS:
    183 Implements the AAD instruction and side effects.
    184 ****************************************************************************/
    185 u16
    186 aad_word(u16 d)
    187 {
    188     u16 l;
    189     u8 hb, lb;
    190 
    191     hb = (u8) ((d >> 8) & 0xff);
    192     lb = (u8) ((d & 0xff));
    193     l = (u16) ((lb + 10 * hb) & 0xFF);
    194 
    195     CLEAR_FLAG(F_CF);
    196     CLEAR_FLAG(F_AF);
    197     CLEAR_FLAG(F_OF);
    198     CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
    199     CONDITIONAL_SET_FLAG(l == 0, F_ZF);
    200     CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
    201     return l;
    202 }
    203 
    204 /****************************************************************************
    205 REMARKS:
    206 Implements the AAM instruction and side effects.
    207 ****************************************************************************/
    208 u16
    209 aam_word(u8 d)
    210 {
    211     u16 h, l;
    212 
    213     h = (u16) (d / 10);
    214     l = (u16) (d % 10);
    215     l |= (u16) (h << 8);
    216 
    217     CLEAR_FLAG(F_CF);
    218     CLEAR_FLAG(F_AF);
    219     CLEAR_FLAG(F_OF);
    220     CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
    221     CONDITIONAL_SET_FLAG(l == 0, F_ZF);
    222     CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
    223     return l;
    224 }
    225 
    226 /****************************************************************************
    227 REMARKS:
    228 Implements the ADC instruction and side effects.
    229 ****************************************************************************/
    230 u8
    231 adc_byte(u8 d, u8 s)
    232 {
    233     register u32 res;           /* all operands in native machine order */
    234     register u32 cc;
    235 
    236     if (ACCESS_FLAG(F_CF))
    237         res = 1 + d + s;
    238     else
    239         res = d + s;
    240 
    241     CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
    242     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    243     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    244     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    245 
    246     /* calculate the carry chain  SEE NOTE AT TOP. */
    247     cc = (s & d) | ((~res) & (s | d));
    248     CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
    249     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    250     return (u8) res;
    251 }
    252 
    253 /****************************************************************************
    254 REMARKS:
    255 Implements the ADC instruction and side effects.
    256 ****************************************************************************/
    257 u16
    258 adc_word(u16 d, u16 s)
    259 {
    260     register u32 res;           /* all operands in native machine order */
    261     register u32 cc;
    262 
    263     if (ACCESS_FLAG(F_CF))
    264         res = 1 + d + s;
    265     else
    266         res = d + s;
    267 
    268     CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
    269     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    270     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    271     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    272 
    273     /* calculate the carry chain  SEE NOTE AT TOP. */
    274     cc = (s & d) | ((~res) & (s | d));
    275     CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
    276     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    277     return (u16) res;
    278 }
    279 
    280 /****************************************************************************
    281 REMARKS:
    282 Implements the ADC instruction and side effects.
    283 ****************************************************************************/
    284 u32
    285 adc_long(u32 d, u32 s)
    286 {
    287     register u32 lo;            /* all operands in native machine order */
    288     register u32 hi;
    289     register u32 res;
    290     register u32 cc;
    291 
    292     if (ACCESS_FLAG(F_CF)) {
    293         lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
    294         res = 1 + d + s;
    295     }
    296     else {
    297         lo = (d & 0xFFFF) + (s & 0xFFFF);
    298         res = d + s;
    299     }
    300     hi = (lo >> 16) + (d >> 16) + (s >> 16);
    301 
    302     CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
    303     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    304     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    305     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    306 
    307     /* calculate the carry chain  SEE NOTE AT TOP. */
    308     cc = (s & d) | ((~res) & (s | d));
    309     CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
    310     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    311     return res;
    312 }
    313 
    314 /****************************************************************************
    315 REMARKS:
    316 Implements the ADD instruction and side effects.
    317 ****************************************************************************/
    318 u8
    319 add_byte(u8 d, u8 s)
    320 {
    321     register u32 res;           /* all operands in native machine order */
    322     register u32 cc;
    323 
    324     res = d + s;
    325     CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
    326     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    327     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    328     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    329 
    330     /* calculate the carry chain  SEE NOTE AT TOP. */
    331     cc = (s & d) | ((~res) & (s | d));
    332     CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
    333     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    334     return (u8) res;
    335 }
    336 
    337 /****************************************************************************
    338 REMARKS:
    339 Implements the ADD instruction and side effects.
    340 ****************************************************************************/
    341 u16
    342 add_word(u16 d, u16 s)
    343 {
    344     register u32 res;           /* all operands in native machine order */
    345     register u32 cc;
    346 
    347     res = d + s;
    348     CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
    349     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    350     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    351     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    352 
    353     /* calculate the carry chain  SEE NOTE AT TOP. */
    354     cc = (s & d) | ((~res) & (s | d));
    355     CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
    356     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    357     return (u16) res;
    358 }
    359 
    360 /****************************************************************************
    361 REMARKS:
    362 Implements the ADD instruction and side effects.
    363 ****************************************************************************/
    364 u32
    365 add_long(u32 d, u32 s)
    366 {
    367     register u32 lo;            /* all operands in native machine order */
    368     register u32 hi;
    369     register u32 res;
    370     register u32 cc;
    371 
    372     lo = (d & 0xFFFF) + (s & 0xFFFF);
    373     res = d + s;
    374     hi = (lo >> 16) + (d >> 16) + (s >> 16);
    375 
    376     CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
    377     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    378     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    379     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    380 
    381     /* calculate the carry chain  SEE NOTE AT TOP. */
    382     cc = (s & d) | ((~res) & (s | d));
    383     CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
    384     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    385 
    386     return res;
    387 }
    388 
    389 /****************************************************************************
    390 REMARKS:
    391 Implements the AND instruction and side effects.
    392 ****************************************************************************/
    393 u8
    394 and_byte(u8 d, u8 s)
    395 {
    396     register u8 res;            /* all operands in native machine order */
    397 
    398     res = d & s;
    399 
    400     /* set the flags  */
    401     CLEAR_FLAG(F_OF);
    402     CLEAR_FLAG(F_CF);
    403     CLEAR_FLAG(F_AF);
    404     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    405     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    406     CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
    407     return res;
    408 }
    409 
    410 /****************************************************************************
    411 REMARKS:
    412 Implements the AND instruction and side effects.
    413 ****************************************************************************/
    414 u16
    415 and_word(u16 d, u16 s)
    416 {
    417     register u16 res;           /* all operands in native machine order */
    418 
    419     res = d & s;
    420 
    421     /* set the flags  */
    422     CLEAR_FLAG(F_OF);
    423     CLEAR_FLAG(F_CF);
    424     CLEAR_FLAG(F_AF);
    425     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    426     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    427     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    428     return res;
    429 }
    430 
    431 /****************************************************************************
    432 REMARKS:
    433 Implements the AND instruction and side effects.
    434 ****************************************************************************/
    435 u32
    436 and_long(u32 d, u32 s)
    437 {
    438     register u32 res;           /* all operands in native machine order */
    439 
    440     res = d & s;
    441 
    442     /* set the flags  */
    443     CLEAR_FLAG(F_OF);
    444     CLEAR_FLAG(F_CF);
    445     CLEAR_FLAG(F_AF);
    446     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    447     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    448     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    449     return res;
    450 }
    451 
    452 /****************************************************************************
    453 REMARKS:
    454 Implements the CMP instruction and side effects.
    455 ****************************************************************************/
    456 u8
    457 cmp_byte(u8 d, u8 s)
    458 {
    459     register u32 res;           /* all operands in native machine order */
    460     register u32 bc;
    461 
    462     res = d - s;
    463     CLEAR_FLAG(F_CF);
    464     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    465     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    466     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    467 
    468     /* calculate the borrow chain.  See note at top */
    469     bc = (res & (~d | s)) | (~d & s);
    470     CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
    471     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
    472     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    473     return d;
    474 }
    475 
    476 /****************************************************************************
    477 REMARKS:
    478 Implements the CMP instruction and side effects.
    479 ****************************************************************************/
    480 u16
    481 cmp_word(u16 d, u16 s)
    482 {
    483     register u32 res;           /* all operands in native machine order */
    484     register u32 bc;
    485 
    486     res = d - s;
    487     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    488     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    489     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    490 
    491     /* calculate the borrow chain.  See note at top */
    492     bc = (res & (~d | s)) | (~d & s);
    493     CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
    494     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
    495     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    496     return d;
    497 }
    498 
    499 /****************************************************************************
    500 REMARKS:
    501 Implements the CMP instruction and side effects.
    502 ****************************************************************************/
    503 u32
    504 cmp_long(u32 d, u32 s)
    505 {
    506     register u32 res;           /* all operands in native machine order */
    507     register u32 bc;
    508 
    509     res = d - s;
    510     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    511     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    512     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    513 
    514     /* calculate the borrow chain.  See note at top */
    515     bc = (res & (~d | s)) | (~d & s);
    516     CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
    517     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
    518     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    519     return d;
    520 }
    521 
    522 /****************************************************************************
    523 REMARKS:
    524 Implements the DAA instruction and side effects.
    525 ****************************************************************************/
    526 u8
    527 daa_byte(u8 d)
    528 {
    529     u32 res = d;
    530 
    531     if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
    532         res += 6;
    533         SET_FLAG(F_AF);
    534     }
    535     if (res > 0x9F || ACCESS_FLAG(F_CF)) {
    536         res += 0x60;
    537         SET_FLAG(F_CF);
    538     }
    539     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    540     CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
    541     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    542     return (u8) res;
    543 }
    544 
    545 /****************************************************************************
    546 REMARKS:
    547 Implements the DAS instruction and side effects.
    548 ****************************************************************************/
    549 u8
    550 das_byte(u8 d)
    551 {
    552     if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
    553         d -= 6;
    554         SET_FLAG(F_AF);
    555     }
    556     if (d > 0x9F || ACCESS_FLAG(F_CF)) {
    557         d -= 0x60;
    558         SET_FLAG(F_CF);
    559     }
    560     CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
    561     CONDITIONAL_SET_FLAG(d == 0, F_ZF);
    562     CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
    563     return d;
    564 }
    565 
    566 /****************************************************************************
    567 REMARKS:
    568 Implements the DEC instruction and side effects.
    569 ****************************************************************************/
    570 u8
    571 dec_byte(u8 d)
    572 {
    573     register u32 res;           /* all operands in native machine order */
    574     register u32 bc;
    575 
    576     res = d - 1;
    577     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    578     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    579     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    580 
    581     /* calculate the borrow chain.  See note at top */
    582     /* based on sub_byte, uses s==1.  */
    583     bc = (res & (~d | 1)) | (~d & 1);
    584     /* carry flag unchanged */
    585     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
    586     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    587     return (u8) res;
    588 }
    589 
    590 /****************************************************************************
    591 REMARKS:
    592 Implements the DEC instruction and side effects.
    593 ****************************************************************************/
    594 u16
    595 dec_word(u16 d)
    596 {
    597     register u32 res;           /* all operands in native machine order */
    598     register u32 bc;
    599 
    600     res = d - 1;
    601     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    602     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    603     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    604 
    605     /* calculate the borrow chain.  See note at top */
    606     /* based on the sub_byte routine, with s==1 */
    607     bc = (res & (~d | 1)) | (~d & 1);
    608     /* carry flag unchanged */
    609     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
    610     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    611     return (u16) res;
    612 }
    613 
    614 /****************************************************************************
    615 REMARKS:
    616 Implements the DEC instruction and side effects.
    617 ****************************************************************************/
    618 u32
    619 dec_long(u32 d)
    620 {
    621     register u32 res;           /* all operands in native machine order */
    622     register u32 bc;
    623 
    624     res = d - 1;
    625 
    626     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    627     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    628     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    629 
    630     /* calculate the borrow chain.  See note at top */
    631     bc = (res & (~d | 1)) | (~d & 1);
    632     /* carry flag unchanged */
    633     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
    634     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    635     return res;
    636 }
    637 
    638 /****************************************************************************
    639 REMARKS:
    640 Implements the INC instruction and side effects.
    641 ****************************************************************************/
    642 u8
    643 inc_byte(u8 d)
    644 {
    645     register u32 res;           /* all operands in native machine order */
    646     register u32 cc;
    647 
    648     res = d + 1;
    649     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    650     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    651     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    652 
    653     /* calculate the carry chain  SEE NOTE AT TOP. */
    654     cc = ((1 & d) | (~res)) & (1 | d);
    655     CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
    656     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    657     return (u8) res;
    658 }
    659 
    660 /****************************************************************************
    661 REMARKS:
    662 Implements the INC instruction and side effects.
    663 ****************************************************************************/
    664 u16
    665 inc_word(u16 d)
    666 {
    667     register u32 res;           /* all operands in native machine order */
    668     register u32 cc;
    669 
    670     res = d + 1;
    671     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    672     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    673     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    674 
    675     /* calculate the carry chain  SEE NOTE AT TOP. */
    676     cc = (1 & d) | ((~res) & (1 | d));
    677     CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
    678     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    679     return (u16) res;
    680 }
    681 
    682 /****************************************************************************
    683 REMARKS:
    684 Implements the INC instruction and side effects.
    685 ****************************************************************************/
    686 u32
    687 inc_long(u32 d)
    688 {
    689     register u32 res;           /* all operands in native machine order */
    690     register u32 cc;
    691 
    692     res = d + 1;
    693     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    694     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    695     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    696 
    697     /* calculate the carry chain  SEE NOTE AT TOP. */
    698     cc = (1 & d) | ((~res) & (1 | d));
    699     CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
    700     CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
    701     return res;
    702 }
    703 
    704 /****************************************************************************
    705 REMARKS:
    706 Implements the OR instruction and side effects.
    707 ****************************************************************************/
    708 u8
    709 or_byte(u8 d, u8 s)
    710 {
    711     register u8 res;            /* all operands in native machine order */
    712 
    713     res = d | s;
    714     CLEAR_FLAG(F_OF);
    715     CLEAR_FLAG(F_CF);
    716     CLEAR_FLAG(F_AF);
    717     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    718     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    719     CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
    720     return res;
    721 }
    722 
    723 /****************************************************************************
    724 REMARKS:
    725 Implements the OR instruction and side effects.
    726 ****************************************************************************/
    727 u16
    728 or_word(u16 d, u16 s)
    729 {
    730     register u16 res;           /* all operands in native machine order */
    731 
    732     res = d | s;
    733     /* set the carry flag to be bit 8 */
    734     CLEAR_FLAG(F_OF);
    735     CLEAR_FLAG(F_CF);
    736     CLEAR_FLAG(F_AF);
    737     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    738     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    739     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    740     return res;
    741 }
    742 
    743 /****************************************************************************
    744 REMARKS:
    745 Implements the OR instruction and side effects.
    746 ****************************************************************************/
    747 u32
    748 or_long(u32 d, u32 s)
    749 {
    750     register u32 res;           /* all operands in native machine order */
    751 
    752     res = d | s;
    753 
    754     /* set the carry flag to be bit 8 */
    755     CLEAR_FLAG(F_OF);
    756     CLEAR_FLAG(F_CF);
    757     CLEAR_FLAG(F_AF);
    758     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    759     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
    760     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    761     return res;
    762 }
    763 
    764 /****************************************************************************
    765 REMARKS:
    766 Implements the OR instruction and side effects.
    767 ****************************************************************************/
    768 u8
    769 neg_byte(u8 s)
    770 {
    771     register u8 res;
    772     register u8 bc;
    773 
    774     CONDITIONAL_SET_FLAG(s != 0, F_CF);
    775     res = (u8) - s;
    776     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
    777     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
    778     CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
    779     /* calculate the borrow chain --- modified such that d=0.
    780        substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
    781        (the one used for sub) and simplifying, since ~d=0xff...,
    782        ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
    783        ~d&s == s.  So the simplified result is: */
    784     bc = res | s;
    785     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
    786     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    787     return res;
    788 }
    789 
    790 /****************************************************************************
    791 REMARKS:
    792 Implements the OR instruction and side effects.
    793 ****************************************************************************/
    794 u16
    795 neg_word(u16 s)
    796 {
    797     register u16 res;
    798     register u16 bc;
    799 
    800     CONDITIONAL_SET_FLAG(s != 0, F_CF);
    801     res = (u16) - s;
    802     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
    803     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
    804     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    805 
    806     /* calculate the borrow chain --- modified such that d=0.
    807        substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
    808        (the one used for sub) and simplifying, since ~d=0xff...,
    809        ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
    810        ~d&s == s.  So the simplified result is: */
    811     bc = res | s;
    812     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
    813     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    814     return res;
    815 }
    816 
    817 /****************************************************************************
    818 REMARKS:
    819 Implements the OR instruction and side effects.
    820 ****************************************************************************/
    821 u32
    822 neg_long(u32 s)
    823 {
    824     register u32 res;
    825     register u32 bc;
    826 
    827     CONDITIONAL_SET_FLAG(s != 0, F_CF);
    828     res = (u32) - s;
    829     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
    830     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
    831     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
    832 
    833     /* calculate the borrow chain --- modified such that d=0.
    834        substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
    835        (the one used for sub) and simplifying, since ~d=0xff...,
    836        ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
    837        ~d&s == s.  So the simplified result is: */
    838     bc = res | s;
    839     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
    840     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
    841     return res;
    842 }
    843 
    844 /****************************************************************************
    845 REMARKS:
    846 Implements the NOT instruction and side effects.
    847 ****************************************************************************/
    848 u8
    849 not_byte(u8 s)
    850 {
    851     return ~s;
    852 }
    853 
    854 /****************************************************************************
    855 REMARKS:
    856 Implements the NOT instruction and side effects.
    857 ****************************************************************************/
    858 u16
    859 not_word(u16 s)
    860 {
    861     return ~s;
    862 }
    863 
    864 /****************************************************************************
    865 REMARKS:
    866 Implements the NOT instruction and side effects.
    867 ****************************************************************************/
    868 u32
    869 not_long(u32 s)
    870 {
    871     return ~s;
    872 }
    873 
    874 /****************************************************************************
    875 REMARKS:
    876 Implements the RCL instruction and side effects.
    877 ****************************************************************************/
    878 u8
    879 rcl_byte(u8 d, u8 s)
    880 {
    881     register unsigned int res, cnt, mask, cf;
    882 
    883     /* s is the rotate distance.  It varies from 0 - 8. */
    884     /* have
    885 
    886        CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
    887 
    888        want to rotate through the carry by "s" bits.  We could
    889        loop, but that's inefficient.  So the width is 9,
    890        and we split into three parts:
    891 
    892        The new carry flag   (was B_n)
    893        the stuff in B_n-1 .. B_0
    894        the stuff in B_7 .. B_n+1
    895 
    896        The new rotate is done mod 9, and given this,
    897        for a rotation of n bits (mod 9) the new carry flag is
    898        then located n bits from the MSB.  The low part is
    899        then shifted up cnt bits, and the high part is or'd
    900        in.  Using CAPS for new values, and lowercase for the
    901        original values, this can be expressed as:
    902 
    903        IF n > 0
    904        1) CF <-  b_(8-n)
    905        2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
    906        3) B_(n-1) <- cf
    907        4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
    908      */
    909     res = d;
    910     if ((cnt = s % 9) != 0) {
    911         /* extract the new CARRY FLAG. */
    912         /* CF <-  b_(8-n)             */
    913         cf = (d >> (8 - cnt)) & 0x1;
    914 
    915         /* get the low stuff which rotated
    916            into the range B_7 .. B_cnt */
    917         /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
    918         /* note that the right hand side done by the mask */
    919         res = (d << cnt) & 0xff;
    920 
    921         /* now the high stuff which rotated around
    922            into the positions B_cnt-2 .. B_0 */
    923         /* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
    924         /* shift it downward, 7-(n-2) = 9-n positions.
    925            and mask off the result before or'ing in.
    926          */
    927         mask = (1 << (cnt - 1)) - 1;
    928         res |= (d >> (9 - cnt)) & mask;
    929 
    930         /* if the carry flag was set, or it in.  */
    931         if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
    932             /*  B_(n-1) <- cf */
    933             res |= 1 << (cnt - 1);
    934         }
    935         /* set the new carry flag, based on the variable "cf" */
    936         CONDITIONAL_SET_FLAG(cf, F_CF);
    937         /* OVERFLOW is set *IFF* cnt==1, then it is the
    938            xor of CF and the most significant bit.  Blecck. */
    939         /* parenthesized this expression since it appears to
    940            be causing OF to be misset */
    941         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), F_OF);
    942 
    943     }
    944     return (u8) res;
    945 }
    946 
    947 /****************************************************************************
    948 REMARKS:
    949 Implements the RCL instruction and side effects.
    950 ****************************************************************************/
    951 u16
    952 rcl_word(u16 d, u8 s)
    953 {
    954     register unsigned int res, cnt, mask, cf;
    955 
    956     res = d;
    957     if ((cnt = s % 17) != 0) {
    958         cf = (d >> (16 - cnt)) & 0x1;
    959         res = (d << cnt) & 0xffff;
    960         mask = (1 << (cnt - 1)) - 1;
    961         res |= (d >> (17 - cnt)) & mask;
    962         if (ACCESS_FLAG(F_CF)) {
    963             res |= 1 << (cnt - 1);
    964         }
    965         CONDITIONAL_SET_FLAG(cf, F_CF);
    966         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF);
    967     }
    968     return (u16) res;
    969 }
    970 
    971 /****************************************************************************
    972 REMARKS:
    973 Implements the RCL instruction and side effects.
    974 ****************************************************************************/
    975 u32
    976 rcl_long(u32 d, u8 s)
    977 {
    978     register u32 res, cnt, mask, cf;
    979 
    980     res = d;
    981     if ((cnt = s % 33) != 0) {
    982         cf = (d >> (32 - cnt)) & 0x1;
    983         res = (d << cnt) & 0xffffffff;
    984         mask = (1 << (cnt - 1)) - 1;
    985         res |= (d >> (33 - cnt)) & mask;
    986         if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
    987             res |= 1 << (cnt - 1);
    988         }
    989         CONDITIONAL_SET_FLAG(cf, F_CF);
    990         CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF);
    991     }
    992     return res;
    993 }
    994 
    995 /****************************************************************************
    996 REMARKS:
    997 Implements the RCR instruction and side effects.
    998 ****************************************************************************/
    999 u8
   1000 rcr_byte(u8 d, u8 s)
   1001 {
   1002     u32 res, cnt;
   1003     u32 mask, cf, ocf = 0;
   1004 
   1005     /* rotate right through carry */
   1006     /*
   1007        s is the rotate distance.  It varies from 0 - 8.
   1008        d is the byte object rotated.
   1009 
   1010        have
   1011 
   1012        CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
   1013 
   1014        The new rotate is done mod 9, and given this,
   1015        for a rotation of n bits (mod 9) the new carry flag is
   1016        then located n bits from the LSB.  The low part is
   1017        then shifted up cnt bits, and the high part is or'd
   1018        in.  Using CAPS for new values, and lowercase for the
   1019        original values, this can be expressed as:
   1020 
   1021        IF n > 0
   1022        1) CF <-  b_(n-1)
   1023        2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
   1024        3) B_(8-n) <- cf
   1025        4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0)
   1026      */
   1027     res = d;
   1028     if ((cnt = s % 9) != 0) {
   1029         /* extract the new CARRY FLAG. */
   1030         /* CF <-  b_(n-1)              */
   1031         if (cnt == 1) {
   1032             cf = d & 0x1;
   1033             /* note hackery here.  Access_flag(..) evaluates to either
   1034                0 if flag not set
   1035                non-zero if flag is set.
   1036                doing access_flag(..) != 0 casts that into either
   1037                0..1 in any representation of the flags register
   1038                (i.e. packed bit array or unpacked.)
   1039              */
   1040             ocf = ACCESS_FLAG(F_CF) != 0;
   1041         }
   1042         else
   1043             cf = (d >> (cnt - 1)) & 0x1;
   1044 
   1045         /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
   1046         /* note that the right hand side done by the mask
   1047            This is effectively done by shifting the
   1048            object to the right.  The result must be masked,
   1049            in case the object came in and was treated
   1050            as a negative number.  Needed??? */
   1051 
   1052         mask = (1 << (8 - cnt)) - 1;
   1053         res = (d >> cnt) & mask;
   1054 
   1055         /* now the high stuff which rotated around
   1056            into the positions B_cnt-2 .. B_0 */
   1057         /* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
   1058         /* shift it downward, 7-(n-2) = 9-n positions.
   1059            and mask off the result before or'ing in.
   1060          */
   1061         res |= (d << (9 - cnt));
   1062 
   1063         /* if the carry flag was set, or it in.  */
   1064         if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
   1065             /*  B_(8-n) <- cf */
   1066             res |= 1 << (8 - cnt);
   1067         }
   1068         /* set the new carry flag, based on the variable "cf" */
   1069         CONDITIONAL_SET_FLAG(cf, F_CF);
   1070         /* OVERFLOW is set *IFF* cnt==1, then it is the
   1071            xor of CF and the most significant bit.  Blecck. */
   1072         /* parenthesized... */
   1073         if (cnt == 1) {
   1074             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF);
   1075         }
   1076     }
   1077     return (u8) res;
   1078 }
   1079 
   1080 /****************************************************************************
   1081 REMARKS:
   1082 Implements the RCR instruction and side effects.
   1083 ****************************************************************************/
   1084 u16
   1085 rcr_word(u16 d, u8 s)
   1086 {
   1087     u32 res, cnt;
   1088     u32 mask, cf, ocf = 0;
   1089 
   1090     /* rotate right through carry */
   1091     res = d;
   1092     if ((cnt = s % 17) != 0) {
   1093         if (cnt == 1) {
   1094             cf = d & 0x1;
   1095             ocf = ACCESS_FLAG(F_CF) != 0;
   1096         }
   1097         else
   1098             cf = (d >> (cnt - 1)) & 0x1;
   1099         mask = (1 << (16 - cnt)) - 1;
   1100         res = (d >> cnt) & mask;
   1101         res |= (d << (17 - cnt));
   1102         if (ACCESS_FLAG(F_CF)) {
   1103             res |= 1 << (16 - cnt);
   1104         }
   1105         CONDITIONAL_SET_FLAG(cf, F_CF);
   1106         if (cnt == 1) {
   1107             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF);
   1108         }
   1109     }
   1110     return (u16) res;
   1111 }
   1112 
   1113 /****************************************************************************
   1114 REMARKS:
   1115 Implements the RCR instruction and side effects.
   1116 ****************************************************************************/
   1117 u32
   1118 rcr_long(u32 d, u8 s)
   1119 {
   1120     u32 res, cnt;
   1121     u32 mask, cf, ocf = 0;
   1122 
   1123     /* rotate right through carry */
   1124     res = d;
   1125     if ((cnt = s % 33) != 0) {
   1126         if (cnt == 1) {
   1127             cf = d & 0x1;
   1128             ocf = ACCESS_FLAG(F_CF) != 0;
   1129         }
   1130         else
   1131             cf = (d >> (cnt - 1)) & 0x1;
   1132         mask = (1 << (32 - cnt)) - 1;
   1133         res = (d >> cnt) & mask;
   1134         if (cnt != 1)
   1135             res |= (d << (33 - cnt));
   1136         if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
   1137             res |= 1 << (32 - cnt);
   1138         }
   1139         CONDITIONAL_SET_FLAG(cf, F_CF);
   1140         if (cnt == 1) {
   1141             CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF);
   1142         }
   1143     }
   1144     return res;
   1145 }
   1146 
   1147 /****************************************************************************
   1148 REMARKS:
   1149 Implements the ROL instruction and side effects.
   1150 ****************************************************************************/
   1151 u8
   1152 rol_byte(u8 d, u8 s)
   1153 {
   1154     register unsigned int res, cnt, mask;
   1155 
   1156     /* rotate left */
   1157     /*
   1158        s is the rotate distance.  It varies from 0 - 8.
   1159        d is the byte object rotated.
   1160 
   1161        have
   1162 
   1163        CF  B_7 ... B_0
   1164 
   1165        The new rotate is done mod 8.
   1166        Much simpler than the "rcl" or "rcr" operations.
   1167 
   1168        IF n > 0
   1169        1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0)
   1170        2) B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n)
   1171      */
   1172     res = d;
   1173     if ((cnt = s % 8) != 0) {
   1174         /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
   1175         res = (d << cnt);
   1176 
   1177         /* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
   1178         mask = (1 << cnt) - 1;
   1179         res |= (d >> (8 - cnt)) & mask;
   1180 
   1181         /* set the new carry flag, Note that it is the low order
   1182            bit of the result!!!                               */
   1183         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1184         /* OVERFLOW is set *IFF* s==1, then it is the
   1185            xor of CF and the most significant bit.  Blecck. */
   1186         CONDITIONAL_SET_FLAG(s == 1 &&
   1187                              XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF);
   1188     }
   1189     if (s != 0) {
   1190         /* set the new carry flag, Note that it is the low order
   1191            bit of the result!!!                               */
   1192         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1193     }
   1194     return (u8) res;
   1195 }
   1196 
   1197 /****************************************************************************
   1198 REMARKS:
   1199 Implements the ROL instruction and side effects.
   1200 ****************************************************************************/
   1201 u16
   1202 rol_word(u16 d, u8 s)
   1203 {
   1204     register unsigned int res, cnt, mask;
   1205 
   1206     res = d;
   1207     if ((cnt = s % 16) != 0) {
   1208         res = (d << cnt);
   1209         mask = (1 << cnt) - 1;
   1210         res |= (d >> (16 - cnt)) & mask;
   1211         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1212         CONDITIONAL_SET_FLAG(s == 1 &&
   1213                              XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF);
   1214     }
   1215     if (s != 0) {
   1216         /* set the new carry flag, Note that it is the low order
   1217            bit of the result!!!                               */
   1218         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1219     }
   1220     return (u16) res;
   1221 }
   1222 
   1223 /****************************************************************************
   1224 REMARKS:
   1225 Implements the ROL instruction and side effects.
   1226 ****************************************************************************/
   1227 u32
   1228 rol_long(u32 d, u8 s)
   1229 {
   1230     register u32 res, cnt, mask;
   1231 
   1232     res = d;
   1233     if ((cnt = s % 32) != 0) {
   1234         res = (d << cnt);
   1235         mask = (1 << cnt) - 1;
   1236         res |= (d >> (32 - cnt)) & mask;
   1237         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1238         CONDITIONAL_SET_FLAG(s == 1 &&
   1239                              XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF);
   1240     }
   1241     if (s != 0) {
   1242         /* set the new carry flag, Note that it is the low order
   1243            bit of the result!!!                               */
   1244         CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   1245     }
   1246     return res;
   1247 }
   1248 
   1249 /****************************************************************************
   1250 REMARKS:
   1251 Implements the ROR instruction and side effects.
   1252 ****************************************************************************/
   1253 u8
   1254 ror_byte(u8 d, u8 s)
   1255 {
   1256     register unsigned int res, cnt, mask;
   1257 
   1258     /* rotate right */
   1259     /*
   1260        s is the rotate distance.  It varies from 0 - 8.
   1261        d is the byte object rotated.
   1262 
   1263        have
   1264 
   1265        B_7 ... B_0
   1266 
   1267        The rotate is done mod 8.
   1268 
   1269        IF n > 0
   1270        1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
   1271        2) B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0)
   1272      */
   1273     res = d;
   1274     if ((cnt = s % 8) != 0) {   /* not a typo, do nada if cnt==0 */
   1275         /* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
   1276         res = (d << (8 - cnt));
   1277 
   1278         /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
   1279         mask = (1 << (8 - cnt)) - 1;
   1280         res |= (d >> (cnt)) & mask;
   1281 
   1282         /* set the new carry flag, Note that it is the low order
   1283            bit of the result!!!                               */
   1284         CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
   1285         /* OVERFLOW is set *IFF* s==1, then it is the
   1286            xor of the two most significant bits.  Blecck. */
   1287         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
   1288     }
   1289     else if (s != 0) {
   1290         /* set the new carry flag, Note that it is the low order
   1291            bit of the result!!!                               */
   1292         CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
   1293     }
   1294     return (u8) res;
   1295 }
   1296 
   1297 /****************************************************************************
   1298 REMARKS:
   1299 Implements the ROR instruction and side effects.
   1300 ****************************************************************************/
   1301 u16
   1302 ror_word(u16 d, u8 s)
   1303 {
   1304     register unsigned int res, cnt, mask;
   1305 
   1306     res = d;
   1307     if ((cnt = s % 16) != 0) {
   1308         res = (d << (16 - cnt));
   1309         mask = (1 << (16 - cnt)) - 1;
   1310         res |= (d >> (cnt)) & mask;
   1311         CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
   1312         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
   1313     }
   1314     else if (s != 0) {
   1315         /* set the new carry flag, Note that it is the low order
   1316            bit of the result!!!                               */
   1317         CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
   1318     }
   1319     return (u16) res;
   1320 }
   1321 
   1322 /****************************************************************************
   1323 REMARKS:
   1324 Implements the ROR instruction and side effects.
   1325 ****************************************************************************/
   1326 u32
   1327 ror_long(u32 d, u8 s)
   1328 {
   1329     register u32 res, cnt, mask;
   1330 
   1331     res = d;
   1332     if ((cnt = s % 32) != 0) {
   1333         res = (d << (32 - cnt));
   1334         mask = (1 << (32 - cnt)) - 1;
   1335         res |= (d >> (cnt)) & mask;
   1336         CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
   1337         CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
   1338     }
   1339     else if (s != 0) {
   1340         /* set the new carry flag, Note that it is the low order
   1341            bit of the result!!!                               */
   1342         CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
   1343     }
   1344     return res;
   1345 }
   1346 
   1347 /****************************************************************************
   1348 REMARKS:
   1349 Implements the SHL instruction and side effects.
   1350 ****************************************************************************/
   1351 u8
   1352 shl_byte(u8 d, u8 s)
   1353 {
   1354     unsigned int cnt, res, cf;
   1355 
   1356     if (s < 8) {
   1357         cnt = s % 8;
   1358 
   1359         /* last bit shifted out goes into carry flag */
   1360         if (cnt > 0) {
   1361             res = d << cnt;
   1362             cf = d & (1 << (8 - cnt));
   1363             CONDITIONAL_SET_FLAG(cf, F_CF);
   1364             CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   1365             CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   1366             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1367         }
   1368         else {
   1369             res = (u8) d;
   1370         }
   1371 
   1372         if (cnt == 1) {
   1373             /* Needs simplification. */
   1374             CONDITIONAL_SET_FLAG((((res & 0x80) == 0x80) ^
   1375                                   (ACCESS_FLAG(F_CF) != 0)),
   1376                                  /* was (M.x86.R_FLG&F_CF)==F_CF)), */
   1377                                  F_OF);
   1378         }
   1379         else {
   1380             CLEAR_FLAG(F_OF);
   1381         }
   1382     }
   1383     else {
   1384         res = 0;
   1385         CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
   1386         CLEAR_FLAG(F_OF);
   1387         CLEAR_FLAG(F_SF);
   1388         SET_FLAG(F_PF);
   1389         SET_FLAG(F_ZF);
   1390     }
   1391     return (u8) res;
   1392 }
   1393 
   1394 /****************************************************************************
   1395 REMARKS:
   1396 Implements the SHL instruction and side effects.
   1397 ****************************************************************************/
   1398 u16
   1399 shl_word(u16 d, u8 s)
   1400 {
   1401     unsigned int cnt, res, cf;
   1402 
   1403     if (s < 16) {
   1404         cnt = s % 16;
   1405         if (cnt > 0) {
   1406             res = d << cnt;
   1407             cf = d & (1 << (16 - cnt));
   1408             CONDITIONAL_SET_FLAG(cf, F_CF);
   1409             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1410             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1411             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1412         }
   1413         else {
   1414             res = (u16) d;
   1415         }
   1416 
   1417         if (cnt == 1) {
   1418             CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
   1419                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
   1420         }
   1421         else {
   1422             CLEAR_FLAG(F_OF);
   1423         }
   1424     }
   1425     else {
   1426         res = 0;
   1427         CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
   1428         CLEAR_FLAG(F_OF);
   1429         CLEAR_FLAG(F_SF);
   1430         SET_FLAG(F_PF);
   1431         SET_FLAG(F_ZF);
   1432     }
   1433     return (u16) res;
   1434 }
   1435 
   1436 /****************************************************************************
   1437 REMARKS:
   1438 Implements the SHL instruction and side effects.
   1439 ****************************************************************************/
   1440 u32
   1441 shl_long(u32 d, u8 s)
   1442 {
   1443     unsigned int cnt, res, cf;
   1444 
   1445     if (s < 32) {
   1446         cnt = s % 32;
   1447         if (cnt > 0) {
   1448             res = d << cnt;
   1449             cf = d & (1 << (32 - cnt));
   1450             CONDITIONAL_SET_FLAG(cf, F_CF);
   1451             CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1452             CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1453             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1454         }
   1455         else {
   1456             res = d;
   1457         }
   1458         if (cnt == 1) {
   1459             CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
   1460                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
   1461         }
   1462         else {
   1463             CLEAR_FLAG(F_OF);
   1464         }
   1465     }
   1466     else {
   1467         res = 0;
   1468         CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
   1469         CLEAR_FLAG(F_OF);
   1470         CLEAR_FLAG(F_SF);
   1471         SET_FLAG(F_PF);
   1472         SET_FLAG(F_ZF);
   1473     }
   1474     return res;
   1475 }
   1476 
   1477 /****************************************************************************
   1478 REMARKS:
   1479 Implements the SHR instruction and side effects.
   1480 ****************************************************************************/
   1481 u8
   1482 shr_byte(u8 d, u8 s)
   1483 {
   1484     unsigned int cnt, res, cf;
   1485 
   1486     if (s < 8) {
   1487         cnt = s % 8;
   1488         if (cnt > 0) {
   1489             cf = d & (1 << (cnt - 1));
   1490             res = d >> cnt;
   1491             CONDITIONAL_SET_FLAG(cf, F_CF);
   1492             CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   1493             CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   1494             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1495         }
   1496         else {
   1497             res = (u8) d;
   1498         }
   1499 
   1500         if (cnt == 1) {
   1501             CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
   1502         }
   1503         else {
   1504             CLEAR_FLAG(F_OF);
   1505         }
   1506     }
   1507     else {
   1508         res = 0;
   1509         CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
   1510         CLEAR_FLAG(F_OF);
   1511         CLEAR_FLAG(F_SF);
   1512         SET_FLAG(F_PF);
   1513         SET_FLAG(F_ZF);
   1514     }
   1515     return (u8) res;
   1516 }
   1517 
   1518 /****************************************************************************
   1519 REMARKS:
   1520 Implements the SHR instruction and side effects.
   1521 ****************************************************************************/
   1522 u16
   1523 shr_word(u16 d, u8 s)
   1524 {
   1525     unsigned int cnt, res, cf;
   1526 
   1527     if (s < 16) {
   1528         cnt = s % 16;
   1529         if (cnt > 0) {
   1530             cf = d & (1 << (cnt - 1));
   1531             res = d >> cnt;
   1532             CONDITIONAL_SET_FLAG(cf, F_CF);
   1533             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1534             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1535             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1536         }
   1537         else {
   1538             res = d;
   1539         }
   1540 
   1541         if (cnt == 1) {
   1542             CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
   1543         }
   1544         else {
   1545             CLEAR_FLAG(F_OF);
   1546         }
   1547     }
   1548     else {
   1549         res = 0;
   1550         CLEAR_FLAG(F_CF);
   1551         CLEAR_FLAG(F_OF);
   1552         SET_FLAG(F_ZF);
   1553         CLEAR_FLAG(F_SF);
   1554         CLEAR_FLAG(F_PF);
   1555     }
   1556     return (u16) res;
   1557 }
   1558 
   1559 /****************************************************************************
   1560 REMARKS:
   1561 Implements the SHR instruction and side effects.
   1562 ****************************************************************************/
   1563 u32
   1564 shr_long(u32 d, u8 s)
   1565 {
   1566     unsigned int cnt, res, cf;
   1567 
   1568     if (s < 32) {
   1569         cnt = s % 32;
   1570         if (cnt > 0) {
   1571             cf = d & (1 << (cnt - 1));
   1572             res = d >> cnt;
   1573             CONDITIONAL_SET_FLAG(cf, F_CF);
   1574             CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1575             CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1576             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1577         }
   1578         else {
   1579             res = d;
   1580         }
   1581         if (cnt == 1) {
   1582             CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
   1583         }
   1584         else {
   1585             CLEAR_FLAG(F_OF);
   1586         }
   1587     }
   1588     else {
   1589         res = 0;
   1590         CLEAR_FLAG(F_CF);
   1591         CLEAR_FLAG(F_OF);
   1592         SET_FLAG(F_ZF);
   1593         CLEAR_FLAG(F_SF);
   1594         CLEAR_FLAG(F_PF);
   1595     }
   1596     return res;
   1597 }
   1598 
   1599 /****************************************************************************
   1600 REMARKS:
   1601 Implements the SAR instruction and side effects.
   1602 ****************************************************************************/
   1603 u8
   1604 sar_byte(u8 d, u8 s)
   1605 {
   1606     unsigned int cnt, res, cf, mask, sf;
   1607 
   1608     res = d;
   1609     sf = d & 0x80;
   1610     cnt = s % 8;
   1611     if (cnt > 0 && cnt < 8) {
   1612         mask = (1 << (8 - cnt)) - 1;
   1613         cf = d & (1 << (cnt - 1));
   1614         res = (d >> cnt) & mask;
   1615         CONDITIONAL_SET_FLAG(cf, F_CF);
   1616         if (sf) {
   1617             res |= ~mask;
   1618         }
   1619         CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   1620         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1621         CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   1622     }
   1623     else if (cnt >= 8) {
   1624         if (sf) {
   1625             res = 0xff;
   1626             SET_FLAG(F_CF);
   1627             CLEAR_FLAG(F_ZF);
   1628             SET_FLAG(F_SF);
   1629             SET_FLAG(F_PF);
   1630         }
   1631         else {
   1632             res = 0;
   1633             CLEAR_FLAG(F_CF);
   1634             SET_FLAG(F_ZF);
   1635             CLEAR_FLAG(F_SF);
   1636             CLEAR_FLAG(F_PF);
   1637         }
   1638     }
   1639     return (u8) res;
   1640 }
   1641 
   1642 /****************************************************************************
   1643 REMARKS:
   1644 Implements the SAR instruction and side effects.
   1645 ****************************************************************************/
   1646 u16
   1647 sar_word(u16 d, u8 s)
   1648 {
   1649     unsigned int cnt, res, cf, mask, sf;
   1650 
   1651     sf = d & 0x8000;
   1652     cnt = s % 16;
   1653     res = d;
   1654     if (cnt > 0 && cnt < 16) {
   1655         mask = (1 << (16 - cnt)) - 1;
   1656         cf = d & (1 << (cnt - 1));
   1657         res = (d >> cnt) & mask;
   1658         CONDITIONAL_SET_FLAG(cf, F_CF);
   1659         if (sf) {
   1660             res |= ~mask;
   1661         }
   1662         CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1663         CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1664         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1665     }
   1666     else if (cnt >= 16) {
   1667         if (sf) {
   1668             res = 0xffff;
   1669             SET_FLAG(F_CF);
   1670             CLEAR_FLAG(F_ZF);
   1671             SET_FLAG(F_SF);
   1672             SET_FLAG(F_PF);
   1673         }
   1674         else {
   1675             res = 0;
   1676             CLEAR_FLAG(F_CF);
   1677             SET_FLAG(F_ZF);
   1678             CLEAR_FLAG(F_SF);
   1679             CLEAR_FLAG(F_PF);
   1680         }
   1681     }
   1682     return (u16) res;
   1683 }
   1684 
   1685 /****************************************************************************
   1686 REMARKS:
   1687 Implements the SAR instruction and side effects.
   1688 ****************************************************************************/
   1689 u32
   1690 sar_long(u32 d, u8 s)
   1691 {
   1692     u32 cnt, res, cf, mask, sf;
   1693 
   1694     sf = d & 0x80000000;
   1695     cnt = s % 32;
   1696     res = d;
   1697     if (cnt > 0 && cnt < 32) {
   1698         mask = (1 << (32 - cnt)) - 1;
   1699         cf = d & (1 << (cnt - 1));
   1700         res = (d >> cnt) & mask;
   1701         CONDITIONAL_SET_FLAG(cf, F_CF);
   1702         if (sf) {
   1703             res |= ~mask;
   1704         }
   1705         CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1706         CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1707         CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1708     }
   1709     else if (cnt >= 32) {
   1710         if (sf) {
   1711             res = 0xffffffff;
   1712             SET_FLAG(F_CF);
   1713             CLEAR_FLAG(F_ZF);
   1714             SET_FLAG(F_SF);
   1715             SET_FLAG(F_PF);
   1716         }
   1717         else {
   1718             res = 0;
   1719             CLEAR_FLAG(F_CF);
   1720             SET_FLAG(F_ZF);
   1721             CLEAR_FLAG(F_SF);
   1722             CLEAR_FLAG(F_PF);
   1723         }
   1724     }
   1725     return res;
   1726 }
   1727 
   1728 /****************************************************************************
   1729 REMARKS:
   1730 Implements the SHLD instruction and side effects.
   1731 ****************************************************************************/
   1732 u16
   1733 shld_word(u16 d, u16 fill, u8 s)
   1734 {
   1735     unsigned int cnt, res, cf;
   1736 
   1737     if (s < 16) {
   1738         cnt = s % 16;
   1739         if (cnt > 0) {
   1740             res = (d << cnt) | (fill >> (16 - cnt));
   1741             cf = d & (1 << (16 - cnt));
   1742             CONDITIONAL_SET_FLAG(cf, F_CF);
   1743             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1744             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1745             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1746         }
   1747         else {
   1748             res = d;
   1749         }
   1750         if (cnt == 1) {
   1751             CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
   1752                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
   1753         }
   1754         else {
   1755             CLEAR_FLAG(F_OF);
   1756         }
   1757     }
   1758     else {
   1759         res = 0;
   1760         CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
   1761         CLEAR_FLAG(F_OF);
   1762         CLEAR_FLAG(F_SF);
   1763         SET_FLAG(F_PF);
   1764         SET_FLAG(F_ZF);
   1765     }
   1766     return (u16) res;
   1767 }
   1768 
   1769 /****************************************************************************
   1770 REMARKS:
   1771 Implements the SHLD instruction and side effects.
   1772 ****************************************************************************/
   1773 u32
   1774 shld_long(u32 d, u32 fill, u8 s)
   1775 {
   1776     unsigned int cnt, res, cf;
   1777 
   1778     if (s < 32) {
   1779         cnt = s % 32;
   1780         if (cnt > 0) {
   1781             res = (d << cnt) | (fill >> (32 - cnt));
   1782             cf = d & (1 << (32 - cnt));
   1783             CONDITIONAL_SET_FLAG(cf, F_CF);
   1784             CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1785             CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1786             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1787         }
   1788         else {
   1789             res = d;
   1790         }
   1791         if (cnt == 1) {
   1792             CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
   1793                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
   1794         }
   1795         else {
   1796             CLEAR_FLAG(F_OF);
   1797         }
   1798     }
   1799     else {
   1800         res = 0;
   1801         CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
   1802         CLEAR_FLAG(F_OF);
   1803         CLEAR_FLAG(F_SF);
   1804         SET_FLAG(F_PF);
   1805         SET_FLAG(F_ZF);
   1806     }
   1807     return res;
   1808 }
   1809 
   1810 /****************************************************************************
   1811 REMARKS:
   1812 Implements the SHRD instruction and side effects.
   1813 ****************************************************************************/
   1814 u16
   1815 shrd_word(u16 d, u16 fill, u8 s)
   1816 {
   1817     unsigned int cnt, res, cf;
   1818 
   1819     if (s < 16) {
   1820         cnt = s % 16;
   1821         if (cnt > 0) {
   1822             cf = d & (1 << (cnt - 1));
   1823             res = (d >> cnt) | (fill << (16 - cnt));
   1824             CONDITIONAL_SET_FLAG(cf, F_CF);
   1825             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1826             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1827             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1828         }
   1829         else {
   1830             res = d;
   1831         }
   1832 
   1833         if (cnt == 1) {
   1834             CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
   1835         }
   1836         else {
   1837             CLEAR_FLAG(F_OF);
   1838         }
   1839     }
   1840     else {
   1841         res = 0;
   1842         CLEAR_FLAG(F_CF);
   1843         CLEAR_FLAG(F_OF);
   1844         SET_FLAG(F_ZF);
   1845         CLEAR_FLAG(F_SF);
   1846         CLEAR_FLAG(F_PF);
   1847     }
   1848     return (u16) res;
   1849 }
   1850 
   1851 /****************************************************************************
   1852 REMARKS:
   1853 Implements the SHRD instruction and side effects.
   1854 ****************************************************************************/
   1855 u32
   1856 shrd_long(u32 d, u32 fill, u8 s)
   1857 {
   1858     unsigned int cnt, res, cf;
   1859 
   1860     if (s < 32) {
   1861         cnt = s % 32;
   1862         if (cnt > 0) {
   1863             cf = d & (1 << (cnt - 1));
   1864             res = (d >> cnt) | (fill << (32 - cnt));
   1865             CONDITIONAL_SET_FLAG(cf, F_CF);
   1866             CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1867             CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1868             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1869         }
   1870         else {
   1871             res = d;
   1872         }
   1873         if (cnt == 1) {
   1874             CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
   1875         }
   1876         else {
   1877             CLEAR_FLAG(F_OF);
   1878         }
   1879     }
   1880     else {
   1881         res = 0;
   1882         CLEAR_FLAG(F_CF);
   1883         CLEAR_FLAG(F_OF);
   1884         SET_FLAG(F_ZF);
   1885         CLEAR_FLAG(F_SF);
   1886         CLEAR_FLAG(F_PF);
   1887     }
   1888     return res;
   1889 }
   1890 
   1891 /****************************************************************************
   1892 REMARKS:
   1893 Implements the SBB instruction and side effects.
   1894 ****************************************************************************/
   1895 u8
   1896 sbb_byte(u8 d, u8 s)
   1897 {
   1898     register u32 res;           /* all operands in native machine order */
   1899     register u32 bc;
   1900 
   1901     if (ACCESS_FLAG(F_CF))
   1902         res = d - s - 1;
   1903     else
   1904         res = d - s;
   1905     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   1906     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   1907     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1908 
   1909     /* calculate the borrow chain.  See note at top */
   1910     bc = (res & (~d | s)) | (~d & s);
   1911     CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
   1912     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   1913     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   1914     return (u8) res;
   1915 }
   1916 
   1917 /****************************************************************************
   1918 REMARKS:
   1919 Implements the SBB instruction and side effects.
   1920 ****************************************************************************/
   1921 u16
   1922 sbb_word(u16 d, u16 s)
   1923 {
   1924     register u32 res;           /* all operands in native machine order */
   1925     register u32 bc;
   1926 
   1927     if (ACCESS_FLAG(F_CF))
   1928         res = d - s - 1;
   1929     else
   1930         res = d - s;
   1931     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   1932     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   1933     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1934 
   1935     /* calculate the borrow chain.  See note at top */
   1936     bc = (res & (~d | s)) | (~d & s);
   1937     CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
   1938     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   1939     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   1940     return (u16) res;
   1941 }
   1942 
   1943 /****************************************************************************
   1944 REMARKS:
   1945 Implements the SBB instruction and side effects.
   1946 ****************************************************************************/
   1947 u32
   1948 sbb_long(u32 d, u32 s)
   1949 {
   1950     register u32 res;           /* all operands in native machine order */
   1951     register u32 bc;
   1952 
   1953     if (ACCESS_FLAG(F_CF))
   1954         res = d - s - 1;
   1955     else
   1956         res = d - s;
   1957     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   1958     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   1959     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1960 
   1961     /* calculate the borrow chain.  See note at top */
   1962     bc = (res & (~d | s)) | (~d & s);
   1963     CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
   1964     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   1965     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   1966     return res;
   1967 }
   1968 
   1969 /****************************************************************************
   1970 REMARKS:
   1971 Implements the SUB instruction and side effects.
   1972 ****************************************************************************/
   1973 u8
   1974 sub_byte(u8 d, u8 s)
   1975 {
   1976     register u32 res;           /* all operands in native machine order */
   1977     register u32 bc;
   1978 
   1979     res = d - s;
   1980     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   1981     CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   1982     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   1983 
   1984     /* calculate the borrow chain.  See note at top */
   1985     bc = (res & (~d | s)) | (~d & s);
   1986     CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
   1987     CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   1988     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   1989     return (u8) res;
   1990 }
   1991 
   1992 /****************************************************************************
   1993 REMARKS:
   1994 Implements the SUB instruction and side effects.
   1995 ****************************************************************************/
   1996 u16
   1997 sub_word(u16 d, u16 s)
   1998 {
   1999     register u32 res;           /* all operands in native machine order */
   2000     register u32 bc;
   2001 
   2002     res = d - s;
   2003     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   2004     CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   2005     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2006 
   2007     /* calculate the borrow chain.  See note at top */
   2008     bc = (res & (~d | s)) | (~d & s);
   2009     CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
   2010     CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   2011     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   2012     return (u16) res;
   2013 }
   2014 
   2015 /****************************************************************************
   2016 REMARKS:
   2017 Implements the SUB instruction and side effects.
   2018 ****************************************************************************/
   2019 u32
   2020 sub_long(u32 d, u32 s)
   2021 {
   2022     register u32 res;           /* all operands in native machine order */
   2023     register u32 bc;
   2024 
   2025     res = d - s;
   2026     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   2027     CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   2028     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2029 
   2030     /* calculate the borrow chain.  See note at top */
   2031     bc = (res & (~d | s)) | (~d & s);
   2032     CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
   2033     CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   2034     CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   2035     return res;
   2036 }
   2037 
   2038 /****************************************************************************
   2039 REMARKS:
   2040 Implements the TEST instruction and side effects.
   2041 ****************************************************************************/
   2042 void
   2043 test_byte(u8 d, u8 s)
   2044 {
   2045     register u32 res;           /* all operands in native machine order */
   2046 
   2047     res = d & s;
   2048 
   2049     CLEAR_FLAG(F_OF);
   2050     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   2051     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2052     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2053     /* AF == don't care */
   2054     CLEAR_FLAG(F_CF);
   2055 }
   2056 
   2057 /****************************************************************************
   2058 REMARKS:
   2059 Implements the TEST instruction and side effects.
   2060 ****************************************************************************/
   2061 void
   2062 test_word(u16 d, u16 s)
   2063 {
   2064     register u32 res;           /* all operands in native machine order */
   2065 
   2066     res = d & s;
   2067 
   2068     CLEAR_FLAG(F_OF);
   2069     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   2070     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2071     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2072     /* AF == don't care */
   2073     CLEAR_FLAG(F_CF);
   2074 }
   2075 
   2076 /****************************************************************************
   2077 REMARKS:
   2078 Implements the TEST instruction and side effects.
   2079 ****************************************************************************/
   2080 void
   2081 test_long(u32 d, u32 s)
   2082 {
   2083     register u32 res;           /* all operands in native machine order */
   2084 
   2085     res = d & s;
   2086 
   2087     CLEAR_FLAG(F_OF);
   2088     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   2089     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2090     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2091     /* AF == don't care */
   2092     CLEAR_FLAG(F_CF);
   2093 }
   2094 
   2095 /****************************************************************************
   2096 REMARKS:
   2097 Implements the XOR instruction and side effects.
   2098 ****************************************************************************/
   2099 u8
   2100 xor_byte(u8 d, u8 s)
   2101 {
   2102     register u8 res;            /* all operands in native machine order */
   2103 
   2104     res = d ^ s;
   2105     CLEAR_FLAG(F_OF);
   2106     CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   2107     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2108     CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
   2109     CLEAR_FLAG(F_CF);
   2110     CLEAR_FLAG(F_AF);
   2111     return res;
   2112 }
   2113 
   2114 /****************************************************************************
   2115 REMARKS:
   2116 Implements the XOR instruction and side effects.
   2117 ****************************************************************************/
   2118 u16
   2119 xor_word(u16 d, u16 s)
   2120 {
   2121     register u16 res;           /* all operands in native machine order */
   2122 
   2123     res = d ^ s;
   2124     CLEAR_FLAG(F_OF);
   2125     CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   2126     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2127     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2128     CLEAR_FLAG(F_CF);
   2129     CLEAR_FLAG(F_AF);
   2130     return res;
   2131 }
   2132 
   2133 /****************************************************************************
   2134 REMARKS:
   2135 Implements the XOR instruction and side effects.
   2136 ****************************************************************************/
   2137 u32
   2138 xor_long(u32 d, u32 s)
   2139 {
   2140     register u32 res;           /* all operands in native machine order */
   2141 
   2142     res = d ^ s;
   2143     CLEAR_FLAG(F_OF);
   2144     CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   2145     CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   2146     CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   2147     CLEAR_FLAG(F_CF);
   2148     CLEAR_FLAG(F_AF);
   2149     return res;
   2150 }
   2151 
   2152 /****************************************************************************
   2153 REMARKS:
   2154 Implements the IMUL instruction and side effects.
   2155 ****************************************************************************/
   2156 void
   2157 imul_byte(u8 s)
   2158 {
   2159     s16 res = (s16) ((s8) M.x86.R_AL * (s8) s);
   2160 
   2161     M.x86.R_AX = res;
   2162     if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
   2163         ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
   2164         CLEAR_FLAG(F_CF);
   2165         CLEAR_FLAG(F_OF);
   2166     }
   2167     else {
   2168         SET_FLAG(F_CF);
   2169         SET_FLAG(F_OF);
   2170     }
   2171 }
   2172 
   2173 /****************************************************************************
   2174 REMARKS:
   2175 Implements the IMUL instruction and side effects.
   2176 ****************************************************************************/
   2177 void
   2178 imul_word(u16 s)
   2179 {
   2180     s32 res = (s16) M.x86.R_AX * (s16) s;
   2181 
   2182     M.x86.R_AX = (u16) res;
   2183     M.x86.R_DX = (u16) (res >> 16);
   2184     if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
   2185         ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
   2186         CLEAR_FLAG(F_CF);
   2187         CLEAR_FLAG(F_OF);
   2188     }
   2189     else {
   2190         SET_FLAG(F_CF);
   2191         SET_FLAG(F_OF);
   2192     }
   2193 }
   2194 
   2195 /****************************************************************************
   2196 REMARKS:
   2197 Implements the IMUL instruction and side effects.
   2198 ****************************************************************************/
   2199 void
   2200 imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
   2201 {
   2202 #ifdef	__HAS_LONG_LONG__
   2203     s64 res = (s64) (s32) d * (s32) s;
   2204 
   2205     *res_lo = (u32) res;
   2206     *res_hi = (u32) (res >> 32);
   2207 #else
   2208     u32 d_lo, d_hi, d_sign;
   2209     u32 s_lo, s_hi, s_sign;
   2210     u32 rlo_lo, rlo_hi, rhi_lo;
   2211 
   2212     if ((d_sign = d & 0x80000000) != 0)
   2213         d = -d;
   2214     d_lo = d & 0xFFFF;
   2215     d_hi = d >> 16;
   2216     if ((s_sign = s & 0x80000000) != 0)
   2217         s = -s;
   2218     s_lo = s & 0xFFFF;
   2219     s_hi = s >> 16;
   2220     rlo_lo = d_lo * s_lo;
   2221     rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
   2222     rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
   2223     *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
   2224     *res_hi = rhi_lo;
   2225     if (d_sign != s_sign) {
   2226         d = ~*res_lo;
   2227         s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
   2228         *res_lo = ~*res_lo + 1;
   2229         *res_hi = ~*res_hi + (s >> 16);
   2230     }
   2231 #endif
   2232 }
   2233 
   2234 /****************************************************************************
   2235 REMARKS:
   2236 Implements the IMUL instruction and side effects.
   2237 ****************************************************************************/
   2238 void
   2239 imul_long(u32 s)
   2240 {
   2241     imul_long_direct(&M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
   2242     if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
   2243         ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
   2244         CLEAR_FLAG(F_CF);
   2245         CLEAR_FLAG(F_OF);
   2246     }
   2247     else {
   2248         SET_FLAG(F_CF);
   2249         SET_FLAG(F_OF);
   2250     }
   2251 }
   2252 
   2253 /****************************************************************************
   2254 REMARKS:
   2255 Implements the MUL instruction and side effects.
   2256 ****************************************************************************/
   2257 void
   2258 mul_byte(u8 s)
   2259 {
   2260     u16 res = (u16) (M.x86.R_AL * s);
   2261 
   2262     M.x86.R_AX = res;
   2263     if (M.x86.R_AH == 0) {
   2264         CLEAR_FLAG(F_CF);
   2265         CLEAR_FLAG(F_OF);
   2266     }
   2267     else {
   2268         SET_FLAG(F_CF);
   2269         SET_FLAG(F_OF);
   2270     }
   2271 }
   2272 
   2273 /****************************************************************************
   2274 REMARKS:
   2275 Implements the MUL instruction and side effects.
   2276 ****************************************************************************/
   2277 void
   2278 mul_word(u16 s)
   2279 {
   2280     u32 res = M.x86.R_AX * s;
   2281 
   2282     M.x86.R_AX = (u16) res;
   2283     M.x86.R_DX = (u16) (res >> 16);
   2284     if (M.x86.R_DX == 0) {
   2285         CLEAR_FLAG(F_CF);
   2286         CLEAR_FLAG(F_OF);
   2287     }
   2288     else {
   2289         SET_FLAG(F_CF);
   2290         SET_FLAG(F_OF);
   2291     }
   2292 }
   2293 
   2294 /****************************************************************************
   2295 REMARKS:
   2296 Implements the MUL instruction and side effects.
   2297 ****************************************************************************/
   2298 void
   2299 mul_long(u32 s)
   2300 {
   2301 #ifdef	__HAS_LONG_LONG__
   2302     u64 res = (u64) M.x86.R_EAX * s;
   2303 
   2304     M.x86.R_EAX = (u32) res;
   2305     M.x86.R_EDX = (u32) (res >> 32);
   2306 #else
   2307     u32 a, a_lo, a_hi;
   2308     u32 s_lo, s_hi;
   2309     u32 rlo_lo, rlo_hi, rhi_lo;
   2310 
   2311     a = M.x86.R_EAX;
   2312     a_lo = a & 0xFFFF;
   2313     a_hi = a >> 16;
   2314     s_lo = s & 0xFFFF;
   2315     s_hi = s >> 16;
   2316     rlo_lo = a_lo * s_lo;
   2317     rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
   2318     rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
   2319     M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
   2320     M.x86.R_EDX = rhi_lo;
   2321 #endif
   2322 
   2323     if (M.x86.R_EDX == 0) {
   2324         CLEAR_FLAG(F_CF);
   2325         CLEAR_FLAG(F_OF);
   2326     }
   2327     else {
   2328         SET_FLAG(F_CF);
   2329         SET_FLAG(F_OF);
   2330     }
   2331 }
   2332 
   2333 /****************************************************************************
   2334 REMARKS:
   2335 Implements the IDIV instruction and side effects.
   2336 ****************************************************************************/
   2337 void
   2338 idiv_byte(u8 s)
   2339 {
   2340     s32 dvd, div, mod;
   2341 
   2342     dvd = (s16) M.x86.R_AX;
   2343     if (s == 0) {
   2344         x86emu_intr_raise(0);
   2345         return;
   2346     }
   2347     div = dvd / (s8) s;
   2348     mod = dvd % (s8) s;
   2349     if (abs(div) > 0x7f) {
   2350         x86emu_intr_raise(0);
   2351         return;
   2352     }
   2353     M.x86.R_AL = (s8) div;
   2354     M.x86.R_AH = (s8) mod;
   2355 }
   2356 
   2357 /****************************************************************************
   2358 REMARKS:
   2359 Implements the IDIV instruction and side effects.
   2360 ****************************************************************************/
   2361 void
   2362 idiv_word(u16 s)
   2363 {
   2364     s32 dvd, div, mod;
   2365 
   2366     dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX;
   2367     if (s == 0) {
   2368         x86emu_intr_raise(0);
   2369         return;
   2370     }
   2371     div = dvd / (s16) s;
   2372     mod = dvd % (s16) s;
   2373     if (abs(div) > 0x7fff) {
   2374         x86emu_intr_raise(0);
   2375         return;
   2376     }
   2377     CLEAR_FLAG(F_CF);
   2378     CLEAR_FLAG(F_SF);
   2379     CONDITIONAL_SET_FLAG(div == 0, F_ZF);
   2380     CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   2381 
   2382     M.x86.R_AX = (u16) div;
   2383     M.x86.R_DX = (u16) mod;
   2384 }
   2385 
   2386 /****************************************************************************
   2387 REMARKS:
   2388 Implements the IDIV instruction and side effects.
   2389 ****************************************************************************/
   2390 void
   2391 idiv_long(u32 s)
   2392 {
   2393 #ifdef	__HAS_LONG_LONG__
   2394     s64 dvd, div, mod;
   2395 
   2396     dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
   2397     if (s == 0) {
   2398         x86emu_intr_raise(0);
   2399         return;
   2400     }
   2401     div = dvd / (s32) s;
   2402     mod = dvd % (s32) s;
   2403     if (abs(div) > 0x7fffffff) {
   2404         x86emu_intr_raise(0);
   2405         return;
   2406     }
   2407 #else
   2408     s32 div = 0, mod;
   2409     s32 h_dvd = M.x86.R_EDX;
   2410     u32 l_dvd = M.x86.R_EAX;
   2411     u32 abs_s = s & 0x7FFFFFFF;
   2412     u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
   2413     u32 h_s = abs_s >> 1;
   2414     u32 l_s = abs_s << 31;
   2415     int counter = 31;
   2416     int carry;
   2417 
   2418     if (s == 0) {
   2419         x86emu_intr_raise(0);
   2420         return;
   2421     }
   2422     do {
   2423         div <<= 1;
   2424         carry = (l_dvd >= l_s) ? 0 : 1;
   2425 
   2426         if (abs_h_dvd < (h_s + carry)) {
   2427             h_s >>= 1;
   2428             l_s = abs_s << (--counter);
   2429             continue;
   2430         }
   2431         else {
   2432             abs_h_dvd -= (h_s + carry);
   2433             l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
   2434                 : (l_dvd - l_s);
   2435             h_s >>= 1;
   2436             l_s = abs_s << (--counter);
   2437             div |= 1;
   2438             continue;
   2439         }
   2440 
   2441     } while (counter > -1);
   2442     /* overflow */
   2443     if (abs_h_dvd || (l_dvd > abs_s)) {
   2444         x86emu_intr_raise(0);
   2445         return;
   2446     }
   2447     /* sign */
   2448     div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
   2449     mod = l_dvd;
   2450 
   2451 #endif
   2452     CLEAR_FLAG(F_CF);
   2453     CLEAR_FLAG(F_AF);
   2454     CLEAR_FLAG(F_SF);
   2455     SET_FLAG(F_ZF);
   2456     CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   2457 
   2458     M.x86.R_EAX = (u32) div;
   2459     M.x86.R_EDX = (u32) mod;
   2460 }
   2461 
   2462 /****************************************************************************
   2463 REMARKS:
   2464 Implements the DIV instruction and side effects.
   2465 ****************************************************************************/
   2466 void
   2467 div_byte(u8 s)
   2468 {
   2469     u32 dvd, div, mod;
   2470 
   2471     dvd = M.x86.R_AX;
   2472     if (s == 0) {
   2473         x86emu_intr_raise(0);
   2474         return;
   2475     }
   2476     div = dvd / (u8) s;
   2477     mod = dvd % (u8) s;
   2478     if (abs(div) > 0xff) {
   2479         x86emu_intr_raise(0);
   2480         return;
   2481     }
   2482     M.x86.R_AL = (u8) div;
   2483     M.x86.R_AH = (u8) mod;
   2484 }
   2485 
   2486 /****************************************************************************
   2487 REMARKS:
   2488 Implements the DIV instruction and side effects.
   2489 ****************************************************************************/
   2490 void
   2491 div_word(u16 s)
   2492 {
   2493     u32 dvd, div, mod;
   2494 
   2495     dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX;
   2496     if (s == 0) {
   2497         x86emu_intr_raise(0);
   2498         return;
   2499     }
   2500     div = dvd / (u16) s;
   2501     mod = dvd % (u16) s;
   2502     if (abs(div) > 0xffff) {
   2503         x86emu_intr_raise(0);
   2504         return;
   2505     }
   2506     CLEAR_FLAG(F_CF);
   2507     CLEAR_FLAG(F_SF);
   2508     CONDITIONAL_SET_FLAG(div == 0, F_ZF);
   2509     CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   2510 
   2511     M.x86.R_AX = (u16) div;
   2512     M.x86.R_DX = (u16) mod;
   2513 }
   2514 
   2515 /****************************************************************************
   2516 REMARKS:
   2517 Implements the DIV instruction and side effects.
   2518 ****************************************************************************/
   2519 void
   2520 div_long(u32 s)
   2521 {
   2522 #ifdef	__HAS_LONG_LONG__
   2523     u64 dvd, div, mod;
   2524 
   2525     dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
   2526     if (s == 0) {
   2527         x86emu_intr_raise(0);
   2528         return;
   2529     }
   2530     div = dvd / (u32) s;
   2531     mod = dvd % (u32) s;
   2532     if (abs(div) > 0xffffffff) {
   2533         x86emu_intr_raise(0);
   2534         return;
   2535     }
   2536 #else
   2537     s32 div = 0, mod;
   2538     s32 h_dvd = M.x86.R_EDX;
   2539     u32 l_dvd = M.x86.R_EAX;
   2540 
   2541     u32 h_s = s;
   2542     u32 l_s = 0;
   2543     int counter = 32;
   2544     int carry;
   2545 
   2546     if (s == 0) {
   2547         x86emu_intr_raise(0);
   2548         return;
   2549     }
   2550     do {
   2551         div <<= 1;
   2552         carry = (l_dvd >= l_s) ? 0 : 1;
   2553 
   2554         if (h_dvd < (h_s + carry)) {
   2555             h_s >>= 1;
   2556             l_s = s << (--counter);
   2557             continue;
   2558         }
   2559         else {
   2560             h_dvd -= (h_s + carry);
   2561             l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
   2562                 : (l_dvd - l_s);
   2563             h_s >>= 1;
   2564             l_s = s << (--counter);
   2565             div |= 1;
   2566             continue;
   2567         }
   2568 
   2569     } while (counter > -1);
   2570     /* overflow */
   2571     if (h_dvd || (l_dvd > s)) {
   2572         x86emu_intr_raise(0);
   2573         return;
   2574     }
   2575     mod = l_dvd;
   2576 #endif
   2577     CLEAR_FLAG(F_CF);
   2578     CLEAR_FLAG(F_AF);
   2579     CLEAR_FLAG(F_SF);
   2580     SET_FLAG(F_ZF);
   2581     CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   2582 
   2583     M.x86.R_EAX = (u32) div;
   2584     M.x86.R_EDX = (u32) mod;
   2585 }
   2586 
   2587 /****************************************************************************
   2588 REMARKS:
   2589 Implements the IN string instruction and side effects.
   2590 ****************************************************************************/
   2591 void
   2592 ins(int size)
   2593 {
   2594     int inc = size;
   2595 
   2596     if (ACCESS_FLAG(F_DF)) {
   2597         inc = -size;
   2598     }
   2599     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2600         /* don't care whether REPE or REPNE */
   2601         /* in until CX is ZERO. */
   2602         u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
   2603                      M.x86.R_ECX : M.x86.R_CX);
   2604         switch (size) {
   2605         case 1:
   2606             while (count--) {
   2607                 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
   2608                                     (*sys_inb) (M.x86.R_DX));
   2609                 M.x86.R_DI += inc;
   2610             }
   2611             break;
   2612 
   2613         case 2:
   2614             while (count--) {
   2615                 store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
   2616                                     (*sys_inw) (M.x86.R_DX));
   2617                 M.x86.R_DI += inc;
   2618             }
   2619             break;
   2620         case 4:
   2621             while (count--) {
   2622                 store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
   2623                                     (*sys_inl) (M.x86.R_DX));
   2624                 M.x86.R_DI += inc;
   2625                 break;
   2626             }
   2627         }
   2628         M.x86.R_CX = 0;
   2629         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2630             M.x86.R_ECX = 0;
   2631         }
   2632         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2633     }
   2634     else {
   2635         switch (size) {
   2636         case 1:
   2637             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
   2638                                 (*sys_inb) (M.x86.R_DX));
   2639             break;
   2640         case 2:
   2641             store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
   2642                                 (*sys_inw) (M.x86.R_DX));
   2643             break;
   2644         case 4:
   2645             store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
   2646                                 (*sys_inl) (M.x86.R_DX));
   2647             break;
   2648         }
   2649         M.x86.R_DI += inc;
   2650     }
   2651 }
   2652 
   2653 /****************************************************************************
   2654 REMARKS:
   2655 Implements the OUT string instruction and side effects.
   2656 ****************************************************************************/
   2657 void
   2658 outs(int size)
   2659 {
   2660     int inc = size;
   2661 
   2662     if (ACCESS_FLAG(F_DF)) {
   2663         inc = -size;
   2664     }
   2665     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2666         /* don't care whether REPE or REPNE */
   2667         /* out until CX is ZERO. */
   2668         u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
   2669                      M.x86.R_ECX : M.x86.R_CX);
   2670         switch (size) {
   2671         case 1:
   2672             while (count--) {
   2673                 (*sys_outb) (M.x86.R_DX,
   2674                              fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
   2675                 M.x86.R_SI += inc;
   2676             }
   2677             break;
   2678 
   2679         case 2:
   2680             while (count--) {
   2681                 (*sys_outw) (M.x86.R_DX,
   2682                              fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
   2683                 M.x86.R_SI += inc;
   2684             }
   2685             break;
   2686         case 4:
   2687             while (count--) {
   2688                 (*sys_outl) (M.x86.R_DX,
   2689                              fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
   2690                 M.x86.R_SI += inc;
   2691                 break;
   2692             }
   2693         }
   2694         M.x86.R_CX = 0;
   2695         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2696             M.x86.R_ECX = 0;
   2697         }
   2698         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2699     }
   2700     else {
   2701         switch (size) {
   2702         case 1:
   2703             (*sys_outb) (M.x86.R_DX,
   2704                          fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
   2705             break;
   2706         case 2:
   2707             (*sys_outw) (M.x86.R_DX,
   2708                          fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
   2709             break;
   2710         case 4:
   2711             (*sys_outl) (M.x86.R_DX,
   2712                          fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
   2713             break;
   2714         }
   2715         M.x86.R_SI += inc;
   2716     }
   2717 }
   2718 
   2719 /****************************************************************************
   2720 PARAMETERS:
   2721 addr	- Address to fetch word from
   2722 
   2723 REMARKS:
   2724 Fetches a word from emulator memory using an absolute address.
   2725 ****************************************************************************/
   2726 u16
   2727 mem_access_word(int addr)
   2728 {
   2729     DB(if (CHECK_MEM_ACCESS())
   2730        x86emu_check_mem_access(addr);)
   2731         return (*sys_rdw) (addr);
   2732 }
   2733 
   2734 /****************************************************************************
   2735 REMARKS:
   2736 Pushes a word onto the stack.
   2737 
   2738 NOTE: Do not inline this, as (*sys_wrX) is already inline!
   2739 ****************************************************************************/
   2740 void
   2741 push_word(u16 w)
   2742 {
   2743     DB(if (CHECK_SP_ACCESS())
   2744        x86emu_check_sp_access();)
   2745         M.x86.R_SP -= 2;
   2746     (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
   2747 }
   2748 
   2749 /****************************************************************************
   2750 REMARKS:
   2751 Pushes a long onto the stack.
   2752 
   2753 NOTE: Do not inline this, as (*sys_wrX) is already inline!
   2754 ****************************************************************************/
   2755 void
   2756 push_long(u32 w)
   2757 {
   2758     DB(if (CHECK_SP_ACCESS())
   2759        x86emu_check_sp_access();)
   2760         M.x86.R_SP -= 4;
   2761     (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
   2762 }
   2763 
   2764 /****************************************************************************
   2765 REMARKS:
   2766 Pops a word from the stack.
   2767 
   2768 NOTE: Do not inline this, as (*sys_rdX) is already inline!
   2769 ****************************************************************************/
   2770 u16
   2771 pop_word(void)
   2772 {
   2773     register u16 res;
   2774 
   2775     DB(if (CHECK_SP_ACCESS())
   2776        x86emu_check_sp_access();)
   2777         res = (*sys_rdw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
   2778     M.x86.R_SP += 2;
   2779     return res;
   2780 }
   2781 
   2782 /****************************************************************************
   2783 REMARKS:
   2784 Pops a long from the stack.
   2785 
   2786 NOTE: Do not inline this, as (*sys_rdX) is already inline!
   2787 ****************************************************************************/
   2788 u32
   2789 pop_long(void)
   2790 {
   2791     register u32 res;
   2792 
   2793     DB(if (CHECK_SP_ACCESS())
   2794        x86emu_check_sp_access();)
   2795         res = (*sys_rdl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
   2796     M.x86.R_SP += 4;
   2797     return res;
   2798 }
   2799 
   2800 /****************************************************************************
   2801 REMARKS:
   2802 CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
   2803 ****************************************************************************/
   2804 void
   2805 cpuid(void)
   2806 {
   2807     u32 feature = M.x86.R_EAX;
   2808 
   2809 #ifdef X86EMU_HAS_HW_CPUID
   2810     /* If the platform allows it, we will base our values on the real
   2811      * results from the CPUID instruction.  We limit support to the
   2812      * first two features, and the results of those are sanitized.
   2813      */
   2814     if (feature <= 1)
   2815         hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX);
   2816 #endif
   2817 
   2818     switch (feature) {
   2819     case 0:
   2820         /* Regardless if we have real data from the hardware, the emulator
   2821          * will only support up to feature 1, which we set in register EAX.
   2822          * Registers EBX:EDX:ECX contain a string identifying the CPU.
   2823          */
   2824         M.x86.R_EAX = 1;
   2825 #ifndef X86EMU_HAS_HW_CPUID
   2826         /* EBX:EDX:ECX = "GenuineIntel" */
   2827         M.x86.R_EBX = 0x756e6547;
   2828         M.x86.R_EDX = 0x49656e69;
   2829         M.x86.R_ECX = 0x6c65746e;
   2830 #endif
   2831         break;
   2832     case 1:
   2833 #ifndef X86EMU_HAS_HW_CPUID
   2834         /* If we don't have x86 compatible hardware, we return values from an
   2835          * Intel 486dx4; which was one of the first processors to have CPUID.
   2836          */
   2837         M.x86.R_EAX = 0x00000480;
   2838         M.x86.R_EBX = 0x00000000;
   2839         M.x86.R_ECX = 0x00000000;
   2840         M.x86.R_EDX = 0x00000002;       /* VME */
   2841 #else
   2842         /* In the case that we have hardware CPUID instruction, we make sure
   2843          * that the features reported are limited to TSC and VME.
   2844          */
   2845         M.x86.R_EDX &= 0x00000012;
   2846 #endif
   2847         break;
   2848     default:
   2849         /* Finally, we don't support any additional features.  Most CPUs
   2850          * return all zeros when queried for invalid or unsupported feature
   2851          * numbers.
   2852          */
   2853         M.x86.R_EAX = 0;
   2854         M.x86.R_EBX = 0;
   2855         M.x86.R_ECX = 0;
   2856         M.x86.R_EDX = 0;
   2857         break;
   2858     }
   2859 }