/*
Copyright Notice
================
BOCHS is Copyright 1994 by Kevin P. Lawton.

BOCHS is shareware for PERSONAL USE only.

For more information, read the file 'LICENSE' included in the bochs
distribution.  If you don't have access to this file, or have questions
regarding the licensing policy, the author may be contacted via:

    US Mail:  Kevin Lawton
              528 Lexington St.
              Waltham, MA 02154

    EMail:    bochs@tiac.net
*/





#include "bx_bochs.h"




  void
bx_XOR_EbGb()
{
  Bit8u op2, op1, result;
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  /* op2 is a register, op2_addr is an index of a register */
  BX_READ_8BIT_REG(op2, op2_addr);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 ^ op2;

  /* set EFLAGS:
   * XOR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}

  void
bx_XOR_EvGv()
{
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u result_b15;



  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op2_32 is a register, op2_addr is an index of a register */
    BX_READ_32BIT_REG(op2_32, op2_addr);

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 ^ op2_32;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    /* op2_16 is a register, op2_addr is an index of a register */
    BX_READ_16BIT_REG(op2_16, op2_addr);

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 ^ op2_16;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_XOR_GbEb()
{
  Bit8u op1, op2, result;
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  /* op1 is a register, op1_addr is an index of a register */
  BX_READ_8BIT_REG(op1, op1_addr);

  /* op2 is a register or memory reference */
  if (op2_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op2, op2_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op2_seg_reg, op2_addr, 1, BX_READ, &op2);

  result = op1 ^ op2;

  /* set eflags:
   * XOR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination, which is a register */
  BX_WRITE_8BIT_REG(op1_addr, result);
}

  void
bx_XOR_GvEv()
{
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u result_b31;
  Bit32u op1_32, op2_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, result_16;
  Bit16u result_b15;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1_32 is a register, op1_addr is an index of a register */
    BX_READ_32BIT_REG(op1_32, op1_addr);

    /* op2_32 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op2_32, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 4, BX_READ, &op2_32);

    result_32 = op1_32 ^ op2_32;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b31 = result_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_32BIT_REG(op1_addr, result_32);
    }
  else { /* 16 bit operand size mode */

    /* op1_16 is a register, op1_addr is an index of a register */
    BX_READ_16BIT_REG(op1_16, op1_addr);

    /* op2_16 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op2_16, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 2, BX_READ, &op2_16);

    result_16 = op1_16 ^ op2_16;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b15 = result_16 & 0x8000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_16BIT_REG(op1_addr, result_16);
    }
}

  void
bx_XOR_ALIb()
{
  Bit8u op1, op2, sum;
  Bit8u sum_b7;


  op1 = AL;

  op2 = bx_fetch_next_byte();

  sum = op1 ^ op2;

  /* set eflags:
   * XOR affects the following flags: O,S,Z,P,C
   */
  sum_b7 = sum & 0x80;


  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (sum_b7 != 0);
  bx_cpu.eflags.zf = (sum == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[sum];

  /* now write sum back to destination, which is a register */
  AL = sum;
}

  void
bx_XOR_eAXIv()
{
  /* for 32 bit operand size mode */
  Bit32u sum_b31;
  Bit32u op1_32, op2_32, sum_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, sum_16;
  Bit16u sum_b15;


  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op1_32 = EAX;

    op2_32 = bx_fetch_next_dword();

    sum_32 = op1_32 ^ op2_32;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    sum_b31 = sum_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b31 != 0);
    bx_cpu.eflags.zf = (sum_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_32 & 0xFF];

    /* now write sum back to destination */

    EAX = sum_32;
    }
  else { /* 16 bit operand size mode */
    op1_16 = AX;

    op2_16 = bx_fetch_next_word();

    sum_16 = op1_16 ^ op2_16;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    sum_b15 = sum_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b15 != 0);
    bx_cpu.eflags.zf = (sum_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_16 & 0xFF];

    /* now write sum back to destination */

    AX = sum_16;
    }
}

  void
