Esempio n. 1
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EwGwR(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 4
  Bit16u op1_16, op2_16, sum_16;

  /* XADD dst(r/m), src(r)
   * temp <-- src + dst         | sum = op2 + op1
   * src  <-- dst               | op2 = op1
   * dst  <-- tmp               | op1 = sum
   */

  op1_16 = BX_READ_16BIT_REG(i->rm());
  op2_16 = BX_READ_16BIT_REG(i->nnn());
  sum_16 = op1_16 + op2_16;

  // and write destination into source
  // Note: if both op1 & op2 are registers, the last one written
  //       should be the sum, as op1 & op2 may be the same register.
  //       For example:  XADD AL, AL
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
  BX_WRITE_16BIT_REG(i->rm(), sum_16);

  SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
#else
  BX_INFO(("XADD_EwGw: not supported on < 80486"));
  UndefinedOpcode(i);
#endif
}
Esempio n. 2
0
File: bit.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BSWAP_RX(bxInstruction_c *i)
{
  BX_ERROR(("BSWAP with 16-bit opsize: undefined behavior !"));
  BX_WRITE_16BIT_REG(i->rm(), 0);

  BX_NEXT_INSTR(i);
}
Esempio n. 3
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbR(bxInstruction_c *i)
{
  Bit8u op2_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());

  /* sign extend byte op2 into word op1 */
  BX_WRITE_16BIT_REG(i->nnn(), (Bit8s) op2_8);
}
Esempio n. 4
0
void BX_CPU_C::BSR_GwEw(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16;

  /* op2_16 is a register or memory reference */
  if (i->modC0()) {
    op2_16 = BX_READ_16BIT_REG(i->rm());
  }
  else {
    /* pointer, segment address pair */
    read_virtual_word(i->seg(), RMAddr(i), &op2_16);
  }

  if (op2_16 == 0) {
    assert_ZF(); /* op1_16 undefined */
    return;
  }

  op1_16 = 15;
  while ( (op2_16 & 0x8000) == 0 ) {
    op1_16--;
    op2_16 <<= 1;
  }

  SET_FLAGS_OSZAPC_RESULT_16(op1_16, BX_INSTR_BITSCAN16);

  /* now write result back to destination */
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
}
Esempio n. 5
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EwGwM(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 4
  Bit16u op1_16, op2_16, sum_16;

  /* XADD dst(r/m), src(r)
   * temp <-- src + dst         | sum = op2 + op1
   * src  <-- dst               | op2 = op1
   * dst  <-- tmp               | op1 = sum
   */

  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  op1_16 = read_RMW_virtual_word(i->seg(), RMAddr(i));
  op2_16 = BX_READ_16BIT_REG(i->nnn());
  sum_16 = op1_16 + op2_16;
  write_RMW_virtual_word(sum_16);

  /* and write destination into source */
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);

  SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
#else
  BX_INFO(("XADD_EwGw: not supported on < 80486"));
  UndefinedOpcode(i);
