Fixed IRET 64-bit mode bug

Support for 32 float copare methods for AVX
ckeanups in fetchdecode
This commit is contained in:
Stanislav Shwartsman 2011-02-13 06:10:11 +00:00
parent 0c50875e7f
commit 2d3f3668c7
10 changed files with 545 additions and 536 deletions

View File

@ -25,8 +25,8 @@ Changes after 2.4.5 release:
- 32-bit physical address for 386/486 guests
- 36-bit physical address for PSE-36 enabled Pentium guest
- 40-bit physical address for PAE enabled P6 or later guests
- Updated config.guess/config.sub scripts to May 2010 revisions.
- Updated Visual Studio 2008 project files in build/win32/vs2008ex-workspace.zip
- Update config.guess/config.sub scripts to May 2010 revisions.
- Update Visual Studio 2008 project files in build/win32/vs2008ex-workspace.zip
- Added Bochs compilation timestamp after Bochs version string.
- GUI and display libraries (Volker)
@ -74,12 +74,12 @@ Changes after 2.4.5 release:
- bugfix: close images on exit
- SF patches applied
[3164945] hack to compile under WIN64 by Darek Mihocka and Stanislav
[3164073] Fine grain SMC invalidation by Stanislav
[1539417] write protect for floppy drives by Ben Lunt
[2862322] fixes for emulated DHCP in eth_vnet
- these S.F. bugs were closed/fixed
[3012207] Int 13h FN 48h incorrect return values
[2588085] Mouse capture
[3140332] typo in mf3/ps2 mapping of BX_KEY_CTRL_R
[3111577] No "back" option in log settings

View File

