implemented missed XOP instructions FRCZPS/PD/SS/SD + update CHANGES with fixed bugs

This commit is contained in:
Stanislav Shwartsman 2011-11-24 11:34:26 +00:00
parent 9f5dabf839
commit f660d3dc68
4 changed files with 168 additions and 4 deletions

View File

@ -77,6 +77,8 @@ Detailed change log :
- Added Bochs internal debugger command 'vmexitbp' to set breakpoint on
VMX guest VMEXIT (patch by Jianan Hao). Type 'vmexitbp' in debugger
command window to switch it on/off (similar to modebp).
- Fixed linear to physical address translation by Bochs internal debugger
for EPT unrestricted guest (VMX guest with paging disabled under EPT)
- Fixed bug in GUI debugger SSE registers display.
- Correctly display current CPU mode in GUI debugger status bar.
- Turn off the mouse capture when the internal debugger or gdbstub enter
@ -186,6 +188,8 @@ Detailed change log :
[3190995] add eth backend based on Slirp by Heikki Lindholm
- these S.F. bugs were closed/fixed
[2829847] Mouse locked during magic-break
[3418621] release mouse when debugger breakpoint was hit
[1947077] sb command bug
[2802677] Unable to install Cirrus SVGA driver in guest Windows ME
[3422638] large ramfile support broken on anything but Linux

View File