#endif
}
Esempio n. 6
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GwEwM(bxInstruction_c *i)
{
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit16u val16 = read_virtual_word(i->seg(), RMAddr(i));
  BX_WRITE_16BIT_REG(i->nnn(), val16);
}
Esempio n. 7
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EwR(bxInstruction_c *i)
{
  Bit16u op1_16 = BX_READ_16BIT_REG(i->rm());
  op1_16 = - (Bit16s)(op1_16);
  BX_WRITE_16BIT_REG(i->rm(), op1_16);

  SET_FLAGS_OSZAPC_RESULT_16(op1_16, BX_LF_INSTR_NEG16);
}
Esempio n. 8
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSX_GwEbM(bxInstruction_c *i)
{
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit8u op2_8 = read_virtual_byte(i->seg(), RMAddr(i));

  /* sign extend byte op2 into word op1 */
  BX_WRITE_16BIT_REG(i->nnn(), (Bit8s) op2_8);
}
Esempio n. 9
0
File: bit.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_GwMw(bxInstruction_c *i)
{
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  Bit16u val16 = read_virtual_word(i->seg(), eaddr);
  
  BX_WRITE_16BIT_REG(i->nnn(), bx_bswap16(val16));

  BX_NEXT_INSTR(i);
}
Esempio n. 10
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNLE_GwEwR(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 6
  if (! get_ZF() && (getB_SF() == getB_OF()))
    BX_WRITE_16BIT_REG(i->nnn(), BX_READ_16BIT_REG(i->rm()));
#else
  BX_INFO(("CMOVNLE_GwEw: --enable-cpu-level=6 required"));
  UndefinedOpcode(i);
#endif
}
Esempio n. 11
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_EwIwR(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16 = i->Iw(), diff_16;

  op1_16 = BX_READ_16BIT_REG(i->rm());
  diff_16 = op1_16 - op2_16;
  BX_WRITE_16BIT_REG(i->rm(), diff_16);

  SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
}
Esempio n. 12
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EwIwR(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16 = i->Iw(), sum_16;

  op1_16 = BX_READ_16BIT_REG(i->rm());
  sum_16 = op1_16 + op2_16;
  BX_WRITE_16BIT_REG(i->rm(), sum_16);

  SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);
}
Esempio n. 13
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwR(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16;

#if BX_DEBUGGER
  // Note for mortals: the instruction to trigger this is "xchgw %bx,%bx"
  if (bx_dbg.magic_break_enabled && (i->nnn() == 3) && (i->rm() == 3))
  {
    BX_CPU_THIS_PTR magic_break = 1;
    return;
  }
#endif

  op1_16 = BX_READ_16BIT_REG(i->rm());
  op2_16 = BX_READ_16BIT_REG(i->nnn());

  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
  BX_WRITE_16BIT_REG(i->rm(),  op2_16);
}
Esempio n. 14
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::NEG_EwR(bxInstruction_c *i)
{
    Bit32u op1_16 = BX_READ_16BIT_REG(i->rm());
    op1_16 = 0 - (Bit32s)(Bit16s)(op1_16);
    BX_WRITE_16BIT_REG(i->rm(), op1_16);

    SET_FLAGS_OSZAPC_SUB_16(0, 0 - op1_16, op1_16);

    BX_NEXT_INSTR(i);
}
Esempio n. 15
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EwIwR(bxInstruction_c *i)
{
  bx_bool temp_CF = getB_CF();
  Bit16u op1_16, op2_16 = i->Iw(), diff_16;

  op1_16 = BX_READ_16BIT_REG(i->rm());
  diff_16 = op1_16 - (op2_16 + temp_CF);
  BX_WRITE_16BIT_REG(i->rm(), diff_16);

  SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_LF_INSTR_SUB_SBB16(temp_CF));
}
Esempio n. 16
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::ADC_EwIwR(bxInstruction_c *i)
{
  bx_bool temp_CF = getB_CF();
  Bit16u op1_16, op2_16 = i->Iw(), sum_16;

  op1_16 = BX_READ_16BIT_REG(i->rm());
  sum_16 = op1_16 + op2_16 + temp_CF;
  BX_WRITE_16BIT_REG(i->rm(), sum_16);

  SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_LF_INSTR_ADD_ADC16(temp_CF));
}
Esempio n. 17
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ADD_EwIwR(bxInstruction_c *i)
{
    Bit32u op1_16 = BX_READ_16BIT_REG(i->rm());
    Bit32u op2_16 = i->Iw();
    Bit32u sum_16 = op1_16 + op2_16;
    BX_WRITE_16BIT_REG(i->rm(), sum_16);

    SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);

    BX_NEXT_INSTR(i);
}
Esempio n. 18
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_EwIwR(bxInstruction_c *i)
{
    Bit32u op1_16 = BX_READ_16BIT_REG(i->rm());
    Bit32u op2_16 = i->Iw();
    Bit32u diff_16 = op1_16 - (op2_16 + getB_CF());

    BX_WRITE_16BIT_REG(i->rm(), diff_16);

    SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);

    BX_NEXT_INSTR(i);
}
Esempio n. 19
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GwEwR(bxInstruction_c *i)
{
    Bit32u op1_16 = BX_READ_16BIT_REG(i->nnn());
    Bit32u op2_16 = BX_READ_16BIT_REG(i->rm());
    Bit32u diff_16 = op1_16 - op2_16;

    BX_WRITE_16BIT_REG(i->nnn(), diff_16);

    SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);

    BX_NEXT_INSTR(i);
}
Esempio n. 20
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EwGwM(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16;

  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  op1_16 = read_RMW_virtual_word(i->seg(), RMAddr(i));
  op2_16 = BX_READ_16BIT_REG(i->nnn());

  write_RMW_virtual_word(op2_16);
  BX_WRITE_16BIT_REG(i->nnn(), op1_16);
}
Esempio n. 21
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SUB_GwEwM(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16, diff_16;

  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  op1_16 = BX_READ_16BIT_REG(i->nnn());
  op2_16 = read_virtual_word(i->seg(), RMAddr(i));
  diff_16 = op1_16 - op2_16;
  BX_WRITE_16BIT_REG(i->nnn(), diff_16);

  SET_FLAGS_OSZAPC_SUB_16(op1_16, op2_16, diff_16);
}
Esempio n. 22
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LFS_GwMp(bxInstruction_c *i)
{
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit16u reg_16 = read_virtual_word(i->seg(), eaddr);
  Bit16u fs     = read_virtual_word(i->seg(), (eaddr + 2) & i->asize_mask());

  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);

  BX_WRITE_16BIT_REG(i->nnn(), reg_16);

  BX_NEXT_INSTR(i);
}
Esempio n. 23
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SBB_GwEwM(bxInstruction_c *i)
{
  Bit16u op1_16, op2_16, diff_16;
  bx_bool temp_CF = getB_CF();

  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  op1_16 = BX_READ_16BIT_REG(i->nnn());
  op2_16 = read_virtual_word(i->seg(), RMAddr(i));
  diff_16 = op1_16 - (op2_16 + temp_CF);
  BX_WRITE_16BIT_REG(i->nnn(), diff_16);

  SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_LF_INSTR_SUB_SBB16(temp_CF));
}
Esempio n. 24
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMOVNLE_GwEwM(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 6
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit16u op2_16 = read_virtual_word(i->seg(), RMAddr(i));

  if (! get_ZF() && (getB_SF() == getB_OF()))
    BX_WRITE_16BIT_REG(i->nnn(), op2_16);
#else
  BX_INFO(("CMOVNLE_GwEw: --enable-cpu-level=6 required"));
  UndefinedOpcode(i);
#endif
}
Esempio n. 25
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XADD_EwGwR(bxInstruction_c *i)
{
    /* XADD dst(r/m), src(r)
     * temp <-- src + dst         | sum = op2 + op1
     * src  <-- dst               | op2 = op1
     * dst  <-- tmp               | op1 = sum
     */

    Bit32u op1_16 = BX_READ_16BIT_REG(i->rm());
    Bit32u op2_16 = BX_READ_16BIT_REG(i->nnn());
    Bit32u sum_16 = op1_16 + op2_16;

    // and write destination into source
    // Note: if both op1 & op2 are registers, the last one written
    //       should be the sum, as op1 & op2 may be the same register.
    //       For example:  XADD AL, AL
    BX_WRITE_16BIT_REG(i->nnn(), op1_16);
    BX_WRITE_16BIT_REG(i->rm(), sum_16);

    SET_FLAGS_OSZAPC_ADD_16(op1_16, op2_16, sum_16);

    BX_NEXT_INSTR(i);
}
Esempio n. 26
0
// LES/LDS can't be called from long64 mode
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LDS_GwMp(bxInstruction_c *i)
{
  BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);

  Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  Bit16u reg_16 = read_virtual_word_32(i->seg(), eaddr);
  Bit16u ds     = read_virtual_word_32(i->seg(), (eaddr + 2) & i->asize_mask());

  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);

  BX_WRITE_16BIT_REG(i->nnn(), reg_16);

  BX_NEXT_INSTR(i);
}
Esempio n. 27
0
void BX_CPU_C::LDS_GwMp(bxInstruction_c *i)
{
  if (i->modC0()) {
    BX_DEBUG(("LDS_GwMp: invalid use of LDS, must be memory reference!"));
    UndefinedOpcode(i);
  }

  Bit16u reg_16, ds;

  read_virtual_word(i->seg(), RMAddr(i), &reg_16);
  read_virtual_word(i->seg(), RMAddr(i) + 2, &ds);

  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);

  BX_WRITE_16BIT_REG(i->nnn(), reg_16);
}
Esempio n. 28
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EwSwR(bxInstruction_c *i)
{
  /* Illegal to use nonexisting segments */
  if (i->nnn() >= 6) {
    BX_INFO(("MOV_EwSw: using of nonexisting segment register %d", i->nnn()));
    UndefinedOpcode(i);
  }

  Bit16u seg_reg = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value;

  if (i->os32L()) {
    BX_WRITE_32BIT_REGZ(i->rm(), seg_reg);
  }
  else {
    BX_WRITE_16BIT_REG(i->rm(), seg_reg);
  }
}
Esempio n. 29
0
File: arith16.cpp Progetto: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EwGwR(bxInstruction_c *i)
{
    Bit16u op1_16 = BX_READ_16BIT_REG(i->rm());
    Bit16u diff_16 = AX - op1_16;

    SET_FLAGS_OSZAPC_SUB_16(AX, op1_16, diff_16);

    if (diff_16 == 0) {  // if accumulator == dest
        // dest <-- src
        BX_WRITE_16BIT_REG(i->rm(), BX_READ_16BIT_REG(i->nnn()));
    }
    else {
        // accumulator <-- dest
        AX = op1_16;
    }

    BX_NEXT_INSTR(i);
}
Esempio n. 30
0
  void
bx_cpu_c::POP_Ew(BxInstruction_t *i)
{
  Bit16u val16;

  pop_16(&val16);

  if (i->mod == 0xc0) {
    BX_WRITE_16BIT_REG(i->rm, val16);
    }
  else {
    // Note: there is one little weirdism here.  When 32bit addressing
    // is used, it is possible to use ESP in the modrm addressing.
    // If used, the value of ESP after the pop is used to calculate
    // the address.
    if (i->as_32 && (i->mod!=0xc0) && (i->rm==4) && (i->base==4)) {
      i->ResolveModrm(i);
      }
    write_virtual_word(i->seg, i->rm_addr, &val16);
    }
}