Exemplo n.º 1
0
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMI_ST0_STj(bxInstruction_c *i)
{
  BX_CPU_THIS_PTR prepareFPU(i);
  BX_CPU_THIS_PTR FPU_update_last_instruction(i);

  int pop_stack = i->b1() & 4;

  clear_C1();

  if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
  {
      FPU_exception(FPU_EX_Stack_Underflow);
      setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);

      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());

  int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status);
  BX_CPU_THIS_PTR write_eflags_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);
}
Exemplo n.º 2
0
/* 66 0F 3A 62 */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPISTRM_VdqWdqIb(bxInstruction_c *i)
{
#if (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
    BX_CPU_THIS_PTR prepareSSE();

    BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2, result;
    Bit8u imm8 = i->Ib();

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

    // compare all pairs of Ai, Bj
    bx_bool BoolRes[16][16];
    compare_strings(BoolRes, op1, op2, imm8);

    unsigned num_elements = (imm8 & 0x1) ? 8 : 16;
    unsigned len1 = find_eos(op1, imm8);
    unsigned len2 = find_eos(op2, imm8);
    Bit16u result2 = aggregate(BoolRes, len1, len2, imm8);

    // As defined by imm8[6], result2 is then either stored to the least
    // significant bits of XMM0 (zero extended to 128 bits) or expanded
    // into a byte/word-mask and then stored to XMM0
    if (imm8 & 0x40) {
        if (num_elements == 8) {
            for (int index = 0; index < 8; index++)
                result.xmm16u(index) = (result2 & (1<<index)) ? 0xffff : 0;
        }
        else {  // num_elements = 16
            for (int index = 0; index < 16; index++)
                result.xmmubyte(index) = (result2 & (1<<index)) ? 0xff : 0;
        }
    }
    else {
        result.xmm64u(1) = 0;
        result.xmm64u(0) = (Bit64u) result2;
    }

    Bit32u flags = 0;
    if (result2 != 0) flags |= EFlagsCFMask;
    if (len1 < num_elements) flags |= EFlagsSFMask;
    if (len2 < num_elements) flags |= EFlagsZFMask;
    if (result2 & 0x1)
        flags |= EFlagsOFMask;
    setEFlagsOSZAPC(flags);

    BX_WRITE_XMM_REG(0, result); /* store result XMM0 */
#else
    BX_INFO(("PCMPISTRM_VdqWdqIb: required SSE4.2, use --enable-sse and --enable-sse-extension options"));
    UndefinedOpcode(i);
#endif
}
Exemplo n.º 3
0
/* 66 0F 3A 63 */
void BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPISTRI_VdqWdqIb(bxInstruction_c *i)
{
#if (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0)
    BX_CPU_THIS_PTR prepareSSE();

    BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2;
    Bit8u imm8 = i->Ib();

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

    // compare all pairs of Ai, Bj
    bx_bool BoolRes[16][16];
    compare_strings(BoolRes, op1, op2, imm8);
    unsigned num_elements = (imm8 & 0x1) ? 8 : 16;
    int index;

    unsigned len1 = find_eos(op1, imm8);
    unsigned len2 = find_eos(op2, imm8);
    Bit16u result2 = aggregate(BoolRes, len1, len2, imm8);

    // The index of the first (or last, according to imm8[6]) set bit of result2
    // is returned to ECX. If no bits are set in IntRes2, ECX is set to 16 (8)
    if (imm8 & 0x40) {
        // The index returned to ECX is of the MSB in result2
        for (index=num_elements-1; index>=0; index--)
            if (result2 & (1<<index)) break;
        if (index < 0) index = num_elements;
    }
    else {
        // The index returned to ECX is of the LSB in result2
        for (index=0; index<(int)num_elements; index++)
            if (result2 & (1<<index)) break;
    }
    RCX = index;

    Bit32u flags = 0;
    if (result2 != 0) flags |= EFlagsCFMask;
    if (len1 < num_elements) flags |= EFlagsSFMask;
    if (len2 < num_elements) flags |= EFlagsZFMask;
    if (result2 & 0x1)
        flags |= EFlagsOFMask;
    setEFlagsOSZAPC(flags);

#else
    BX_INFO(("PCMPISTRI_VdqWdqIb: required SSE4.2, use --enable-sse and --enable-sse-extension options"));
    UndefinedOpcode(i);
#endif
}
Exemplo n.º 4
0
/* 66 0F 3A 60 */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPESTRM_VdqWdqIbR(bxInstruction_c *i)
{
  BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn());
  BxPackedXmmRegister op2 = BX_READ_XMM_REG(i->rm()), result;
  Bit8u imm8 = i->Ib();

  // compare all pairs of Ai, Bj
  Bit8u BoolRes[16][16];
  compare_strings(BoolRes, op1, op2, imm8);
  unsigned len1, len2, num_elements = (imm8 & 0x1) ? 8 : 16;

