Index: uspace/lib/softfloat/generic/softfloat.c
===================================================================
--- uspace/lib/softfloat/generic/softfloat.c	(revision 750636ac4a65360c44846b7681af6ae46854dd3a)
+++ uspace/lib/softfloat/generic/softfloat.c	(revision 3e01316fd558e3235487a9cfe2a4fe29615ff69a)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2005 Josef Cejka
+ * Copyright (c) 2011 Petr Koupy
  * All rights reserved.
  *
@@ -32,5 +33,5 @@
  * @{
  */
-/** @file
+/** @file Softfloat API.
  */
 
@@ -83,4 +84,20 @@
 }
 
+long double __addtf3(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	if (ta.parts.sign != tb.parts.sign) {
+		if (ta.parts.sign) {
+			ta.parts.sign = 0;
+			return subFloat128(tb, ta).ld;
+		};
+		tb.parts.sign = 0;
+		return subFloat128(ta, tb).ld;
+	}
+	return addFloat128(ta, tb).ld;
+}
+
 float __subsf3(float a, float b)
 {
@@ -107,4 +124,16 @@
 }
 
+long double __subtf3(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	if (ta.parts.sign != tb.parts.sign) {
+		tb.parts.sign = !tb.parts.sign;
+		return addFloat128(ta, tb).ld;
+	}
+	return subFloat128(ta, tb).ld;
+}
+
 float __mulsf3(float a, float b) 
 {
@@ -123,4 +152,12 @@
 }
 
+long double __multf3(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	return 	mulFloat128(ta, tb).ld;
+}
+
 float __divsf3(float a, float b) 
 {
@@ -139,4 +176,12 @@
 }
 
+long double __divtf3(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	return 	divFloat128(ta, tb).ld;
+}
+
 float __negsf2(float a)
 {
@@ -149,8 +194,16 @@
 double __negdf2(double a)
 {
-	float64 fa;
-	fa.d = a;
-	fa.parts.sign = !fa.parts.sign;
-	return fa.d;
+	float64 da;
+	da.d = a;
+	da.parts.sign = !da.parts.sign;
+	return da.d;
+}
+
+long double __negtf2(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+	ta.parts.sign = !ta.parts.sign;
+	return ta.ld;
 }
 
@@ -164,4 +217,18 @@
 }
 
+long double __extendsftf2(float a)
+{
+	float32 fa;
+	fa.f = a;
+	return convertFloat32ToFloat128(fa).ld;
+}
+
+long double __extenddftf2(double a)
+{
+	float64 da;
+	da.d = a;
+	return convertFloat64ToFloat128(da).ld;
+}
+
 float __truncdfsf2(double a) 
 {
@@ -171,4 +238,18 @@
 }
 
+float __trunctfsf2(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+	return convertFloat128ToFloat32(ta).f;
+}
+
+double __trunctfdf2(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+	return convertFloat128ToFloat64(ta).d;
+}
+
 int __fixsfsi(float a)
 {
@@ -178,4 +259,5 @@
 	return float32_to_int(fa);
 }
+
 int __fixdfsi(double a)
 {
@@ -184,4 +266,12 @@
 	
 	return float64_to_int(da);
+}
+
+int __fixtfsi(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_int(ta);
 }
  
@@ -193,4 +283,5 @@
 	return float32_to_long(fa);
 }
+
 long __fixdfdi(double a)
 {
@@ -199,4 +290,12 @@
 	
 	return float64_to_long(da);
+}
+
+long __fixtfdi(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_long(ta);
 }
  
@@ -208,4 +307,5 @@
 	return float32_to_longlong(fa);
 }
+
 long long __fixdfti(double a)
 {
@@ -216,4 +316,12 @@
 }
 
+long long __fixtfti(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_longlong(ta);
+}
+
 unsigned int __fixunssfsi(float a)
 {
@@ -223,4 +331,5 @@
 	return float32_to_uint(fa);
 }
+
 unsigned int __fixunsdfsi(double a)
 {
@@ -229,4 +338,12 @@
 	
 	return float64_to_uint(da);
+}
+
+unsigned int __fixunstfsi(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_uint(ta);
 }
  
@@ -238,4 +355,5 @@
 	return float32_to_ulong(fa);
 }