bx_XOR_EbIb()
{
  Bit8u op2, op1, result;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2 = bx_fetch_next_byte();

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 ^ op2;

  /* set eflags:
   * XOR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}

  void
bx_XOR_EvIv()
{
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u result_b15;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_dword();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 ^ op2_32;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_word();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 ^ op2_16;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_XOR_EvIb()
{
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u result_b15;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_byte();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 ^ op2_32;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_byte();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 ^ op2_16;

    /* set eflags:
     * XOR affects the following flags: O,S,Z,P,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}


void bx_SHLD_EvGvIb() {bx_invalid_instruction();}
void bx_SHLD_EvGvCL() {bx_invalid_instruction();}
void bx_SHRD_EvGvIb() {bx_invalid_instruction();}
void bx_SHRD_EvGvCL() {bx_invalid_instruction();}


  void
bx_OR_EvIv()
{
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_dword();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 | op2_32;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_word();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 | op2_16;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_OR_EvIb()
{
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_byte();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 | op2_32;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_byte();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 | op2_16;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_OR_EbIb()
{
  Bit8u op2, op1, result;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2 = bx_fetch_next_byte();

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 | op2;

  /* set eflags:
   * OR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}




  void
bx_ROL_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 %= 8;  /* use only 3 LSB's */

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 << op2_8) | (op1_8 >> (8 - op2_8));

  /* set eflags:
   * ROL affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;

  bx_cpu.eflags.cf = result_8 & 0x01;
  bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b7?1:0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROL_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15;
  Bit32u op1_32, result_32, result_b31;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 %= 32;  /* use only 5 LSB's */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 << op2_8) | (op1_32 >> (32 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.cf = result_32 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b31?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 %= 16;  /* use only 4 LSB's */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 << op2_8) | (op1_16 >> (16 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.cf = result_16 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b15?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_ROL_Eb1()
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);


  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 << 1) | (op1_8 >> 7);

  /* set eflags:
   * ROL affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;

  bx_cpu.eflags.cf = result_8 & 0x01;
  bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b7?1:0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROL_Ev1()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15;
  Bit32u op1_32, result_32, result_b31;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = 1;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 << op2_8) | (op1_32 >> (32 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.cf = result_32 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b31?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 << op2_8) | (op1_16 >> (16 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.cf = result_16 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b15?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_ROL_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 %= 8;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 << op2_8) | (op1_8 >> (8 - op2_8));

  /* set eflags:
   * ROL affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;

  bx_cpu.eflags.cf = result_8 & 0x01;
  bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b7?1:0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROL_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15;
  Bit32u op1_32, result_32, result_b31;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 %= 32;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 << op2_8) | (op1_32 >> (32 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.cf = result_32 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b31?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 %= 16;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 << op2_8) | (op1_16 >> (16 - op2_8));

    /* set eflags:
     * ROL affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.cf = result_16 & 0x01;
    bx_cpu.eflags.of = bx_cpu.eflags.cf ^ (result_b15?1:0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_ROR_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7, result_b6;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 %= 8;  /* use only 3 LSB's */

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> op2_8) | (op1_8 << (8 - op2_8));

  /* set eflags:
   * ROL affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;
  result_b6 = result_8 & 0x40;

  bx_cpu.eflags.of = (result_b7 != 0) ^ (result_b6 != 0);
  bx_cpu.eflags.cf = (result_b7 != 0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROR_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15, result_b14;
  Bit32u op1_32, result_32, result_b31, result_b30;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 %= 32;  /* use only 5 LSB's */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> op2_8) | (op1_32 << (32 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;
    result_b30 = result_32 & 0x40000000;

    bx_cpu.eflags.of = (result_b31 != 0) ^ (result_b30 != 0);
    bx_cpu.eflags.cf = (result_b31 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 %= 16;  /* use only 4 LSB's */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> op2_8) | (op1_16 << (16 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;
    result_b14 = result_16 & 0x4000;

    bx_cpu.eflags.of = (result_b15 != 0) ^ (result_b14 != 0);
    bx_cpu.eflags.cf = (result_b15 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_ROR_Eb1()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7, result_b6;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = 1;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> op2_8) | (op1_8 << (8 - op2_8));

  /* set eflags:
   * ROR affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;
  result_b6 = result_8 & 0x40;

  bx_cpu.eflags.of = (result_b7 != 0) ^ (result_b6 != 0);
  bx_cpu.eflags.cf = (result_b7 != 0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROR_Ev1()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15, result_b14;
  Bit32u op1_32, result_32, result_b31, result_b30;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = 1;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> op2_8) | (op1_32 << (32 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;
    result_b30 = result_32 & 0x40000000;

    bx_cpu.eflags.of = (result_b31 != 0) ^ (result_b30 != 0);
    bx_cpu.eflags.cf = (result_b31 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> op2_8) | (op1_16 << (16 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;
    result_b14 = result_16 & 0x4000;

    bx_cpu.eflags.of = (result_b15 != 0) ^ (result_b14 != 0);
    bx_cpu.eflags.cf = (result_b15 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_ROR_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7, result_b6;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 %= 8;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> op2_8) | (op1_8 << (8 - op2_8));

  /* set eflags:
   * ROR affects the following flags: O,C
   */
  result_b7 = result_8 & 0x80;
  result_b6 = result_8 & 0x40;

  bx_cpu.eflags.of = (result_b7 != 0) ^ (result_b6 != 0);
  bx_cpu.eflags.cf = (result_b7 != 0);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_ROR_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16, result_b15, result_b14;
  Bit32u op1_32, result_32, result_b31, result_b30;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 %= 32;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> op2_8) | (op1_32 << (32 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b31 = result_32 & 0x80000000;
    result_b30 = result_32 & 0x40000000;

    bx_cpu.eflags.of = (result_b31 != 0) ^ (result_b30 != 0);
    bx_cpu.eflags.cf = (result_b31 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 %= 16;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> op2_8) | (op1_16 << (16 - op2_8));

    /* set eflags:
     * ROR affects the following flags: O,C
     */
    result_b15 = result_16 & 0x8000;
    result_b14 = result_16 & 0x4000;

    bx_cpu.eflags.of = (result_b15 != 0) ^ (result_b14 != 0);
    bx_cpu.eflags.cf = (result_b15 != 0);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_RCL_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 = ( op2_8 & 0x1F ) % 9;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8) {
    result_8 = (op1_8 << op2_8) |
             (bx_cpu.eflags.cf << (op2_8 - 1)) |
             (op1_8 >> (9 - op2_8));

    /* set eflags:
     * RCL affects the following flags: O,C
     */

    bx_cpu.eflags.cf = (op1_8 >> (8 - op2_8)) & 0x01;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_RCL_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 = op2_8 & 0x1F;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8) {
      result_32 = (op1_32 << op2_8) |
                (bx_cpu.eflags.cf << (op2_8 - 1)) |
                (op1_32 >> (33 - op2_8));

      /* set eflags:
       * RCL affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_32 >> (32 - op2_8)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 = (op2_8 & 0x1F) % 17;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8) {
      result_16 = (op1_16 << op2_8) |
		(bx_cpu.eflags.cf << (op2_8 - 1)) |
		(op1_16 >> (17 - op2_8));

      /* set eflags:
       * RCL affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_16 >> (16 - op2_8)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_RCL_Eb1() 
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 << 1) | bx_cpu.eflags.cf;

  /* set eflags:
   * RCL affects the following flags: O,C
   */

  bx_cpu.eflags.cf = (op1_8 >> 7);
  bx_cpu.eflags.of = (result_8 >> 7) ^ bx_cpu.eflags.cf;

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}


  void
bx_RCL_Ev1() 
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 << 1) | bx_cpu.eflags.cf;

    /* set eflags:
     * RCL affects the following flags: O,C
     */

    bx_cpu.eflags.cf = op1_32 >> 31;
    bx_cpu.eflags.of = (result_32 >> 31) ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 << 1) | bx_cpu.eflags.cf;

    /* set eflags:
     * RCL affects the following flags: O,C
     */

    bx_cpu.eflags.cf = op1_16 >> 15;
    bx_cpu.eflags.of = (result_16 >> 15) ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}


  void
bx_RCL_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 = ( op2_8 & 0x1F ) % 9;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8) {
    result_8 = (op1_8 << op2_8) |
             (bx_cpu.eflags.cf << (op2_8 - 1)) |
             (op1_8 >> (9 - op2_8));

    /* set eflags:
     * RCL affects the following flags: O,C
     */

    bx_cpu.eflags.cf = (op1_8 >> (8 - op2_8)) & 0x01;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_RCL_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 = op2_8 & 0x1F;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8) {
      result_32 = (op1_32 << op2_8) |
                (bx_cpu.eflags.cf << (op2_8 - 1)) |
                (op1_32 >> (33 - op2_8));

      /* set eflags:
       * RCL affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_32 >> (32 - op2_8)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 = (op2_8 & 0x1F) % 17;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8) {
      result_16 = (op1_16 << op2_8) |
		(bx_cpu.eflags.cf << (op2_8 - 1)) |
		(op1_16 >> (17 - op2_8));

      /* set eflags:
       * RCL affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_16 >> (16 - op2_8)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}


  void
bx_RCR_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 = ( op2_8 & 0x1F ) % 9;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8) {
    result_8 = (op1_8 >> op2_8) |
             (bx_cpu.eflags.cf << (8 - op2_8)) |
             (op1_8 << (9 - op2_8));

    /* set eflags:
     * RCR affects the following flags: O,C
     */

    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_RCR_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 = op2_8 & 0x1F;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8) {
      result_32 = (op1_32 >> op2_8) |
                (bx_cpu.eflags.cf << (32 - op2_8)) |
                (op1_32 << (33 - op2_8));

      /* set eflags:
       * RCR affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 = (op2_8 & 0x1F) % 17;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8) {
      result_16 = (op1_16 >> op2_8) |
		(bx_cpu.eflags.cf << (16 - op2_8)) |
		(op1_16 << (17 - op2_8));

      /* set eflags:
       * RCR affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_RCR_Eb1()
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> 1) | (bx_cpu.eflags.cf << 7);

  /* set eflags:
   * RCR affects the following flags: O,C
   */

  bx_cpu.eflags.of = (op1_8 >> 7) ^ bx_cpu.eflags.cf;
  bx_cpu.eflags.cf = (op1_8 & 0x01);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_RCR_Ev1()
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> 1) | (bx_cpu.eflags.cf << 31);

    /* set eflags:
     * RCR affects the following flags: O,C
     */

    bx_cpu.eflags.of = (op1_32 >> 31) ^ bx_cpu.eflags.cf;
    bx_cpu.eflags.cf = (op1_32 & 0x01);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

      result_16 = (op1_16 >> 1) | (bx_cpu.eflags.cf << 15);

      /* set eflags:
       * RCR affects the following flags: O,C
       */

      bx_cpu.eflags.of = (result_16 >> 15) ^ bx_cpu.eflags.cf;
      bx_cpu.eflags.cf = (op1_16 & 0x01);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_RCR_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 = ( op2_8 & 0x1F ) % 9;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8) {
    result_8 = (op1_8 >> op2_8) |
             (bx_cpu.eflags.cf << (8 - op2_8)) |
             (op1_8 << (9 - op2_8));

    /* set eflags:
     * RCR affects the following flags: O,C
     */

    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_RCR_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;

  if (bx_32bit_opsize) { /* 32 bit operand size mode */
    op2_8 = op2_8 & 0x1F;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8) {
      result_32 = (op1_32 >> op2_8) |
                (bx_cpu.eflags.cf << (32 - op2_8)) |
                (op1_32 << (33 - op2_8));

      /* set eflags:
       * RCR affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */
    op2_8 = (op2_8 & 0x1F) % 17;

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8) {
      result_16 = (op1_16 >> op2_8) |
		(bx_cpu.eflags.cf << (16 - op2_8)) |
		(op1_16 << (17 - op2_8));

      /* set eflags:
       * RCR affects the following flags: O,C
       */

      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SHL_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte() & 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  /* set eflags:
   * SHL affects the following flags: O,S,Z,P,C
   */

  if (op2_8 < 8) {
    bx_cpu.eflags.cf = (op1_8 >> (8 - op2_8)) & 0x01;
    result_8 = (op1_8 << op2_8);
    }
  else {
    bx_cpu.eflags.cf = 0;
    result_8 = 0;
    }

  bx_cpu.eflags.zf = (result_8 == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result_8];
  bx_cpu.eflags.sf = (result_8 >> 7);
  bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SHL_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte() & 0x1F; /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */

    if (op2_8 < 32) {
      bx_cpu.eflags.cf = (op1_32 >> (32 - op2_8)) & 0x01;
      result_32 = (op1_32 << op2_8);
      }
    else {
      bx_cpu.eflags.cf = 0;
      result_32 = 0;
      }

    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
    bx_cpu.eflags.sf = (result_32 >> 31);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */
    if (op2_8 < 16) {
      bx_cpu.eflags.cf = (op1_16 >> (16 - op2_8)) & 0x01;
      result_16 = (op1_16 << op2_8);
      }
    else {
      bx_cpu.eflags.cf = 0;
      result_16 = 0;
      }

    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
    bx_cpu.eflags.sf = (result_16 >> 15);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SHL_Eb1() 
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 << 1);

  /* set eflags:
   * SHL affects the following flags: O,S,Z,P,C
   */

  bx_cpu.eflags.cf = (op1_8 >> 7);

  bx_cpu.eflags.zf = (result_8 == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result_8];
  bx_cpu.eflags.sf = (result_8 >> 7);
  bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;


  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SHL_Ev1() 
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 << 1);

    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_32 >> 31);

    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
    bx_cpu.eflags.sf = (result_32 >> 31);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 << 1);

    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_16 >> 15);

    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
    bx_cpu.eflags.sf = (result_16 >> 15);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SHL_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL & 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8 < 8) {
    bx_cpu.eflags.cf = (op1_8 >> (8 - op2_8)) & 0x01;
    result_8 = (op1_8 << op2_8);
    }
  else {
    bx_cpu.eflags.cf = 0;
    result_8 = 0;
    }

  /* set eflags:
   * SHL affects the following flags: O,S,Z,P,Z
   */
  bx_cpu.eflags.zf = (result_8 == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result_8];
  bx_cpu.eflags.sf = (result_8 >> 7);
  bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SHL_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL & 0x1F; /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */

    if (op2_8 < 32) {
      bx_cpu.eflags.cf = (op1_32 >> (32 - op2_8)) & 0x01;
      result_32 = (op1_32 << op2_8);
      }
    else {
      bx_cpu.eflags.cf = 0;
      result_32 = 0;
      }

    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
    bx_cpu.eflags.sf = (result_32 >> 31);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);


    /* set eflags:
     * SHL affects the following flags: O,S,Z,P,C
     */

    if (op2_8 < 16) {
      bx_cpu.eflags.cf = (op1_16 >> (16 - op2_8)) & 0x01;
      result_16 = (op1_16 << op2_8);
      }
    else {
      bx_cpu.eflags.cf = 0;
      result_16 = 0;
      }

    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
    bx_cpu.eflags.sf = (result_16 >> 15);
    bx_cpu.eflags.of = bx_cpu.eflags.sf ^ bx_cpu.eflags.cf;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}


  void
