Fixed IRET 64-bit mode bug
Support for 32 float copare methods for AVX ckeanups in fetchdecode
This commit is contained in:
parent
0c50875e7f
commit
2d3f3668c7
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 |
|
||||
|
@ -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
496
bochs/fpu/softfloat-compare.h
Executable 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
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user