+
 unsigned long __fixunsdfdi(double a)
 {
@@ -244,4 +362,12 @@
 	
 	return float64_to_ulong(da);
+}
+
+unsigned long __fixunstfdi(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_ulong(ta);
 }
  
@@ -253,4 +379,5 @@
 	return float32_to_ulonglong(fa);
 }
+
 unsigned long long __fixunsdfti(double a)
 {
@@ -259,4 +386,12 @@
 	
 	return float64_to_ulonglong(da);
+}
+
+unsigned long long __fixunstfti(long double a)
+{
+	float128 ta;
+	ta.ld = a;
+
+	return float128_to_ulonglong(ta);
 }
  
@@ -268,4 +403,5 @@
 	return fa.f;
 }
+
 double __floatsidf(int i)
 {
@@ -275,4 +411,12 @@
 	return da.d;
 }
+
+long double __floatsitf(int i)
+{
+	float128 ta;
+
+	ta = int_to_float128(i);
+	return ta.ld;
+}
  
 float __floatdisf(long i)
@@ -283,4 +427,5 @@
 	return fa.f;
 }
+
 double __floatdidf(long i)
 {
@@ -290,4 +435,12 @@
 	return da.d;
 }
+
+long double __floatditf(long i)
+{
+	float128 ta;
+
+	ta = long_to_float128(i);
+	return ta.ld;
+}
  
 float __floattisf(long long i)
@@ -298,4 +451,5 @@
 	return fa.f;
 }
+
 double __floattidf(long long i)
 {
@@ -306,4 +460,12 @@
 }
 
+long double __floattitf(long long i)
+{
+	float128 ta;
+
+	ta = longlong_to_float128(i);
+	return ta.ld;
+}
+
 float __floatunsisf(unsigned int i)
 {
@@ -313,4 +475,5 @@
 	return fa.f;
 }
+
 double __floatunsidf(unsigned int i)
 {
@@ -320,4 +483,12 @@
 	return da.d;
 }
+
+long double __floatunsitf(unsigned int i)
+{
+	float128 ta;
+
+	ta = uint_to_float128(i);
+	return ta.ld;
+}
  
 float __floatundisf(unsigned long i)
@@ -328,4 +499,5 @@
 	return fa.f;
 }
+
 double __floatundidf(unsigned long i)
 {
@@ -335,4 +507,12 @@
 	return da.d;
 }
+
+long double __floatunditf(unsigned long i)
+{
+	float128 ta;
+
+	ta = ulong_to_float128(i);
+	return ta.ld;
+}
  
 float __floatuntisf(unsigned long long i)
@@ -343,4 +523,5 @@
 	return fa.f;
 }
+
 double __floatuntidf(unsigned long long i)
 {
@@ -351,11 +532,13 @@
 }
 
+long double __floatuntitf(unsigned long long i)
+{
+	float128 ta;
+
+	ta = ulonglong_to_float128(i);
+	return ta.ld;
+}
+
 /* Comparison functions */
-/* Comparison functions */
-
-/* a<b .. -1
- * a=b ..  0
- * a>b ..  1
- * */
 
 int __cmpsf2(float a, float b) 
@@ -364,19 +547,62 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
+
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
 		return 1; /* no special constant for unordered - maybe signaled? */
-	};
-
+	}
 	
 	if (isFloat32eq(fa, fb)) {
 		return 0;
-	};
+	}
 	
 	if (isFloat32lt(fa, fb)) {
 		return -1;
-		};
+	}
+
 	return 1;
 }
 
+int __cmpdf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		return 1; /* no special constant for unordered - maybe signaled? */
+	}
+
+	if (isFloat64eq(da, db)) {
+		return 0;
+	}
+
+	if (isFloat64lt(da, db)) {
+		return -1;
+	}
+
+	return 1;
+}
+
+int __cmptf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 1; /* no special constant for unordered - maybe signaled? */
+	}
+
+	if (isFloat128eq(ta, tb)) {
+		return 0;
+	}
+
+	if (isFloat128lt(ta, tb)) {
+		return -1;
+	}
+
+	return 1;
+}
+
 int __unordsf2(float a, float b) 
 {
@@ -384,10 +610,23 @@
 	fa.f = a;
 	fb.f = b;
-	return ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) );
-}
-
-/** 
- * @return zero, if neither argument is a NaN and are equal
- * */
+	return ((isFloat32NaN(fa)) || (isFloat32NaN(fb)));
+}
+
+int __unorddf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+	return ((isFloat64NaN(da)) || (isFloat64NaN(db)));
+}
+
+int __unordtf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	return ((isFloat128NaN(ta)) || (isFloat128NaN(tb)));
+}
+
 int __eqsf2(float a, float b) 
 {
@@ -395,18 +634,53 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
-		/* TODO: sigNaNs*/
-		return 1;
-		};
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
 	return isFloat32eq(fa, fb) - 1;
 }
 