@ -631,28 +631,72 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VPCOMUQ_VdqHdqWdqIbR(bxInstruction
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VFRCZPS_VpsWpsR(bxInstruction_c *i)
{
BX_PANIC(("VFRCZPS_VpsWpsR: not implemented yet"));
BxPackedAvxRegister op = BX_READ_AVX_REG(i->rm());
unsigned len = i->getVL();
float_status_t status;
mxcsr_to_softfloat_status_word(status, MXCSR);
for (unsigned n=0; n < (4*len); n++) {
op.avx32u(n) = float32_frc(op.avx32u(n), status);
}
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_AVX_REGZ(i->nnn(), op, len);
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VFRCZPD_VpdWpdR(bxInstruction_c *i)
{
BX_PANIC(("VFRCZPD_VpdWpdR: not implemented yet"));
BxPackedAvxRegister op = BX_READ_AVX_REG(i->rm());
unsigned len = i->getVL();
float_status_t status;
mxcsr_to_softfloat_status_word(status, MXCSR);
for (unsigned n=0; n < (2*len); n++) {
op.avx64u(n) = float64_frc(op.avx64u(n), status);
}
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_AVX_REGZ(i->nnn(), op, len);
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VFRCZSS_VssWssR(bxInstruction_c *i)
{
BX_PANIC(("VFRCZSS_VssWssR: not implemented yet"));
float32 op = BX_READ_XMM_REG_LO_DWORD(i->rm());
BxPackedXmmRegister r;
float_status_t status;
mxcsr_to_softfloat_status_word(status, MXCSR);
r.xmm32u(0) = float32_frc(op, status);
r.xmm32u(1) = 0;
r.xmm64u(1) = 0;
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_XMM_REG_CLEAR_HIGH(i->nnn(), r);
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VFRCZSD_VsdWsdR(bxInstruction_c *i)
{
BX_PANIC(("VFRCZSD_VsdWsdR: not implemented yet"));
float64 op = BX_READ_XMM_REG_LO_QWORD(i->rm());
BxPackedXmmRegister r;
float_status_t status;
mxcsr_to_softfloat_status_word(status, MXCSR);
r.xmm64u(0) = float64_frc(op, status);
r.xmm64u(1) = 0;
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_XMM_REG_CLEAR_HIGH(i->nnn(), r);
BX_NEXT_INSTR(i);
}

View File

@ -355,6 +355,63 @@ float32 float32_round_to_int(float32 a, float_status_t &status)
return z;
}
/*----------------------------------------------------------------------------
| Extracts the fractional portion of single-precision floating-point value `a',
| and returns the result as a single-precision floating-point value. The
| fractional results are precise. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 float32_frc(float32 a, float_status_t &status)
{
int roundingMode = get_float_rounding_mode(status);
Bit16s aExp = extractFloat32Exp(a);
Bit32u aSig = extractFloat32Frac(a);
int aSign = extractFloat32Sign(a);
if (aExp == 0xFF) {
if (aSig) return propagateFloat32NaN(a, status);
float_raise(status, float_flag_invalid);
return float32_default_nan;
}
if (aExp >= 0x96) {
return packFloat32(roundingMode == float_round_down, 0, 0);
}
if (aExp < 0x7F) {
if (aExp == 0) {
if (get_denormals_are_zeros(status)) aSig = 0;
if (aSig == 0) {
return packFloat32(roundingMode == float_round_down, 0, 0);
}
float_raise(status, float_flag_denormal);
if (! float_exception_masked(status, float_flag_underflow))
float_raise(status, float_flag_underflow);
if(get_flush_underflow_to_zero(status)) {
float_raise(status, float_flag_underflow | float_flag_inexact);
return packFloat32(aSign, 0, 0);
}
}
return a;
}
Bit32u lastBitMask = 1 << (0x96 - aExp);
Bit32u roundBitsMask = lastBitMask - 1;
aSig &= roundBitsMask;
aSig <<= 7;
aExp--;
if (aSig == 0)
return packFloat32(roundingMode == float_round_down, 0, 0);
return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
}
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the single-precision
| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
@ -1167,6 +1224,63 @@ float64 float64_round_to_int(float64 a, float_status_t &status)
return z;
}
/*----------------------------------------------------------------------------
| Extracts the fractional portion of double-precision floating-point value `a',
| and returns the result as a double-precision floating-point value. The
| fractional results are precise. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float64 float64_frc(float64 a, float_status_t &status)
{
int roundingMode = get_float_rounding_mode(status);
Bit64u aSig = extractFloat64Frac(a);
Bit16s aExp = extractFloat64Exp(a);
int aSign = extractFloat64Sign(a);
if (aExp == 0x7FF) {
if (aSig) return propagateFloat64NaN(a, status);
float_raise(status, float_flag_invalid);
return float64_default_nan;
}
if (aExp >= 0x433) {
return packFloat64(roundingMode == float_round_down, 0, 0);
}
if (aExp < 0x3FF) {
if (aExp == 0) {
if (get_denormals_are_zeros(status)) aSig = 0;
if (aSig == 0) {
return packFloat64(roundingMode == float_round_down, 0, 0);
}
float_raise(status, float_flag_denormal);
if (! float_exception_masked(status, float_flag_underflow))
float_raise(status, float_flag_underflow);
if(get_flush_underflow_to_zero(status)) {
float_raise(status, float_flag_underflow | float_flag_inexact);
return packFloat64(aSign, 0, 0);
}
}
return a;
}
Bit64u lastBitMask = BX_CONST64(1) << (0x433 - aExp);
Bit64u roundBitsMask = lastBitMask - 1;
aSig &= roundBitsMask;
aSig <<= 10;
aExp--;
if (aSig == 0)
return packFloat64(roundingMode == float_round_down, 0, 0);
return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
}
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the double-precision
| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated

View File

@ -240,6 +240,7 @@ float32 float32_sub(float32, float32, float_status_t &status);
float32 float32_mul(float32, float32, float_status_t &status);
float32 float32_div(float32, float32, float_status_t &status);
float32 float32_sqrt(float32, float_status_t &status);
float32 float32_frc(float32, float_status_t &status);
float32 float32_muladd(float32, float32, float32, int flags, float_status_t &status);
BX_CPP_INLINE float32 float32_fmadd(float32 a, float32 b, float32 c, float_status_t &status)
@ -291,6 +292,7 @@ float64 float64_sub(float64, float64, float_status_t &status);
float64 float64_mul(float64, float64, float_status_t &status);
float64 float64_div(float64, float64, float_status_t &status);
float64 float64_sqrt(float64, float_status_t &status);
float64 float64_frc(float64, float_status_t &status);
float64 float64_muladd(float64, float64, float64, int flags, float_status_t &status);
BX_CPP_INLINE float64 float64_fmadd(float64 a, float64 b, float64 c, float_status_t &status)