Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ufix64toa.c « powerpc « machine « libc « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4d3d0a8851ae5b80442b12fd0c4e38596a1a3152 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* _ufix64toa_r: convert unsigned 64-bit fixed point to ASCII string.
 *
 * This routine converts an unsigned fixed-point number to long double format and
 * then calls _ldtoa_r to do the conversion.
 *
 * Written by Jeff Johnston.
 */

#include <_ansi.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
#include "fix64.h"

extern char *_simdldtoa_r _PARAMS((struct _reent *, LONG_DOUBLE_UNION *, int,
			       int, int *, int *, char **));

/*
 * Convert an unsigned fixed-point 64-bit value to string.
 *
 * Ignores `locale' stuff.
 */

char *
_DEFUN (_ufix64toa_r, (rptr, value, mode, ndigits, decpt, sign, rve),
	struct _reent *rptr _AND
	__uint64_t value _AND
	int mode _AND
	int ndigits _AND
	int *decpt _AND
	int *sign _AND
	char **rve)
{
  union long_double_union ldbl;
  union fix64_union fix64;
  unsigned long tmp;
  int exp, negexp;

  /* if input is 0, no additional work is needed */
  if (value == 0)
    {
      ldbl.i[0] = ldbl.i[1] = ldbl.i[2] = ldbl.i[3] = 0;
    }
  else /* otherwise, we calculate long double equivalent of value */
    {
      /* find exponent by locating most-significant one-bit */
      fix64.ll = value;
      negexp = 1;
      if (hiword(fix64) == 0)
	{
	  tmp = loword(fix64);
	  negexp = 33;
	}
      else
	{
	  tmp = hiword(fix64);
	  negexp = 1;
	}

      while (negexp < 65)
	{
	  if (tmp & 0x80000000)
	    break;
	  ++negexp;
	  tmp <<= 1;
	}
      
      /* shift input appropriately */
      fix64.ll = value << (negexp - 1 + (Exp_msk1 != 0));
      
      /* build long double */
      exp = -negexp + Bias;
      word0(ldbl) = (exp << Exp_shift);
      word1(ldbl) = hiword(fix64) << (32-Ebits);
      word2(ldbl) = loword(fix64) << (32-Ebits);
      word3(ldbl) = 0;
      if (Ebits < 32)
	{
	  word0(ldbl) |= hiword(fix64) >> Ebits;
	  word1(ldbl) |= loword(fix64) >> Ebits;
	}
    }

  /* convert long double to character */
  return _simdldtoa_r (rptr, &ldbl, mode, ndigits, decpt, sign, rve);
}