#if BX_SUPPORT_X86_64
  if (i->os64L()) {
    len1 = find_eos64(RAX, imm8);
    len2 = find_eos64(RDX, imm8);
  }
  else
#endif
  {
    len1 = find_eos32(EAX, imm8);
    len2 = find_eos32(EDX, imm8);
  }
  Bit16u result2 = aggregate(BoolRes, len1, len2, imm8);

  // As defined by imm8[6], result2 is then either stored to the least
  // significant bits of XMM0 (zero extended to 128 bits) or expanded
  // into a byte/word-mask and then stored to XMM0
  if (imm8 & 0x40) {
     if (num_elements == 8) {
       for (int index = 0; index < 8; index++)
         result.xmm16u(index) = (result2 & (1<<index)) ? 0xffff : 0;
     }
     else {  // num_elements = 16
       for (int index = 0; index < 16; index++)
         result.xmmubyte(index) = (result2 & (1<<index)) ? 0xff : 0;
     }
  }
  else {
     result.xmm64u(1) = 0;
     result.xmm64u(0) = (Bit64u) result2;
  }

  Bit32u flags = 0;
  if (result2 != 0) flags |= EFlagsCFMask;
  if (len1 < num_elements) flags |= EFlagsSFMask;
  if (len2 < num_elements) flags |= EFlagsZFMask;
  if (result2 & 0x1)
    flags |= EFlagsOFMask;
  setEFlagsOSZAPC(flags);

  BX_WRITE_XMM_REGZ(0, result, i->getVL()); /* store result XMM0 */

  BX_NEXT_INSTR(i);
}
Exemplo n.º 5
0
void BX_CPU_C::write_eflags_fpu_compare(int float_relation)
{
  switch(float_relation) {
   case float_relation_unordered:
      setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);
      break;

   case float_relation_greater:
      setEFlagsOSZAPC(0);
      break;

   case float_relation_less:
      setEFlagsOSZAPC(EFlagsCFMask);
      break;

   case float_relation_equal:
      setEFlagsOSZAPC(EFlagsZFMask);
      break;

   default:
      BX_PANIC(("write_eflags: unknown floating point compare relation"));
  }
}
Exemplo n.º 6
0
void BX_CPU_C::AND_EdId(bxInstruction_c *i)
{
  Bit32u op2_32, op1_32, result_32;

  op2_32 = i->Id();

  if (i->modC0()) {
    op1_32 = BX_READ_32BIT_REG(i->rm());

#if defined(BX_HostAsm_And32)
    Bit32u flags32;
    asmAnd32(result_32, op1_32, op2_32, flags32);
    setEFlagsOSZAPC(flags32);
#else
    result_32 = op1_32 & op2_32;
#endif

    BX_WRITE_32BIT_REGZ(i->rm(), result_32);
  }
  else {
    read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);

#if defined(BX_HostAsm_And32)
    Bit32u flags32;
    asmAnd32(result_32, op1_32, op2_32, flags32);
    setEFlagsOSZAPC(flags32);
#else
    result_32 = op1_32 & op2_32;
#endif

    write_RMW_virtual_dword(result_32);
  }

#if !defined(BX_HostAsm_And32)
  SET_FLAGS_OSZAPC_RESULT_32(result_32, BX_INSTR_LOGIC32);