bx_SHR_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 &= 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> op2_8);

  /* set eflags:
   * SHR affects the following flags: O,S,Z,P,C
   */

  if (op2_8) {
    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    bx_cpu.eflags.zf = (result_8 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_8];
    bx_cpu.eflags.sf = (result_8 >> 7);
    /* OF really only defined if op2 == 1 */
    bx_cpu.eflags.of = ((result_8 >> 6) & 0x01) != bx_cpu.eflags.sf;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}


  void
bx_SHR_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte() & 0x1F; /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> op2_8);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_32 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
      bx_cpu.eflags.sf = (result_32 >> 31);
      /* OF really only defined if op2 == 1 */
      bx_cpu.eflags.of = ((result_32 >> 30) & 0x01) != bx_cpu.eflags.sf;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> op2_8);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_16 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
      bx_cpu.eflags.sf = (result_16 >> 15);
      /* OF really only defined if op2 == 1 */
      bx_cpu.eflags.of = ((result_16 >> 14) & 0x01) != bx_cpu.eflags.sf;
      }


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SHR_Eb1() 
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> 1);

  /* set eflags:
   * SHR affects the following flags: O,S,Z,P,C
   */

  bx_cpu.eflags.cf = (op1_8 & 0x01);
  bx_cpu.eflags.zf = (result_8 == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result_8];
  bx_cpu.eflags.sf = (result_8 >> 7);
  bx_cpu.eflags.of = ((result_8 >> 6) & 0x01) != bx_cpu.eflags.sf;


  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SHR_Ev1() 
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);


  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> 1);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_32 & 0x01);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
    bx_cpu.eflags.sf = (result_32 >> 31);
    bx_cpu.eflags.of = ((result_32 >> 30) & 0x01) != bx_cpu.eflags.sf;


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> 1);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_16 & 0x01);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
    bx_cpu.eflags.sf = (result_16 >> 15);
    bx_cpu.eflags.of = ((result_16 >> 14) & 0x01) != bx_cpu.eflags.sf;


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SHR_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL & 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = (op1_8 >> op2_8);

  /* set eflags:
   * SHR affects the following flags: O,S,Z,P,C
   */

  if (op2_8) {
    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    bx_cpu.eflags.zf = (result_8 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_8];
    bx_cpu.eflags.sf = (result_8 >> 7);
    /* OF really only defined if op2 == 1 */
    bx_cpu.eflags.of = ((result_8 >> 6) & 0x01) != bx_cpu.eflags.sf;
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SHR_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL & 0x1F; /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = (op1_32 >> op2_8);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_32 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
      bx_cpu.eflags.sf = (result_32 >> 31);
      /* OF really only defined if op2 == 1 */
      bx_cpu.eflags.of = ((result_32 >> 30) & 0x01) != bx_cpu.eflags.sf;
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = (op1_16 >> op2_8);

    /* set eflags:
     * SHR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_16 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
      bx_cpu.eflags.sf = (result_16 >> 15);
      /* OF really only defined if op2 == 1 */
      bx_cpu.eflags.of = ((result_16 >> 14) & 0x01) != bx_cpu.eflags.sf;
      }


    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}


  void
