177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* This file is distributed under the University of Illinois Open Source 277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * License. See LICENSE.TXT for details. 377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao */ 477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* uint64_t __fixunstfdi(long double x); */ 677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* This file implements the PowerPC 128-bit double-double -> uint64_t conversion */ 777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#include "DD.h" 977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#include <stdint.h> 1077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 1177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaouint64_t __fixunstfdi(long double input) 1277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao{ 1377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const DD x = { .ld = input }; 1477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const doublebits hibits = { .d = x.s.hi }; 1577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 1677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const uint32_t highWordMinusOne = (uint32_t)(hibits.x >> 32) - UINT32_C(0x3ff00000); 1777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 1877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* If (1.0 - tiny) <= input < 0x1.0p64: */ 1977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao if (UINT32_C(0x04000000) > highWordMinusOne) 2077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao { 2177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const int unbiasedHeadExponent = highWordMinusOne >> 20; 2277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao uint64_t result = hibits.x & UINT64_C(0x000fffffffffffff); /* mantissa(hi) */ 2477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao result |= UINT64_C(0x0010000000000000); /* matissa(hi) with implicit bit */ 2577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao result <<= 11; /* mantissa(hi) left aligned in the int64 field. */ 2677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* If the tail is non-zero, we need to patch in the tail bits. */ 2877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao if (0.0 != x.s.lo) 2977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao { 3077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const doublebits lobits = { .d = x.s.lo }; 3177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int64_t tailMantissa = lobits.x & INT64_C(0x000fffffffffffff); 3277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao tailMantissa |= INT64_C(0x0010000000000000); 3377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 3477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* At this point we have the mantissa of |tail| */ 3577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 3677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const int64_t negationMask = ((int64_t)(lobits.x)) >> 63; 3777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao tailMantissa = (tailMantissa ^ negationMask) - negationMask; 3877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 3977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* Now we have the mantissa of tail as a signed 2s-complement integer */ 4077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao const int biasedTailExponent = (int)(lobits.x >> 52) & 0x7ff; 4277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* Shift the tail mantissa into the right position, accounting for the 4477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * bias of 11 that we shifted the head mantissa by. 4577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao */ 4677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao tailMantissa >>= (unbiasedHeadExponent - (biasedTailExponent - (1023 - 11))); 4777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao result += tailMantissa; 4977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao } 5077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 5177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao result >>= (63 - unbiasedHeadExponent); 5277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao return result; 5377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao } 5477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 5577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* Edge cases are handled here, with saturation. */ 5677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao if (1.0 > x.s.hi) 5777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao return UINT64_C(0); 5877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao else 5977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao return UINT64_MAX; 6077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao} 61