Index: uspace/lib/softfloat/conversion.c
===================================================================
--- uspace/lib/softfloat/conversion.c	(revision efdfebc372ac1a93545f90450c8e1fe0aa789daf)
+++ uspace/lib/softfloat/conversion.c	(revision efdfebc372ac1a93545f90450c8e1fe0aa789daf)
@@ -0,0 +1,1041 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * Copyright (c) 2011 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup softfloat
+ * @{
+ */
+/** @file Conversion of precision and conversion between integers and floats.
+ */
+
+#include "sftypes.h"
+#include "conversion.h"
+#include "comparison.h"
+#include "common.h"
+
+float64 float32_to_float64(float32 a)
+{
+	float64 result;
+	uint64_t frac;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.fraction = a.parts.fraction;
+	result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
+	
+	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (result.parts.fraction == 0) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+			
+		frac = result.parts.fraction;
+		
+		while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
+			frac <<= 1;
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.fraction = frac;
+	}
+	
+	return result;
+}
+
+float128 float32_to_float128(float32 a)
+{
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	uint64_t tmp_hi, tmp_lo;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = a.parts.fraction;
+	lshift128(result.parts.frac_hi, result.parts.frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE),
+	    &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	
+	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
+		result.parts.exp = FLOAT128_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (eq128(result.parts.frac_hi,
+		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+		
+		frac_hi = result.parts.frac_hi;
+		frac_lo = result.parts.frac_lo;
+		
+		and128(frac_hi, frac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.frac_hi = frac_hi;
+		result.parts.frac_lo = frac_lo;
+	}
+	
+	return result;
+}
+
+float128 float64_to_float128(float64 a)
+{
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	uint64_t tmp_hi, tmp_lo;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = a.parts.fraction;
+	lshift128(result.parts.frac_hi, result.parts.frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE),
+	    &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	
+	if ((is_float64_infinity(a)) || (is_float64_nan(a))) {
+		result.parts.exp = FLOAT128_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (eq128(result.parts.frac_hi,
+		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+		
+		frac_hi = result.parts.frac_hi;
+		frac_lo = result.parts.frac_lo;
+		
+		and128(frac_hi, frac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.frac_hi = frac_hi;
+		result.parts.frac_lo = frac_lo;
+	}
+	
+	return result;
+}
+
+float32 float64_to_float32(float64 a)
+{
+	float32 result;
+	int32_t exp;
+	uint64_t frac;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float64_nan(a)) {
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		
+		if (is_float64_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float64_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;	
+		if (exp > FLOAT32_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac = a.parts.fraction; 
+		frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
+		
+		frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
+		
+		while (exp > 0) {
+			--exp;
+			frac >>= 1;
+		}
+		result.parts.fraction = frac;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	result.parts.fraction =
+	    a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
+	return result;
+}
+
+float32 float128_to_float32(float128 a)
+{
+	float32 result;
+	int32_t exp;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float128_nan(a)) {
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		
+		if (is_float128_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float128_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;
+		if (exp > FLOAT32_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac_hi = a.parts.frac_hi;
+		frac_lo = a.parts.frac_lo;
+		
+		/* denormalize and set hidden bit */
+		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+		
+		rshift128(frac_hi, frac_lo,
+		    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
+		    &frac_hi, &frac_lo);
+		
+		while (exp > 0) {
+			--exp;
+			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+		}
+		result.parts.fraction = frac_lo;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	rshift128(frac_hi, frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
+	    &frac_hi, &frac_lo);
+	result.parts.fraction = frac_lo;
+	return result;
+}
+
+float64 float128_to_float64(float128 a)
+{
+	float64 result;
+	int32_t exp;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float128_nan(a)) {
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		
+		if (is_float128_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float128_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
+	
+	if (exp >= FLOAT64_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;
+		if (exp > FLOAT64_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac_hi = a.parts.frac_hi;
+		frac_lo = a.parts.frac_lo;
+		
+		/* denormalize and set hidden bit */
+		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+		
+		rshift128(frac_hi, frac_lo,
+		    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
+		    &frac_hi, &frac_lo);
+		
+		while (exp > 0) {
+			--exp;
+			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+		}
+		result.parts.fraction = frac_lo;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	rshift128(frac_hi, frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
+	    &frac_hi, &frac_lo);
+	result.parts.fraction = frac_lo;
+	return result;
+}
+
+/** Helper procedure for converting float32 to uint32.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint32_t _float32_to_uint32_helper(float32 a)
+{
+	uint32_t frac;
+	
+	if (a.parts.exp < FLOAT32_BIAS) {
+		/* TODO: rounding */
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT32_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 32 - FLOAT32_FRACTION_SIZE - 1; 
+	
+	frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float32_to_uint32(float32 a)
+{
+	if (is_float32_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return _float32_to_uint32_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float32_to_int32(float32 a)
+{
+	if (is_float32_nan(a))
+		return INT32_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return _float32_to_uint32_helper(a);
+}
+
+/** Helper procedure for converting float32 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float32_to_uint64_helper(float32 a)
+{
+	uint64_t frac;
+	
+	if (a.parts.exp < FLOAT32_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT32_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
+	
+	frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float32_to_uint64(float32 a)
+{
+	if (is_float32_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float32_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int64_t float32_to_int64(float32 a)
+{
+	if (is_float32_nan(a))
+		return INT64_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float32_to_uint64_helper(a);
+}
+
+/** Helper procedure for converting float64 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float64_to_uint64_helper(float64 a)
+{
+	uint64_t frac;
+	
+	if (a.parts.exp < FLOAT64_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT64_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
+	
+	frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float64_to_uint32(float64 a)
+{
+	if (is_float64_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return (uint32_t) _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float64_to_int32(float64 a)
+{
+	if (is_float64_nan(a))
+		return INT32_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return (int32_t) _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens 
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float64_to_uint64(float64 a)
+{
+	if (is_float64_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens 
+ *  - now its the biggest or the smallest int
+ */
+int64_t float64_to_int64(float64 a)
+{
+	if (is_float64_nan(a))
+		return INT64_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float64_to_uint64_helper(a);
+}
+
+/** Helper procedure for converting float128 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float128_to_uint64_helper(float128 a)
+{
+	uint64_t frac_hi, frac_lo;
+	
+	if (a.parts.exp < FLOAT128_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	
+	frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	lshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 1), &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - (a.parts.exp - FLOAT128_BIAS) - 1), &frac_hi, &frac_lo);
+	if ((a.parts.sign == 1) && !eq128(frac_hi, frac_lo, 0x0ll, 0x0ll)) {
+		not128(frac_hi, frac_lo, &frac_hi, &frac_lo);
+		add128(frac_hi, frac_lo, 0x0ll, 0x1ll, &frac_hi, &frac_lo);
+	}
+	
+	return frac_lo;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float128_to_uint32(float128 a)
+{
+	if (is_float128_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return (uint32_t) _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float128_to_int32(float128 a)
+{
+	if (is_float128_nan(a))
+		return INT32_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return (int32_t) _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float128_to_uint64(float128 a)
+{
+	if (is_float128_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int64_t float128_to_int64(float128 a)
+{
+	if (is_float128_nan(a))
+		return INT64_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float128_to_uint64_helper(a);
+}
+
+float32 uint32_to_float32(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float32 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT32_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin = 0;
+		return result;
+	}
+	
+	if (counter > 0) {
+		i <<= counter - 1;
+	} else {
+		i >>= 1;
+	}
+	
+	round_float32(&exp, &i);
+	
+	result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float32 int32_to_float32(int32_t i)
+{
+	float32 result;
+	
+	if (i < 0)
+		result = uint32_to_float32((uint32_t) (-i));
+	else
+		result = uint32_to_float32((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float32 uint64_to_float32(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	uint32_t j;
+	float32 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT32_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin = 0;
+		return result;
+	}
+	
+	/* Shift all to the first 31 bits (31st will be hidden 1) */
+	if (counter > 33) {
+		i <<= counter - 1 - 32;
+	} else {
+		i >>= 1 + 32 - counter;
+	}
+	
+	j = (uint32_t) i;
+	round_float32(&exp, &j);
+	
+	result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	return result;
+}
+
+float32 int64_to_float32(int64_t i)
+{
+	float32 result;
+	
+	if (i < 0)
+		result = uint64_to_float32((uint64_t) (-i));
+	else
+		result = uint64_to_float32((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float64 uint32_to_float64(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float64 result;
+	uint64_t frac;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT64_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin = 0;
+		return result;
+	}
+	
+	frac = i;
+	frac <<= counter + 32 - 1;
+	
+	round_float64(&exp, &frac);
+	
+	result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float64 int32_to_float64(int32_t i)
+{
+	float64 result;
+	
+	if (i < 0)
+		result = uint32_to_float64((uint32_t) (-i));
+	else
+		result = uint32_to_float64((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+
+float64 uint64_to_float64(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	float64 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT64_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin = 0;
+		return result;
+	}
+	
+	if (counter > 0) {
+		i <<= counter - 1;
+	} else {
+		i >>= 1;
+	}
+	
+	round_float64(&exp, &i);
+	
+	result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	return result;
+}
+
+float64 int64_to_float64(int64_t i)
+{
+	float64 result;
+	
+	if (i < 0)
+		result = uint64_to_float64((uint64_t) (-i));
+	else
+		result = uint64_to_float64((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float128 uint32_to_float128(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = 0;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT128_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin.hi = 0;
+		result.bin.lo = 0;
+		return result;
+	}
+	
+	frac_hi = 0;
+	frac_lo = i;
+	lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
+	
+	round_float128(&exp, &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float128 int32_to_float128(int32_t i)
+{
+	float128 result;
+	
+	if (i < 0)
+		result = uint32_to_float128((uint32_t) (-i));
+	else
+		result = uint32_to_float128((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+
+float128 uint64_to_float128(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = 0;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT128_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin.hi = 0;
+		result.bin.lo = 0;
+		return result;
+	}
+	
+	frac_hi = 0;
+	frac_lo = i;
+	lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
+	
+	round_float128(&exp, &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float128 int64_to_float128(int64_t i)
+{
+	float128 result;
+	
+	if (i < 0)
+		result = uint64_to_float128((uint64_t) (-i));
+	else
+		result = uint64_to_float128((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+/** @}
+ */