bx_SAR_EbIb()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 &= 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8 < 8) {
    if (op1_8 & 0x80) {
      result_8 = (op1_8 >> op2_8) | (0xFF << (8 - op2_8));
      }
    else {
      result_8 = (op1_8 >> op2_8);
      }
    }
  else {
    result_8 = 0;
    }

  /* set eflags:
   * SAR affects the following flags: O,S,Z,P,C
   */

  if (op2_8) {
    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    bx_cpu.eflags.zf = (result_8 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_8];
    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.sf = (result_8 >> 7);
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SAR_EvIb()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = bx_fetch_next_byte();
  op2_8 &= 0x1F;  /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8 < 8) {
      if (op1_32 & 0x80000000) {
	result_32 = (op1_32 >> op2_8) | (0xFFFFFFFF << (32 - op2_8));
	}
      else {
	result_32 = (op1_32 >> op2_8);
	}
      }
    else {
      result_32 = 0;
      }

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_32 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
      bx_cpu.eflags.of = 0;
      bx_cpu.eflags.sf = (result_32 >> 31);
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8 < 8) {
      if (op1_16 & 0x8000) {
	result_16 = (op1_16 >> op2_8) | (0xFFFF << (16 - op2_8));
	}
      else {
	result_16 = (op1_16 >> op2_8);
	}
      }
    else {
      result_16 = 0;
      }

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_16 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
      bx_cpu.eflags.of = 0;
      bx_cpu.eflags.sf = (result_16 >> 15);
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SAR_Eb1() 
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);


  if (op1_8 & 0x80) {
    result_8 = (op1_8 >> 1) | 0x80;
    }
  else {
    result_8 = (op1_8 >> 1);
    }

  /* set eflags:
   * SAR affects the following flags: O,S,Z,P,C
   */

  bx_cpu.eflags.cf = (op1_8 & 0x01);
  bx_cpu.eflags.zf = (result_8 == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result_8];
  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.sf = (result_8 >> 7);

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SAR_Ev1() 
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op1_32 & 0x80000000) {
      result_32 = (op1_32 >> 1) | 0x80000000;
      }
    else {
      result_32 = (op1_32 >> 1);
      }

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_32 & 0x01);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.sf = (result_32 >> 31);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);


    if (op1_16 & 0x8000)
      result_16 = (op1_16 >> 1) | 0x8000;
    else
      result_16 = (op1_16 >> 1);

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    bx_cpu.eflags.cf = (op1_16 & 0x01);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.sf = (result_16 >> 15);

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_SAR_EbCL()
{
  Bit8u op2_8, op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;



  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 &= 0x1F;

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  if (op2_8 < 8) {
    if (op1_8 & 0x80) {
      result_8 = (op1_8 >> op2_8) | (0xFF << (8 - op2_8));
      }
    else {
      result_8 = (op1_8 >> op2_8);
      }
    }
  else {
    result_8 = 0;
    }

  /* set eflags:
   * SAR affects the following flags: O,S,Z,P,C
   */

  if (op2_8) {
    bx_cpu.eflags.cf = (op1_8 >> (op2_8 - 1)) & 0x01;
    bx_cpu.eflags.zf = (result_8 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_8];
    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.sf = (result_8 >> 7);
    }

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_SAR_EvCL()
{
  Bit8u op2_8;
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2_8 = CL;
  op2_8 &= 0x1F;  /* use only 4 LSB's */

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    if (op2_8 < 8) {
      if (op1_32 & 0x80000000) {
	result_32 = (op1_32 >> op2_8) | (0xFFFFFFFF << (32 - op2_8));
	}
      else {
	result_32 = (op1_32 >> op2_8);
	}
      }
    else {
      result_32 = 0;
      }

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_32 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_32 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];
      bx_cpu.eflags.of = 0;
      bx_cpu.eflags.sf = (result_32 >> 31);
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    if (op2_8 < 8) {
      if (op1_16 & 0x8000) {
	result_16 = (op1_16 >> op2_8) | (0xFFFF << (16 - op2_8));
	}
      else {
	result_16 = (op1_16 >> op2_8);
	}
      }
    else {
      result_16 = 0;
      }

    /* set eflags:
     * SAR affects the following flags: O,S,Z,P,C
     */

    if (op2_8) {
      bx_cpu.eflags.cf = (op1_16 >> (op2_8 - 1)) & 0x01;
      bx_cpu.eflags.zf = (result_16 == 0);
      bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];
      bx_cpu.eflags.of = 0;
      bx_cpu.eflags.sf = (result_16 >> 15);
      }

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_NOT_Eb()
{
  Bit8u op1_8, result_8;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);


  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1_8, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1_8);

  result_8 = ~op1_8;

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result_8);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result_8);
}

  void