@ -702,7 +702,7 @@ sse_pfp.o: sse_pfp.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h \
../cpu/i387.h ../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h \
../fpu/control_w.h ../cpu/xmm.h stack.h ../fpu/softfloat-specialize.h \
../fpu/softfloat.h
../fpu/softfloat-compare.h
sse_rcp.o: sse_rcp.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../gui/paramtree.h ../memory/memory.h \

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.295 2011-01-21 16:07:51 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.296 2011-02-13 06:10:11 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
@ -78,23 +78,6 @@ static const Bit8u BxOpcodeHasModrm32[512] = {
#undef X
/* *********** */
// LOCK PREFIX //
/* *********** */
/*
* The LOCK prefix can be prepended only to the following instructions
* and only to those forms of the instructions where the destination
* operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,
* CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If
* the LOCK prefix is used with one of these instructions and the source
* operand is a memory operand, an undefined opcode exception (#UD) will
* be generated. An undefined opcode exception will also be generated if
* the LOCK prefix is used with any instruction not in the above list.
* The XCHG instruction always asserts the LOCK# signal regardless of the
* presence or absence of the LOCK prefix.
*/
static unsigned Resolve16BaseReg[8] = {
BX_16BIT_REG_BX,
BX_16BIT_REG_BX,

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.h,v 1.109 2011-01-21 16:07:51 sshwarts Exp $
// $Id: fetchdecode.h,v 1.110 2011-02-13 06:10:11 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2011 Stanislav Shwartsman
@ -61,9 +61,8 @@ BX_CPP_INLINE Bit64u FetchQWORD(const Bit8u *iptr)
#define BX_PREPARE_SSE (0x01)
#define BX_PREPARE_AVX (0x02)
#define BX_VEX_L128 (0x04) /* VEX.L128 allowed */
#define BX_VEX_L256 (0x08) /* VEX.L256 allowed */
#define BX_VEX_W0_ONLY (0x10) /* only VEX.W0 allowed */
#define BX_VEX_L128 (0x04) /* VEX.L128 allowed */
#define BX_VEX_L256 (0x08) /* VEX.L256 allowed */
struct bxIAOpcodeTable {
BxExecutePtr_tR execute1;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.292 2011-01-21 19:46:44 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.293 2011-02-13 06:10:11 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
@ -84,23 +84,6 @@ static const Bit8u BxOpcodeHasModrm64[512] = {
#undef X
/* *********** */
// LOCK PREFIX //
/* *********** */
/*
* The LOCK prefix can be prepended only to the following instructions
* and only to those forms of the instructions where the destination
* operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,
* CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If
* the LOCK prefix is used with one of these instructions and the source
* operand is a memory operand, an undefined opcode exception (#UD) will
* be generated. An undefined opcode exception will also be generated if
* the LOCK prefix is used with any instruction not in the above list.
* The XCHG instruction always asserts the LOCK# signal regardless of the
* presence or absence of the LOCK prefix.
*/
// Segment override prefixes
// -------------------------
// In 64-bit mode the CS, DS, ES, and SS segment overrides are ignored.

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: iret.cc,v 1.50 2010-04-11 05:28:19 sshwarts Exp $
// $Id: iret.cc,v 1.51 2011-02-13 06:10:11 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2009 Stanislav Shwartsman
@ -411,14 +411,19 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
check_cs(&cs_descriptor, raw_cs_selector, 0, cs_selector.rpl);
/* INTERRUPT RETURN TO SAME PRIVILEGE LEVEL */
if ((cs_selector.rpl == CPL) && (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64))
if (cs_selector.rpl == CPL && !i->os64L())
{
/* top 24 bytes on stack must be within limits, else #SS(0) */
/* satisfied above */
/* load CS:EIP from stack */
/* load CS-cache with new code segment descriptor */
branch_far32(&cs_selector, &cs_descriptor, (Bit32u) new_rip, CPL);
if(cs_descriptor.u.segment.l) {
branch_far64(&cs_selector, &cs_descriptor, new_rip, CPL);
}
else {
branch_far32(&cs_selector, &cs_descriptor, (Bit32u) new_rip, CPL);
}
// ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask |

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: sse_pfp.cc,v 1.80 2011-01-21 19:46:44 sshwarts Exp $
// $Id: sse_pfp.cc,v 1.81 2011-02-13 06:10:11 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003-2011 Stanislav Shwartsman
@ -28,6 +28,7 @@
#if BX_CPU_LEVEL >= 6
#include "fpu/softfloat-compare.h"
#include "fpu/softfloat-specialize.h"
void BX_CPU_C::check_exceptionsSSE(int exceptions_flags)
@ -59,19 +60,27 @@ BX_CPP_INLINE void mxcsr_to_softfloat_status_word(float_status_t &status, bx_mxc
}
/* Comparison predicate for CMPSS/CMPPS instructions */
static float32_compare_method compare32[4] = {
float32_eq,
float32_lt,
float32_le,
float32_unordered
static float32_compare_method compare32[8] = {
float32_eq_ordered_quiet,
float32_lt_ordered_signalling,
float32_le_ordered_signalling,
float32_unordered_quiet,
float32_neq_unordered_quiet,
float32_nlt_unordered_signalling,
float32_nle_unordered_signalling,
float32_ordered_quiet
};
/* Comparison predicate for CMPSD/CMPPD instructions */
static float64_compare_method compare64[4] = {
float64_eq,
float64_lt,
float64_le,
float64_unordered
static float64_compare_method compare64[8] = {
float64_eq_ordered_quiet,
float64_lt_ordered_signalling,
float64_le_ordered_signalling,
float64_unordered_quiet,
float64_neq_unordered_quiet,
float64_nlt_unordered_signalling,
float64_nle_unordered_signalling,
float64_ordered_quiet
};
#endif // BX_CPU_LEVEL >= 6
@ -1882,30 +1891,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPPS_VpsWpsIbR(bxInstruction_c *i)
op2.xmm32u(3) = float32_denormal_to_zero(op2.xmm32u(3));
}
if(ib < 4)
{
op1.xmm32u(0) =
compare32[ib](op1.xmm32u(0), op2.xmm32u(0), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(1) =
compare32[ib](op1.xmm32u(1), op2.xmm32u(1), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(2) =
compare32[ib](op1.xmm32u(2), op2.xmm32u(2), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(3) =
compare32[ib](op1.xmm32u(3), op2.xmm32u(3), status) ? 0xFFFFFFFF : 0;
}
else
{
ib -= 4;
op1.xmm32u(0) =
compare32[ib](op1.xmm32u(0), op2.xmm32u(0), status) ? 0 : 0xFFFFFFFF;
op1.xmm32u(1) =
compare32[ib](op1.xmm32u(1), op2.xmm32u(1), status) ? 0 : 0xFFFFFFFF;
op1.xmm32u(2) =
compare32[ib](op1.xmm32u(2), op2.xmm32u(2), status) ? 0 : 0xFFFFFFFF;
op1.xmm32u(3) =
compare32[ib](op1.xmm32u(3), op2.xmm32u(3), status) ? 0 : 0xFFFFFFFF;
}
op1.xmm32u(0) = compare32[ib](op1.xmm32u(0), op2.xmm32u(0), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(1) = compare32[ib](op1.xmm32u(1), op2.xmm32u(1), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(2) = compare32[ib](op1.xmm32u(2), op2.xmm32u(2), status) ? 0xFFFFFFFF : 0;
op1.xmm32u(3) = compare32[ib](op1.xmm32u(3), op2.xmm32u(3), status) ? 0xFFFFFFFF : 0;
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_XMM_REG(i->nnn(), op1);
@ -1934,22 +1923,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPPD_VpdWpdIbR(bxInstruction_c *i)
op2.xmm64u(1) = float64_denormal_to_zero(op2.xmm64u(1));
}
if(ib < 4)
{
op1.xmm64u(0) = compare64[ib](op1.xmm64u(0), op2.xmm64u(0), status) ?
BX_CONST64(0xFFFFFFFFFFFFFFFF) : 0;
op1.xmm64u(1) = compare64[ib](op1.xmm64u(1), op2.xmm64u(1), status) ?
BX_CONST64(0xFFFFFFFFFFFFFFFF) : 0;
}
else
{
ib -= 4;
op1.xmm64u(0) = compare64[ib](op1.xmm64u(0), op2.xmm64u(0), status) ?
0 : BX_CONST64(0xFFFFFFFFFFFFFFFF);
op1.xmm64u(1) = compare64[ib](op1.xmm64u(1), op2.xmm64u(1), status) ?
0 : BX_CONST64(0xFFFFFFFFFFFFFFFF);
}
op1.xmm64u(0) = compare64[ib](op1.xmm64u(0), op2.xmm64u(0), status) ?
BX_CONST64(0xFFFFFFFFFFFFFFFF) : 0;
op1.xmm64u(1) = compare64[ib](op1.xmm64u(1), op2.xmm64u(1), status) ?
BX_CONST64(0xFFFFFFFFFFFFFFFF) : 0;
check_exceptionsSSE(status.float_exception_flags);
BX_WRITE_XMM_REG(i->nnn(), op1);
@ -1976,18 +1953,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPSD_VsdWsdIbR(bxInstruction_c *i)
op2 = float64_denormal_to_zero(op2);
}
if(ib < 4) {
if(compare64[ib](op1, op2, status_word)) {
op1 = BX_CONST64(0xFFFFFFFFFFFFFFFF);
} else {
op1 = 0;
}
if(compare64[ib](op1, op2, status_word)) {
op1 = BX_CONST64(0xFFFFFFFFFFFFFFFF);
} else {
if(compare64[ib-4](op1, op2, status_word)) {
op1 = 0;
} else {
op1 = BX_CONST64(0xFFFFFFFFFFFFFFFF);
}
op1 = 0;
}
check_exceptionsSSE(status_word.float_exception_flags);
@ -2015,19 +1984,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPSS_VssWssIbR(bxInstruction_c *i)
op2 = float32_denormal_to_zero(op2);
}
if(ib < 4) {
if(compare32[ib](op1, op2, status_word)) {
op1 = 0xFFFFFFFF;
} else {
op1 = 0;
}
} else {
if(compare32[ib-4](op1, op2, status_word)) {
op1 = 0;
} else {
op1 = 0xFFFFFFFF;
}
}
op1 = compare32[ib](op1, op2, status_word) ? 0xFFFFFFFF : 0;
check_exceptionsSSE(status_word.float_exception_flags);
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), op1);

496
bochs/fpu/softfloat-compare.h Executable file
View File

@ -0,0 +1,496 @@
/*============================================================================
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b.
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Adapted for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
#ifndef _SOFTFLOAT_COMPARE_H_
#define _SOFTFLOAT_COMPARE_H_
#include "softfloat.h"
// ======= float32 ======= //
typedef int (*float32_compare_method)(float32, float32, float_status_t &status);
// 0x00
BX_CPP_INLINE int float32_eq_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_equal);
}
// 0x01
BX_CPP_INLINE int float32_lt_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_less);
}
// 0x02
BX_CPP_INLINE int float32_le_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x03
BX_CPP_INLINE int float32_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_unordered);
}
// 0x04
BX_CPP_INLINE int float32_neq_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_equal);
}
// 0x05
BX_CPP_INLINE int float32_nlt_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_less);
}
// 0x06
BX_CPP_INLINE int float32_nle_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x07
BX_CPP_INLINE int float32_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_unordered);
}
// 0x08
BX_CPP_INLINE int float32_eq_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x09
BX_CPP_INLINE int float32_nge_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x0a
BX_CPP_INLINE int float32_ngt_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_greater);
}
// 0x0b
BX_CPP_INLINE int float32_false_quiet(float32 a, float32 b, float_status_t &status)
{
float32_compare_quiet(a, b, status);
return 0;
}
// 0x0c
BX_CPP_INLINE int float32_neq_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x0d
BX_CPP_INLINE int float32_ge_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x0e
BX_CPP_INLINE int float32_gt_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_greater);
}
// 0x0f
BX_CPP_INLINE int float32_true_quiet(float32 a, float32 b, float_status_t &status)
{
float32_compare_quiet(a, b, status);
return 1;
}
// 0x10
BX_CPP_INLINE int float32_eq_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_equal);
}
// 0x11
BX_CPP_INLINE int float32_lt_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less);
}
// 0x12
BX_CPP_INLINE int float32_le_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x13
BX_CPP_INLINE int float32_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_unordered);
}
// 0x14
BX_CPP_INLINE int float32_neq_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_equal);
}
// 0x15
BX_CPP_INLINE int float32_nlt_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_less);
}
// 0x16
BX_CPP_INLINE int float32_nle_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x17
BX_CPP_INLINE int float32_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_unordered);
}
// 0x18
BX_CPP_INLINE int float32_eq_unordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x19
BX_CPP_INLINE int float32_nge_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x1a
BX_CPP_INLINE int float32_ngt_unordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation != float_relation_greater);
}
// 0x1b
BX_CPP_INLINE int float32_false_signalling(float32 a, float32 b, float_status_t &status)
{
float32_compare(a, b, status);
return 0;
}
// 0x1c
BX_CPP_INLINE int float32_neq_ordered_signalling(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x1d
BX_CPP_INLINE int float32_ge_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x1e
BX_CPP_INLINE int float32_gt_ordered_quiet(float32 a, float32 b, float_status_t &status)
{
int relation = float32_compare_quiet(a, b, status);
return (relation == float_relation_greater);
}
// 0x1f
BX_CPP_INLINE int float32_true_signalling(float32 a, float32 b, float_status_t &status)
{
float32_compare(a, b, status);
return 1;
}
// ======= float64 ======= //
typedef int (*float64_compare_method)(float64, float64, float_status_t &status);
// 0x00
BX_CPP_INLINE int float64_eq_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_equal);
}
// 0x01
BX_CPP_INLINE int float64_lt_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_less);
}
// 0x02
BX_CPP_INLINE int float64_le_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x03
BX_CPP_INLINE int float64_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_unordered);
}
// 0x04
BX_CPP_INLINE int float64_neq_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_equal);
}
// 0x05
BX_CPP_INLINE int float64_nlt_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_less);
}
// 0x06
BX_CPP_INLINE int float64_nle_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x07
BX_CPP_INLINE int float64_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_unordered);
}
// 0x08
BX_CPP_INLINE int float64_eq_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x09
BX_CPP_INLINE int float64_nge_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x0a
BX_CPP_INLINE int float64_ngt_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_greater);
}
// 0x0b
BX_CPP_INLINE int float64_false_quiet(float64 a, float64 b, float_status_t &status)
{
float64_compare_quiet(a, b, status);
return 0;
}
// 0x0c
BX_CPP_INLINE int float64_neq_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x0d
BX_CPP_INLINE int float64_ge_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x0e
BX_CPP_INLINE int float64_gt_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_greater);
}
// 0x0f
BX_CPP_INLINE int float64_true_quiet(float64 a, float64 b, float_status_t &status)
{
float64_compare_quiet(a, b, status);
return 1;
}
// 0x10
BX_CPP_INLINE int float64_eq_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_equal);
}
// 0x11
BX_CPP_INLINE int float64_lt_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less);
}
// 0x12
BX_CPP_INLINE int float64_le_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_equal);
}
// 0x13
BX_CPP_INLINE int float64_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_unordered);
}
// 0x14
BX_CPP_INLINE int float64_neq_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_equal);
}
// 0x15
BX_CPP_INLINE int float64_nlt_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_less);
}
// 0x16
BX_CPP_INLINE int float64_nle_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_less) && (relation != float_relation_equal);
}
// 0x17
BX_CPP_INLINE int float64_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_unordered);
}
// 0x18
BX_CPP_INLINE int float64_eq_unordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation == float_relation_equal) || (relation == float_relation_unordered);
}
// 0x19
BX_CPP_INLINE int float64_nge_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_less) || (relation == float_relation_unordered);
}
// 0x1a
BX_CPP_INLINE int float64_ngt_unordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation != float_relation_greater);
}
// 0x1b
BX_CPP_INLINE int float64_false_signalling(float64 a, float64 b, float_status_t &status)
{
float64_compare(a, b, status);
return 0;
}
// 0x1c
BX_CPP_INLINE int float64_neq_ordered_signalling(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare(a, b, status);
return (relation != float_relation_equal) && (relation != float_relation_unordered);
}
// 0x1d
BX_CPP_INLINE int float64_ge_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_greater) || (relation == float_relation_equal);
}
// 0x1e
BX_CPP_INLINE int float64_gt_ordered_quiet(float64 a, float64 b, float_status_t &status)
{
int relation = float64_compare_quiet(a, b, status);
return (relation == float_relation_greater);
}
// 0x1f
BX_CPP_INLINE int float64_true_signalling(float64 a, float64 b, float_status_t &status)
{
float64_compare(a, b, status);
return 1;
}
#endif

View File

@ -760,205 +760,6 @@ float_class_t float32_class(float32 a)
return float_normalized;
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_eq(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| or equal to the corresponding value `b', and 0 otherwise. The comparison
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
int float32_le(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat32Sign(a);
int bSign = extractFloat32Sign(b);
if (aSign != bSign) return aSign || ((Bit32u) ((a | b)<<1) == 0);
return (a == b) || (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_lt(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat32Sign(a);
int bSign = extractFloat32Sign(b);
if (aSign != bSign) return aSign && ((Bit32u) ((a | b)<<1) != 0);
return (a != b) && (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The invalid exception is
| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_eq_signaling(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
| cause an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_le_quiet(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat32Sign(a);
int bSign = extractFloat32Sign(b);
if (aSign != bSign) return aSign || ((Bit32u) ((a | b)<<1) == 0);
return (a == b) || (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
| exception. Otherwise, the comparison is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float32_lt_quiet(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat32Sign(a);
int bSign = extractFloat32Sign(b);
if (aSign != bSign) return aSign && ((Bit32u) ((a | b)<<1) != 0);
return (a != b) && (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| The unordered relationship is true when at least one of two source operands
| being compared is a NaN. Quiet NaNs do not cause an exception.
*----------------------------------------------------------------------------*/
int float32_unordered(float32 a, float32 b, float_status_t &status)
{
float_class_t aClass = float32_class(a);
float_class_t bClass = float32_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 1;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return 0;
}
/*----------------------------------------------------------------------------
| Compare between two single precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
@ -1688,205 +1489,6 @@ float_class_t float64_class(float64 a)
return float_normalized;
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
| corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_eq(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. The comparison is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
int float64_le(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat64Sign(a);
int bSign = extractFloat64Sign(b);
if (aSign != bSign) return aSign || ((Bit64u) ((a | b)<<1) == 0);
return (a == b) || (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_lt(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat64Sign(a);
int bSign = extractFloat64Sign(b);
if (aSign != bSign) return aSign && ((Bit64u) ((a | b)<<1) != 0);
return (a != b) && (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
| corresponding value `b', and 0 otherwise. The invalid exception is raised
| if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_eq_signaling(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN) {
float_raise(status, float_flag_invalid);
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
| cause an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_le_quiet(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat64Sign(a);
int bSign = extractFloat64Sign(b);
if (aSign != bSign) return aSign || ((Bit64u) ((a | b)<<1) == 0);
return (a == b) || (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
| exception. Otherwise, the comparison is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
int float64_lt_quiet(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 0;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
int aSign = extractFloat64Sign(a);
int bSign = extractFloat64Sign(b);
if (aSign != bSign) return aSign && ((Bit64u) ((a | b)<<1) != 0);
return (a != b) && (aSign ^ (a < b));
}
/*----------------------------------------------------------------------------
| The unordered relationship is true when at least one of two source operands
| being compared is a NaN. Quiet NaNs do not cause an exception.
*----------------------------------------------------------------------------*/
int float64_unordered(float64 a, float64 b, float_status_t &status)
{
float_class_t aClass = float64_class(a);
float_class_t bClass = float64_class(b);
if (aClass == float_NaN || bClass == float_NaN)
{
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
{
float_raise(status, float_flag_invalid);
}
return 1;
}
if (aClass == float_denormal || bClass == float_denormal)
{
float_raise(status, float_flag_denormal);
}
return 0;
}
/*----------------------------------------------------------------------------
| Compare between two double precision floating point numbers. Returns
| 'float_relation_equal' if the operands are equal, 'float_relation_less' if

View File

@ -214,14 +214,6 @@ 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);
typedef int (*float32_compare_method)(float32, float32, float_status_t &status);
int float32_eq(float32, float32, float_status_t &status);
int float32_le(float32, float32, float_status_t &status);
int float32_lt(float32, float32, float_status_t &status);
int float32_eq_signaling(float32, float32, float_status_t &status);
int float32_le_quiet(float32, float32, float_status_t &status);
int float32_lt_quiet(float32, float32, float_status_t &status);
int float32_unordered(float32, float32, float_status_t &status);
int float32_compare(float32, float32, float_status_t &status);
int float32_compare_quiet(float32, float32, float_status_t &status);
@ -248,14 +240,6 @@ 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);
typedef int (*float64_compare_method)(float64, float64, float_status_t &status);
int float64_eq(float64, float64, float_status_t &status);
int float64_le(float64, float64, float_status_t &status);
int float64_lt(float64, float64, float_status_t &status);
int float64_eq_signaling(float64, float64, float_status_t &status);
int float64_le_quiet(float64, float64, float_status_t &status);
int float64_lt_quiet(float64, float64, float_status_t &status);
int float64_unordered(float64, float64, float_status_t &status);
int float64_compare(float64, float64, float_status_t &status);
int float64_compare_quiet(float64, float64, float_status_t &status);