aboutsummaryrefslogtreecommitdiff
path: root/fpu
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-25 18:40:20 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-25 18:40:20 +0000
commit1f587329169765299448c1becd6a633a204ead29 (patch)
treeacfac14d79c8a0923a0ef6beda4447a5f074a310 /fpu
parent5cc9878d3d5b98e2b51f8296bb1f87c970aa0866 (diff)
downloadqemu-1f587329169765299448c1becd6a633a204ead29.zip
qemu-1f587329169765299448c1becd6a633a204ead29.tar.gz
qemu-1f587329169765299448c1becd6a633a204ead29.tar.bz2
128-bit float support for user mode
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3740 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'fpu')
-rw-r--r--fpu/softfloat.c44
-rw-r--r--fpu/softfloat.h2
2 files changed, 46 insertions, 0 deletions
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e30f22f..3ec1e0d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5421,6 +5421,50 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \
COMPARE(32, 0xff)
COMPARE(64, 0x7ff)
+INLINE int float128_compare_internal( float128 a, float128 b,
+ int is_quiet STATUS_PARAM )
+{
+ flag aSign, bSign;
+
+ if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
+ ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
+ ( ( extractFloat128Exp( b ) == 0x7fff ) &&
+ ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
+ if (!is_quiet ||
+ float128_is_signaling_nan( a ) ||
+ float128_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return float_relation_unordered;
+ }
+ aSign = extractFloat128Sign( a );
+ bSign = extractFloat128Sign( b );
+ if ( aSign != bSign ) {
+ if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
+ /* zero case */
+ return float_relation_equal;
+ } else {
+ return 1 - (2 * aSign);
+ }
+ } else {
+ if (a.low == b.low && a.high == b.high) {
+ return float_relation_equal;
+ } else {
+ return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
+ }
+ }
+}
+
+int float128_compare( float128 a, float128 b STATUS_PARAM )
+{
+ return float128_compare_internal(a, b, 0 STATUS_VAR);
+}
+
+int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
+{
+ return float128_compare_internal(a, b, 1 STATUS_VAR);
+}
+
/* Multiply A by 2 raised to the power N. */
float32 float32_scalbn( float32 a, int n STATUS_PARAM )
{
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 84cffdd..5f95d06 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -415,6 +415,8 @@ int float128_lt( float128, float128 STATUS_PARAM );
int float128_eq_signaling( float128, float128 STATUS_PARAM );
int float128_le_quiet( float128, float128 STATUS_PARAM );
int float128_lt_quiet( float128, float128 STATUS_PARAM );
+int float128_compare( float128, float128 STATUS_PARAM );
+int float128_compare_quiet( float128, float128 STATUS_PARAM );
int float128_is_nan( float128 );
int float128_is_signaling_nan( float128 );
float128 float128_scalbn( float128, int STATUS_PARAM );