bx_NOT_Ev()
{
  Bit16u op1_16, result_16;
  Bit32u op1_32, result_32;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = ~op1_32;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit opsize */

    /* op1 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = ~op1_16;

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_OR_EbGb()
{
  Bit8u op2, op1, result;
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  /* op2 is a register, op2_addr is an index of a register */
  BX_READ_8BIT_REG(op2, op2_addr);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 | op2;

  /* set eflags:
   * OR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}

  void
bx_OR_EvGv()
{
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op2_32 is a register, op2_addr is an index of a register */
    BX_READ_32BIT_REG(op2_32, op2_addr);

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 | op2_32;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    /* op2_16 is a register, op2_addr is an index of a register */
    BX_READ_16BIT_REG(op2_16, op2_addr);

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 | op2_16;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_OR_GbEb()
{
  Bit8u op1, op2, result;
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  /* op1 is a register, op1_addr is an index of a register */
  BX_READ_8BIT_REG(op1, op1_addr);

  /* op2 is a register or memory reference */
  if (op2_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op2, op2_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op2_seg_reg, op2_addr, 1, BX_READ, &op2);

  result = op1 | op2;

  /* set eflags:
   * OR affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination, which is a register */
  BX_WRITE_8BIT_REG(op1_addr, result);
}

  void
bx_OR_GvEv()
{
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op1_b31, op2_b31, result_b31;
  Bit32u op1_32, op2_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, result_16;
  Bit16u op1_b15, op2_b15, result_b15;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1_32 is a register, op1_addr is an index of a register */
    BX_READ_32BIT_REG(op1_32, op1_addr);

    /* op2_32 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op2_32, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 4, BX_READ, &op2_32);

    result_32 = op1_32 | op2_32;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op1_b31 = op1_32 & 0x80000000;
    op2_b31 = op2_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_32BIT_REG(op1_addr, result_32);
    }
  else { /* 16 bit operand size mode */

    /* op1_16 is a register, op1_addr is an index of a register */
    BX_READ_16BIT_REG(op1_16, op1_addr);

    /* op2_16 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op2_16, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 2, BX_READ, &op2_16);

    result_16 = op1_16 | op2_16;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op1_b15 = op1_16 & 0x8000;
    op2_b15 = op2_16 & 0x8000;
    result_b15 = result_16 & 0x8000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_16BIT_REG(op1_addr, result_16);
    }
}

  void
bx_OR_ALIb()
{
  Bit8u op1, op2, sum;
  Bit8u op1_b7, op2_b7, sum_b7;


  op1 = AL;

  op2 = bx_fetch_next_byte();

  sum = op1 | op2;

  /* set eflags:
   * OR affects the following flags: O,S,Z,P,C
   */
  op1_b7 = op1 & 0x80;
  op2_b7 = op2 & 0x80;
  sum_b7 = sum & 0x80;


  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (sum_b7 != 0);
  bx_cpu.eflags.zf = (sum == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[sum];

  /* now write sum back to destination, which is a register */
  AL = sum;
}

  void
bx_OR_eAXIv()
{
  /* for 32 bit operand size mode */
  Bit32u op1_b31, op2_b31, sum_b31;
  Bit32u op1_32, op2_32, sum_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, sum_16;
  Bit16u op1_b15, op2_b15, sum_b15;


  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op1_32 = EAX;

    op2_32 = bx_fetch_next_dword();

    sum_32 = op1_32 | op2_32;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op1_b31 = op1_32 & 0x80000000;
    op2_b31 = op2_32 & 0x80000000;
    sum_b31 = sum_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b31 != 0);
    bx_cpu.eflags.zf = (sum_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_32 & 0xFF];

    /* now write sum back to destination */

    EAX = sum_32;
    }
  else { /* 16 bit operand size mode */
    op1_16 = AX;

    op2_16 = bx_fetch_next_word();

    sum_16 = op1_16 | op2_16;

    /* set eflags:
     * OR affects the following flags: O,S,Z,P,C
     */
    op1_b15 = op1_16 & 0x8000;
    op2_b15 = op2_16 & 0x8000;
    sum_b15 = sum_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b15 != 0);
    bx_cpu.eflags.zf = (sum_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_16 & 0xFF];

    /* now write sum back to destination */

    AX = sum_16;
    }
}


  void