-/* strange behavior, but it was in gcc documentation */
+int __eqdf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+	return isFloat64eq(da, db) - 1;
+}
+
+int __eqtf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+	return isFloat128eq(ta, tb) - 1;
+}
+
 int __nesf2(float a, float b) 
 {
+	/* strange behavior, but it was in gcc documentation */
 	return __eqsf2(a, b);
 }
 
-/* return value >= 0 if a>=b and neither is NaN */
+int __nedf2(double a, double b)
+{
+	/* strange behavior, but it was in gcc documentation */
+	return __eqdf2(a, b);
+}
+
+int __netf2(long double a, long double b)
+{
+	/* strange behavior, but it was in gcc documentation */
+	return __eqtf2(a, b);
+}
+
 int __gesf2(float a, float b)
 {
@@ -414,21 +688,65 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
-		/* TODO: sigNaNs*/
-		return -1;
-		};
+
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
 	
 	if (isFloat32eq(fa, fb)) {
 		return 0;
-	};
+	}
 	
 	if (isFloat32gt(fa, fb)) {
 		return 1;
-		};
+	}
 	
 	return -1;
 }
 
-/** Return negative value, if a<b and neither is NaN*/
+int __gedf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
+
+	if (isFloat64eq(da, db)) {
+		return 0;
+	}
+
+	if (isFloat64gt(da, db)) {
+		return 1;
+	}
+
+	return -1;
+}
+
+int __getf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
+
+	if (isFloat128eq(ta, tb)) {
+		return 0;
+	}
+
+	if (isFloat128gt(ta, tb)) {
+		return 1;
+	}
+
+	return -1;
+}
+
 int __ltsf2(float a, float b)
 {
@@ -436,15 +754,53 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
-		/* TODO: sigNaNs*/
-		return 1;
-		};
+
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+
 	if (isFloat32lt(fa, fb)) {
 		return -1;
-		};
+	}
+
 	return 0;
 }
 
-/* return value <= 0 if a<=b and neither is NaN */
+int __ltdf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+
+	if (isFloat64lt(da, db)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+int __lttf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+
+	if (isFloat128lt(ta, tb)) {
+		return -1;
+	}
+
+	return 0;
+}
+
 int __lesf2(float a, float b)
 {
@@ -452,21 +808,65 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
-		/* TODO: sigNaNs*/
-		return 1;
-		};
+
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
 	
 	if (isFloat32eq(fa, fb)) {
 		return 0;
-	};
+	}
 	
 	if (isFloat32lt(fa, fb)) {
 		return -1;
-		};
+	}
 	
 	return 1;
 }
 
-/** Return positive value, if a>b and neither is NaN*/
+int __ledf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+
+	if (isFloat64eq(da, db)) {
+		return 0;
+	}
+
+	if (isFloat64lt(da, db)) {
+		return -1;
+	}
+
+	return 1;
+}
+
+int __letf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		/* TODO: sigNaNs */
+		return 1;
+	}
+
+	if (isFloat128eq(ta, tb)) {
+		return 0;
+	}
+
+	if (isFloat128lt(ta, tb)) {
+		return -1;
+	}
+
+	return 1;
+}
+
 int __gtsf2(float a, float b)
 {
@@ -474,23 +874,250 @@
 	fa.f = a;
 	fb.f = b;
-	if ( (isFloat32NaN(fa)) || (isFloat32NaN(fb)) ) {
-		/* TODO: sigNaNs*/
-		return -1;
-		};
+
+	if ((isFloat32NaN(fa)) || (isFloat32NaN(fb))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
+
 	if (isFloat32gt(fa, fb)) {
 		return 1;
-		};
+	}
+
 	return 0;
 }
 
