Beispiel #1
0
BX_CPU_C::read_virtual_dqword(unsigned s, bx_address offset, Bit8u *data)
{
  // Read Double Quadword.
  Bit64u *qwords = (Bit64u*) data;

  read_virtual_qword(s, offset+Host1stDWordOffset, &qwords[0]);
  read_virtual_qword(s, offset+Host2ndDWordOffset, &qwords[1]);
}
Beispiel #2
0
/* 0F 0F /r 0D */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::PI2FD_PqQq(bxInstruction_c *i)
{
  BxPackedMmxRegister result, op;

  BX_CPU_THIS_PTR prepareMMX();

  /* op is a register or memory reference */
  if (i->modC0()) {
    op = BX_READ_MMX_REG(i->rm());
  }
  else {
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
    /* pointer, segment address pair */
    MMXUQ(op) = read_virtual_qword(i->seg(), RMAddr(i));
  }

  float_status_t status_word;
  prepare_softfloat_status_word(status_word, float_round_to_zero);

  MMXUD0(result) =
        int32_to_float32(MMXSD0(op), status_word);
  MMXUD1(result) =
        int32_to_float32(MMXSD1(op), status_word);

  /* now write result back to destination */
  BX_WRITE_MMX_REG(i->nnn(), result);
}
Beispiel #3
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_DOUBLE_REAL(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);

  RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));

  FPU_update_last_instruction(i);

  clear_C1();

  if (! IS_TAG_EMPTY(-1)) {
    FPU_stack_overflow();
    BX_NEXT_INSTR(i);
  }

  float_status_t status =
    FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());

  // convert to floatx80 format
  floatx80 result = float64_to_floatx80(load_reg, status);

  unsigned unmasked = FPU_exception(status.float_exception_flags);
  if (! (unmasked & FPU_CW_Invalid)) {
    BX_CPU_THIS_PTR the_i387.FPU_push();
    BX_WRITE_FPU_REG(result, 0);
  }

  BX_NEXT_INSTR(i);
}
Beispiel #4
0
/* 0F 0F /r B7 */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::PMULHRW_PqQq(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareMMX();

  BxPackedMmxRegister op1 = BX_READ_MMX_REG(i->nnn()), op2, result;

  /* op2 is a register or memory reference */
  if (i->modC0()) {
    op2 = BX_READ_MMX_REG(i->rm());
  }
  else {
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
    /* pointer, segment address pair */
    MMXUQ(op2) = read_virtual_qword(i->seg(), RMAddr(i));
  }

  Bit32s product1 = Bit32s(MMXSW0(op1)) * Bit32s(MMXSW0(op2)) + 0x8000;
  Bit32s product2 = Bit32s(MMXSW1(op1)) * Bit32s(MMXSW1(op2)) + 0x8000;
  Bit32s product3 = Bit32s(MMXSW2(op1)) * Bit32s(MMXSW2(op2)) + 0x8000;
  Bit32s product4 = Bit32s(MMXSW3(op1)) * Bit32s(MMXSW3(op2)) + 0x8000;

  MMXUW0(result) = Bit16u(product1 >> 16);
  MMXUW1(result) = Bit16u(product2 >> 16);
  MMXUW2(result) = Bit16u(product3 >> 16);
  MMXUW3(result) = Bit16u(product4 >> 16);

  /* now write result back to destination */
  BX_WRITE_MMX_REG(i->nnn(), result);
}
Beispiel #5
0
void BX_CPU_C::BSR_GqEq(bxInstruction_c *i)
{
  /* for 64 bit operand size mode */
  Bit64u op1_64, op2_64;

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

  if (op2_64 == 0) {
    assert_ZF(); /* op1_64 undefined */
    return;
  }

  op1_64 = 63;
  while ( (op2_64 & BX_CONST64(0x8000000000000000)) == 0 ) {
    op1_64--;
    op2_64 <<= 1;
  }

  SET_FLAGS_OSZAPC_RESULT_64(op1_64, BX_INSTR_BITSCAN64);
  
  /* now write result back to destination */
  BX_WRITE_64BIT_REG(i->nnn(), op1_64);
}
Beispiel #6
0
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_DOUBLE_REAL(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
  BX_CPU_THIS_PTR prepareFPU(i);

  float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));

  clear_C1();

  if (! IS_TAG_EMPTY(-1)) {
    BX_CPU_THIS_PTR FPU_stack_overflow();
    return;
  }

  float_status_t status =
     FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());

  // convert to floatx80 format
  floatx80 result = float64_to_floatx80(load_reg, status);

  if (BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags))
    return;

  BX_CPU_THIS_PTR the_i387.FPU_push();
  BX_WRITE_FPU_REG(result, 0);