bx_AND_EbGb()
{
  Bit8u op2, op1, result;
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  /* op2 is a register, op2_addr is an index of a register */
  BX_READ_8BIT_REG(op2, op2_addr);

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 & op2;

  /* set eflags:
   * AND affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}

  void
bx_AND_EvGv()
{
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op2_32 is a register, op2_addr is an index of a register */
    BX_READ_32BIT_REG(op2_32, op2_addr);

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 & op2_32;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    /* op2_16 is a register, op2_addr is an index of a register */
    BX_READ_16BIT_REG(op2_16, op2_addr);

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 & op2_16;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_AND_GbEb()
{
  Bit8u op1, op2, result;
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;
  Bit8u op1_b7, op2_b7, result_b7;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  /* op1 is a register, op1_addr is an index of a register */
  BX_READ_8BIT_REG(op1, op1_addr);

  /* op2 is a register or memory reference */
  if (op2_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op2, op2_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op2_seg_reg, op2_addr, 1, BX_READ, &op2);

  result = op1 & op2;

  /* set eflags:
   * AND affects the following flags: O,S,Z,P,C
   */
  op1_b7 = op1 & 0x80;
  op2_b7 = op2 & 0x80;
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (result_b7 != 0);
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination, which is a register */
  BX_WRITE_8BIT_REG(op1_addr, result);
}

  void
bx_AND_GvEv()
{
  Bit32u op1_addr, op2_addr;
  int op2_type;
  bx_segment_reg_t *op2_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op1_b31, op2_b31, result_b31;
  Bit32u op1_32, op2_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, result_16;
  Bit16u op1_b15, op2_b15, result_b15;


  bx_decode_exgx(&op1_addr, &op2_addr, &op2_type, &op2_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    /* op1_32 is a register, op1_addr is an index of a register */
    BX_READ_32BIT_REG(op1_32, op1_addr);

    /* op2_32 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op2_32, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 4, BX_READ, &op2_32);

    result_32 = op1_32 & op2_32;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op1_b31 = op1_32 & 0x80000000;
    op2_b31 = op2_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_32BIT_REG(op1_addr, result_32);
    }
  else { /* 16 bit operand size mode */

    /* op1_16 is a register, op1_addr is an index of a register */
    BX_READ_16BIT_REG(op1_16, op1_addr);

    /* op2_16 is a register or memory reference */
    if (op2_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op2_16, op2_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op2_seg_reg, op2_addr, 2, BX_READ, &op2_16);

    result_16 = op1_16 & op2_16;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op1_b15 = op1_16 & 0x8000;
    op2_b15 = op2_16 & 0x8000;
    result_b15 = result_16 & 0x8000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */

    BX_WRITE_16BIT_REG(op1_addr, result_16);
    }
}

  void
bx_AND_ALIb()
{
  Bit8u op1, op2, sum;
  Bit8u op1_b7, op2_b7, sum_b7;


  op1 = AL;

  op2 = bx_fetch_next_byte();

  sum = op1 & op2;

  /* set eflags:
   * AND affects the following flags: O,S,Z,P,C
   */
  op1_b7 = op1 & 0x80;
  op2_b7 = op2 & 0x80;
  sum_b7 = sum & 0x80;


  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = (sum_b7 != 0);
  bx_cpu.eflags.zf = (sum == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[sum];

  /* now write sum back to destination, which is a register */
  AL = sum;
}

  void
bx_AND_eAXIv()
{
  /* for 32 bit operand size mode */
  Bit32u op1_b31, op2_b31, sum_b31;
  Bit32u op1_32, op2_32, sum_32;

  /* for 16 bit operand size mode */
  Bit16u op1_16, op2_16, sum_16;
  Bit16u op1_b15, op2_b15, sum_b15;


  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op1_32 = EAX;

    op2_32 = bx_fetch_next_dword();

    sum_32 = op1_32 & op2_32;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op1_b31 = op1_32 & 0x80000000;
    op2_b31 = op2_32 & 0x80000000;
    sum_b31 = sum_32 & 0x80000000;


    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b31 != 0);
    bx_cpu.eflags.zf = (sum_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_32 & 0xFF];

    /* now write sum back to destination */

    EAX = sum_32;
    }
  else { /* 16 bit operand size mode */
    op1_16 = AX;

    op2_16 = bx_fetch_next_word();

    sum_16 = op1_16 & op2_16;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op1_b15 = op1_16 & 0x8000;
    op2_b15 = op2_16 & 0x8000;
    sum_b15 = sum_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (sum_b15 != 0);
    bx_cpu.eflags.zf = (sum_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[sum_16 & 0xFF];

    /* now write sum back to destination */

    AX = sum_16;
    }
}

  void
bx_AND_EvIv()
{
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_dword();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 & op2_32;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_word();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 & op2_16;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_AND_EvIb()
{
  Bit32u op2_addr, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;

  /* for 32 bit operand size mode */
  Bit32u op2_b31, op1_b31, result_b31;
  Bit32u op2_32, op1_32, result_32;

  /* for 16 bit operand size mode */
  Bit16u op2_16, op1_16, result_16;
  Bit16u op2_b15, op1_b15, result_b15;



  bx_decode_exgx(&op2_addr, &op1_addr, &op1_type, &op1_seg_reg);

  if (bx_32bit_opsize) { /* 32 bit operand size mode */

    op2_32 = bx_fetch_next_byte();

    /* op1_32 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_32BIT_REG(op1_32, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_READ, &op1_32);

    result_32 = op1_32 & op2_32;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b31 = op2_32 & 0x80000000;
    op1_b31 = op1_32 & 0x80000000;
    result_b31 = result_32 & 0x80000000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b31 != 0);
    bx_cpu.eflags.zf = (result_32 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_32 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_32BIT_REG(op1_addr, result_32);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 4, BX_WRITE, &result_32);
    }
  else { /* 16 bit operand size mode */

    op2_16 = bx_fetch_next_byte();

    /* op1_16 is a register or memory reference */
    if (op1_type == BX_REGISTER_REF) {
      BX_READ_16BIT_REG(op1_16, op1_addr);
      }
    else
      /* pointer, segment address pair */
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_READ, &op1_16);

    result_16 = op1_16 & op2_16;

    /* set eflags:
     * AND affects the following flags: O,S,Z,P,C
     */
    op2_b15 = op2_16 & 0x8000;
    op1_b15 = op1_16 & 0x8000;
    result_b15 = result_16 & 0x8000;

    bx_cpu.eflags.of = 0;
    bx_cpu.eflags.cf = 0;
    bx_cpu.eflags.sf = (result_b15 != 0);
    bx_cpu.eflags.zf = (result_16 == 0);
    bx_cpu.eflags.pf = bx_parity_lookup[result_16 & 0xFF];

    /* now write result back to destination */
    if (op1_type == BX_REGISTER_REF) {
      BX_WRITE_16BIT_REG(op1_addr, result_16);
      }
    else
      bx_access_virtual(op1_seg_reg, op1_addr, 2, BX_WRITE, &result_16);
    }
}

  void
bx_AND_EbIb()
{
  Bit8u op2, op1, result;
  Bit32u unused, op1_addr;
  int op1_type;
  bx_segment_reg_t *op1_seg_reg;
  Bit8u result_b7;


  bx_decode_exgx(&unused, &op1_addr, &op1_type, &op1_seg_reg);

  op2 = bx_fetch_next_byte();

  /* op1 is a register or memory reference */
  if (op1_type == BX_REGISTER_REF) {
    BX_READ_8BIT_REG(op1, op1_addr);
    }
  else
    /* pointer, segment address pair */
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_READ, &op1);

  result = op1 & op2;

  /* set eflags:
   * AND affects the following flags: O,S,Z,P,C
   */
  result_b7 = result & 0x80;

  bx_cpu.eflags.of = 0;
  bx_cpu.eflags.cf = 0;
  bx_cpu.eflags.sf = result_b7 != 0;
  bx_cpu.eflags.zf = (result == 0);
  bx_cpu.eflags.pf = bx_parity_lookup[result];

  /* now write result back to destination */
  if (op1_type == BX_REGISTER_REF) {
    BX_WRITE_8BIT_REG(op1_addr, result);
    }
  else
    bx_access_virtual(op1_seg_reg, op1_addr, 1, BX_WRITE, &result);
}