-/* Other functions */
-
-float __powisf2(float a, int b)
-{
-/* TODO: */
-	float32 fa;
-	fa.binary = FLOAT32_NAN;
-	return fa.f;
-}
+int __gtdf2(double a, double b)
+{
+	float64 da, db;
+	da.d = a;
+	db.d = b;
+
+	if ((isFloat64NaN(da)) || (isFloat64NaN(db))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
+
+	if (isFloat64gt(da, db)) {
+		return 1;
+	}
+
+	return 0;
+}
+
+int __gttf2(long double a, long double b)
+{
+	float128 ta, tb;
+	ta.ld = a;
+	tb.ld = b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		/* TODO: sigNaNs */
+		return -1;
+	}
+
+	if (isFloat128gt(ta, tb)) {
+		return 1;
+	}
+
+	return 0;
+}
+
+
+
+#ifdef SPARC_SOFTFLOAT
+
+/* SPARC quadruple-precision wrappers */
+
+void _Qp_add(long double *c, long double *a, long double *b)
+{
+	*c = __addtf3(*a, *b);
+}
+
+void _Qp_sub(long double *c, long double *a, long double *b)
+{
+	*c = __subtf3(*a, *b);
+}
+
+void _Qp_mul(long double *c, long double *a, long double *b)
+{
+	*c = __multf3(*a, *b);
+}
+
+void _Qp_div(long double *c, long double *a, long double *b)
+{
+	*c = __divtf3(*a, *b);
+}
+
+void _Qp_neg(long double *c, long double *a)
+{
+	*c = __negtf2(*a);
+}
+
+void _Qp_stoq(long double *c, float a)
+{
+	*c = __extendsftf2(a);
+}
+
+void _Qp_dtoq(long double *c, double a)
+{
+	*c = __extenddftf2(a);
+}
+
+float _Qp_qtos(long double *a)
+{
+	return __trunctfsf2(*a);
+}
+
+double _Qp_qtod(long double *a)
+{
+	return __trunctfdf2(*a);
+}
+
+int _Qp_qtoi(long double *a)
+{
+	return __fixtfsi(*a);
+}
+
+unsigned int _Qp_qtoui(long double *a)
+{
+	return __fixunstfsi(*a);
+}
+
+long _Qp_qtox(long double *a)
+{
+	return __fixtfdi(*a);
+}
+
+unsigned long _Qp_qtoux(long double *a)
+{
+	return __fixunstfdi(*a);
+}
+
+void _Qp_itoq(long double *c, int a)
+{
+	*c = __floatsitf(a);
+}
+
+void _Qp_uitoq(long double *c, unsigned int a)
+{
+	*c = __floatunsitf(a);
+}
+
+void _Qp_xtoq(long double *c, long a)
+{
+	*c = __floatditf(a);
+}
+
+void _Qp_uxtoq(long double *c, unsigned long a)
+{
+	*c = __floatunditf(a);
+}
+
+int _Qp_cmp(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 3;
+	}
+
+	if (isFloat128eq(ta, tb)) {
+		return 0;
+	}
+
+	if (isFloat128lt(ta, tb)) {
+		return 1;
+	}
+
+	return 2;
+}
+
+int _Qp_cmpe(long double *a, long double *b)
+{
+	/* strange, but is defined this way in SPARC Compliance Definition */
+	return _Qp_cmp(a, b);
+}
+
+int _Qp_feq(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 0;
+	}
+
+	return isFloat128eq(ta, tb);
+}
+
+int _Qp_fge(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 0;
+	}
+
+	return isFloat128eq(ta, tb) || isFloat128gt(ta, tb);
+}
+
+int _Qp_fgt(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 0;
+	}
+
+	return isFloat128gt(ta, tb);
+}
+
+int _Qp_fle(long double*a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 0;
+	}
+
+	return isFloat128eq(ta, tb) || isFloat128lt(ta, tb);
+}
+
+int _Qp_flt(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 0;
+	}
+
+	return isFloat128lt(ta, tb);
+}
+
+int _Qp_fne(long double *a, long double *b)
+{
+	float128 ta, tb;
+	ta.ld = *a;
+	tb.ld = *b;
+
+	if ((isFloat128NaN(ta)) || (isFloat128NaN(tb))) {
+		return 1;
+	}
+
+	return !isFloat128eq(ta, tb);
+}
+
+#endif
 
 /** @}