#endif
}
Exemplo n.º 7
0
/* 66 0F 3A 61 */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPESTRI_VdqWdqIbR(bxInstruction_c *i)
{
  BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2 = BX_READ_XMM_REG(i->rm());
  Bit8u imm8 = i->Ib();

  // compare all pairs of Ai, Bj
  Bit8u BoolRes[16][16];
  compare_strings(BoolRes, op1, op2, imm8);
  unsigned len1, len2, num_elements = (imm8 & 0x1) ? 8 : 16;
  int index;

#if BX_SUPPORT_X86_64
  if (i->os64L()) {
    len1 = find_eos64(RAX, imm8);
    len2 = find_eos64(RDX, imm8);
  }
  else
#endif
  {
    len1 = find_eos32(EAX, imm8);
    len2 = find_eos32(EDX, imm8);
  }
  Bit16u result2 = aggregate(BoolRes, len1, len2, imm8);

  // The index of the first (or last, according to imm8[6]) set bit of result2
  // is returned to ECX. If no bits are set in IntRes2, ECX is set to 16 (8)
  if (imm8 & 0x40) {
     // The index returned to ECX is of the MSB in result2
     for (index=num_elements-1; index>=0; index--)
       if (result2 & (1<<index)) break;
     if (index < 0) index = num_elements;
  }
  else {
     // The index returned to ECX is of the LSB in result2
     for (index=0; index<(int)num_elements; index++)
       if (result2 & (1<<index)) break;
  }
  RCX = index;

  Bit32u flags = 0;
  if (result2 != 0) flags |= EFlagsCFMask;
  if (len1 < num_elements) flags |= EFlagsSFMask;
  if (len2 < num_elements) flags |= EFlagsZFMask;
  if (result2 & 0x1)
    flags |= EFlagsOFMask;
  setEFlagsOSZAPC(flags);

  BX_NEXT_INSTR(i);
}
Exemplo n.º 8
0
void BX_CPU_C::TEST_EAXId(bxInstruction_c *i)
{
  Bit32u op2_32, op1_32;

  op1_32 = EAX;
  op2_32 = i->Id();

#if defined(BX_HostAsm_Test32)
  Bit32u flags32;
  asmTest32(op1_32, op2_32, flags32);
  setEFlagsOSZAPC(flags32);
#else
  Bit32u result_32 = op1_32 & op2_32;
  SET_FLAGS_OSZAPC_RESULT_32(result_32, BX_INSTR_LOGIC32);
#endif
}
Exemplo n.º 9
0
Arquivo: avx.cpp Projeto: iver6/BA
/* Opcode: VEX.66.0F.38.17 (VEX.W ignore, VEX.VVV #UD) */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VPTEST_VdqWdqR(bxInstruction_c *i)
{
  BxPackedAvxRegister op1 = BX_READ_AVX_REG(i->nnn()), op2 = BX_READ_AVX_REG(i->rm());
  unsigned len = i->getVL();

  unsigned result = EFlagsZFMask | EFlagsCFMask;

  for (unsigned n=0; n < (2*len); n++) {
    if ((op2.avx64u(n) &  op1.avx64u(n)) != 0) result &= ~EFlagsZFMask;
    if ((op2.avx64u(n) & ~op1.avx64u(n)) != 0) result &= ~EFlagsCFMask;
  }

  setEFlagsOSZAPC(result);

  BX_NEXT_INSTR(i);
}
Exemplo n.º 10
0
void BX_CPU_C::TEST_EdId(bxInstruction_c *i)
{
  Bit32u op2_32, op1_32;

  op2_32 = i->Id();

  if (i->modC0()) {
    op1_32 = BX_READ_32BIT_REG(i->rm());
  }
  else {
    read_virtual_dword(i->seg(), RMAddr(i), &op1_32);
  }

#if defined(BX_HostAsm_Test32)
  Bit32u flags32;
  asmTest32(op1_32, op2_32, flags32);
  setEFlagsOSZAPC(flags32);
#else
  Bit32u result_32 = op1_32 & op2_32;
  SET_FLAGS_OSZAPC_RESULT_32(result_32, BX_INSTR_LOGIC32);
#endif
}
Exemplo n.º 11
0
void BX_CPU_C::OR_GdEd(bxInstruction_c *i)
{
  Bit32u op1_32, op2_32, result_32;

  op1_32 = BX_READ_32BIT_REG(i->nnn());

  if (i->modC0()) {
    op2_32 = BX_READ_32BIT_REG(i->rm());
  }
  else {
    read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
  }

#if defined(BX_HostAsm_Or32)
  Bit32u flags32;
  asmOr32(result_32, op1_32, op2_32, flags32);
  setEFlagsOSZAPC(flags32);
#else
  result_32 = op1_32 | op2_32;
  SET_FLAGS_OSZAPC_RESULT_32(result_32, BX_INSTR_LOGIC32);
#endif

  BX_WRITE_32BIT_REGZ(i->nnn(), result_32);
}