#else
  BX_INFO(("FLD_DOUBLE_REAL: required FPU, configure --enable-fpu"));
#endif
}
Beispiel #7
0
Datei: avx.cpp Projekt: iver6/BA
/* Opcode: VEX.66.0F.38 2D (VEX.W=0) */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMASKMOVPD_VpdHpdMpd(bxInstruction_c *i)
{
  BxPackedAvxRegister mask = BX_READ_AVX_REG(i->vvv()), result;
  unsigned len = i->getVL();

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

#if BX_SUPPORT_X86_64
  if (i->as64L()) {
    for (unsigned n=0; n < (2*len); n++) {
       if (mask.avx32u(n*2+1) & 0x80000000) {
          if (! IsCanonical(get_laddr64(i->seg(), eaddr + 8*n)))
             exception(int_number(i->seg()), 0);
       }
    }
  }
#endif

  for (int n=2*len-1; n >= 0; n--) {
    if (mask.avx32u(n*2+1) & 0x80000000)
       result.avx64u(n) = read_virtual_qword(i->seg(), (eaddr + 8*n) & i->asize_mask());
    else
       result.avx64u(n) = 0;
  }

  BX_WRITE_AVX_REGZ(i->nnn(), result, len);

  BX_NEXT_INSTR(i);
}
Beispiel #8
0
Datei: bit.cpp Projekt: iver6/BA
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVBE_GqMq(bxInstruction_c *i)
{
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  Bit64u val64 = read_virtual_qword(i->seg(), eaddr);
  
  BX_WRITE_64BIT_REG(i->nnn(), bx_bswap64(val64));

  BX_NEXT_INSTR(i);
}
Beispiel #9
0
Datei: avx.cpp Projekt: iver6/BA
/* VEX.66.0F 16 (VEX.W ignore) */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMOVHPD_VpdHpdMq(bxInstruction_c *i)
{
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));

  BxPackedXmmRegister op;

  op.xmm64u(0) = BX_READ_XMM_REG_LO_QWORD(i->vvv());
  op.xmm64u(1) = read_virtual_qword(i->seg(), eaddr);

  BX_WRITE_XMM_REG_CLEAR_HIGH(i->nnn(), op);

  BX_NEXT_INSTR(i);
}
Beispiel #10
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_DOUBLE_REAL(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);

  int pop_stack = i->nnn() & 1, rc;

  RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));

  BX_CPU_THIS_PTR FPU_update_last_instruction(i);

  clear_C1();

  if (IS_TAG_EMPTY(0))
  {
      FPU_exception(FPU_EX_Stack_Underflow);
      setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);

      if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
      {
          if (pop_stack)
              BX_CPU_THIS_PTR the_i387.FPU_pop();
      }
      BX_NEXT_INSTR(i);
  }

  float_status_t status =
      FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());

  floatx80 a = BX_READ_FPU_REG(0);

  if (floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(load_reg)) {
    rc = float_relation_unordered;
    float_raise(status, float_flag_invalid);
  }
  else {
    rc = floatx80_compare(a, float64_to_floatx80(load_reg, status), status);
  }
  setcc(status_word_flags_fpu_compare(rc));

  if (! FPU_exception(status.float_exception_flags)) {
     if (pop_stack)
         BX_CPU_THIS_PTR the_i387.FPU_pop();
  }

  BX_NEXT_INSTR(i);
}
Beispiel #11
0
void BX_CPU_C::LSS_GqMp(bxInstruction_c *i)
{
  if (i->modC0()) {
    BX_DEBUG(("LSS_GqMp: invalid use of LSS, must be memory reference!"));
    UndefinedOpcode(i);
  }

  Bit64u reg_64;
  Bit16u ss;

  read_virtual_qword(i->seg(), RMAddr(i), &reg_64);
  read_virtual_word(i->seg(), RMAddr(i) + 8, &ss);

  load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss);

  BX_WRITE_64BIT_REG(i->nnn(), reg_64);
}
Beispiel #12
0
/* DF /4 */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FBLD_PACKED_BCD(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
  BX_CPU_THIS_PTR prepareFPU(i);

  // read packed bcd from memory
  Bit16u hi2 = read_virtual_word (i->seg(), RMAddr(i) + 8);
  Bit64u lo8 = read_virtual_qword(i->seg(), RMAddr(i));

  clear_C1();

  if (! IS_TAG_EMPTY(-1))
  {
    BX_CPU_THIS_PTR FPU_stack_overflow();
    return;
  }

  // convert packed BCD to 64-bit integer
  Bit64s scale = 1;
  Bit64s val64 = 0;

  for (int n = 0; n < 16; n++)
  {
    val64 += (lo8 & 0x0f) * scale;
    lo8 >>= 4;
    scale *= 10;
  }

  val64 += (hi2 & 0x0f) * scale;
  val64 += ((hi2>>4) & 0x0f) * scale * 10;

  floatx80 result = int64_to_floatx80(val64);
  if (hi2 & 0x8000)	// set negative
      floatx80_chs(result);

  BX_CPU_THIS_PTR the_i387.FPU_push();
  BX_WRITE_FPU_REG(result, 0);
#else
  BX_INFO(("FBLD_PACKED_BCD: required FPU, configure --enable-fpu"));
#endif
}
Beispiel #13
0
/* DF /4 */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FBLD_PACKED_BCD(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);

  RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  Bit16u hi2 = read_virtual_word(i->seg(), (RMAddr(i) + 8) & i->asize_mask());
  Bit64u lo8 = read_virtual_qword(i->seg(), RMAddr(i));

  FPU_update_last_instruction(i);

  clear_C1();

  if (! IS_TAG_EMPTY(-1))
  {
    FPU_stack_overflow();
    BX_NEXT_INSTR(i);
  }

  // convert packed BCD to 64-bit integer
  Bit64s scale = 1;
  Bit64s val64 = 0;

  for (int n = 0; n < 16; n++)
  {
    val64 += (lo8 & 0x0f) * scale;
    lo8 >>= 4;
    scale *= 10;
  }

  val64 += (hi2 & 0x0f) * scale;
  val64 += ((hi2>>4) & 0x0f) * scale * 10;

  floatx80 result = int64_to_floatx80(val64);
  if (hi2 & 0x8000)        // set negative
      floatx80_chs(result);

  BX_CPU_THIS_PTR the_i387.FPU_push();
  BX_WRITE_FPU_REG(result, 0);

  BX_NEXT_INSTR(i);
}
Beispiel #14
0
/* DF /5 */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_QWORD_INTEGER(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
  BX_CPU_THIS_PTR prepareFPU(i);

  Bit64s load_reg = (Bit64s) read_virtual_qword(i->seg(), RMAddr(i));

  clear_C1();

  if (! IS_TAG_EMPTY(-1)) {
    BX_CPU_THIS_PTR FPU_stack_overflow();
    return;
  }

  floatx80 result = int64_to_floatx80(load_reg);
  BX_CPU_THIS_PTR the_i387.FPU_push();
  BX_WRITE_FPU_REG(result, 0);
#else
  BX_INFO(("FILD_QWORD_INTEGER: required FPU, configure --enable-fpu"));
#endif
}
Beispiel #15
0
/* 0F 0F /r BB */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::PSWAPD_PqQq(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareMMX();

  BxPackedMmxRegister result, op;

  /* op is a register or memory reference */
  if (i->modC0()) {
    op = BX_READ_MMX_REG(i->rm());
  }
  else {
    BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
    /* pointer, segment address pair */
    MMXUQ(op) = read_virtual_qword(i->seg(), RMAddr(i));
  }

  MMXUD0(result) = MMXUD1(op);
  MMXUD1(result) = MMXUD0(op);

  /* now write result back to destination */
  BX_WRITE_MMX_REG(i->nnn(), result);
}
Beispiel #16
0
/* DF /5 */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_QWORD_INTEGER(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);

  RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  Bit64s load_reg = (Bit64s) read_virtual_qword(i->seg(), RMAddr(i));

  FPU_update_last_instruction(i);

  clear_C1();

  if (! IS_TAG_EMPTY(-1)) {
    FPU_stack_overflow();
  }
  else {
    floatx80 result = int64_to_floatx80(load_reg);
    BX_CPU_THIS_PTR the_i387.FPU_push();
    BX_WRITE_FPU_REG(result, 0);
  }

  BX_NEXT_INSTR(i);
}
Beispiel #17
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_EXTENDED_REAL(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);

  floatx80 result;

  RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
  result.fraction = read_virtual_qword(i->seg(), RMAddr(i));
  result.exp      = read_virtual_word(i->seg(), (RMAddr(i)+8) & i->asize_mask());

  FPU_update_last_instruction(i);

  clear_C1();

  if (! IS_TAG_EMPTY(-1)) {
    FPU_stack_overflow();
  }
  else {
    BX_CPU_THIS_PTR the_i387.FPU_push();
    BX_WRITE_FPU_REG(result, 0);
  }

  BX_NEXT_INSTR(i);
}
Beispiel #18
0
BX_CPU_C::read_virtual_tword(unsigned s, bx_address offset, floatx80 *data)
{
  // read floating point register
  read_virtual_qword(s, offset+0, &data->fraction);
  read_virtual_word (s, offset+8, &data->exp);
}