/* This file is distributed under the University of Illinois Open Source
 * License. See LICENSE.TXT for details.
 */

/* int64_t __fixunstfdi(long double x);
 * This file implements the PowerPC 128-bit double-double -> int64_t conversion
 */

#include "DD.h"
#include <stdint.h>

uint64_t __fixtfdi(long double input)
{
	const DD x = { .ld = input };
	const doublebits hibits = { .d = x.s.hi };
	
	const uint32_t absHighWord = (uint32_t)(hibits.x >> 32) & UINT32_C(0x7fffffff);
	const uint32_t absHighWordMinusOne = absHighWord - UINT32_C(0x3ff00000);
	
	/* If (1.0 - tiny) <= input < 0x1.0p63: */
	if (UINT32_C(0x03f00000) > absHighWordMinusOne)
	{
		/* Do an unsigned conversion of the absolute value, then restore the sign. */
		const int unbiasedHeadExponent = absHighWordMinusOne >> 20;
		
		int64_t result = hibits.x & INT64_C(0x000fffffffffffff); /* mantissa(hi) */
		result |= INT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */
		result <<= 10; /* mantissa(hi) with one zero preceeding bit. */
		
		const int64_t hiNegationMask = ((int64_t)(hibits.x)) >> 63;
		
		/* If the tail is non-zero, we need to patch in the tail bits. */
		if (0.0 != x.s.lo)
		{
			const doublebits lobits = { .d = x.s.lo };
			int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
			tailMantissa |= INT64_C(0x0010000000000000);
			
			/* At this point we have the mantissa of |tail| */
			/* We need to negate it if head and tail have different signs. */
			const int64_t loNegationMask = ((int64_t)(lobits.x)) >> 63;
			const int64_t negationMask = loNegationMask ^ hiNegationMask;
			tailMantissa = (tailMantissa ^ negationMask) - negationMask;
			
			/* Now we have the mantissa of tail as a signed 2s-complement integer */
			
			const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
			
			/* Shift the tail mantissa into the right position, accounting for the
			 * bias of 10 that we shifted the head mantissa by.
			 */ 
			tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 10)));
			
			result += tailMantissa;
		}
		
		result >>= (62 - unbiasedHeadExponent);
		
		/* Restore the sign of the result and return */
		result = (result ^ hiNegationMask) - hiNegationMask;
		return result;
		
	}

	/* Edge cases handled here: */
	
	/* |x| < 1, result is zero. */
	if (1.0 > __builtin_fabs(x.s.hi))
		return INT64_C(0);
	
	/* x very close to INT64_MIN, care must be taken to see which side we are on. */
	if (x.s.hi == -0x1.0p63) {
		
		int64_t result = INT64_MIN;
		
		if (0.0 < x.s.lo)
		{
			/* If the tail is positive, the correct result is something other than INT64_MIN.
			 * we'll need to figure out what it is.
			 */

			const doublebits lobits = { .d = x.s.lo };
			int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff);
			tailMantissa |= INT64_C(0x0010000000000000);
			
			/* Now we negate the tailMantissa */
			tailMantissa = (tailMantissa ^ INT64_C(-1)) + INT64_C(1);
			
			/* And shift it by the appropriate amount */
			const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff;
			tailMantissa >>= 1075 - biasedTailExponent;
			
			result -= tailMantissa;
		}
		
		return result;
	}
	
	/* Signed overflows, infinities, and NaNs */
	if (x.s.hi > 0.0)
		return INT64_MAX;
	else
		return INT64_MIN;
}
