OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [powerpc/] [strtosfix64.c] - Blame information for rev 826

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
#ifdef __SPE__
2
 
3
#include <_ansi.h>
4
#include <limits.h>
5
#include <errno.h>
6
#include <stdlib.h>
7
#include <reent.h>
8
#include "fix64.h"
9
 
10
/*
11
 * Convert a string to a fixed-point (sign + 63-bits) value.
12
 *
13
 * Ignores `locale' stuff.
14
 */
15
__int64_t
16
_DEFUN (_strtosfix64_r, (rptr, nptr, endptr),
17
        struct _reent *rptr _AND
18
        _CONST char *nptr _AND
19
        char **endptr)
20
{
21
  union long_double_union ldbl;
22
  int exp, negexp, sign, ld_type;
23
  __uint64_t tmp, tmp2;
24
  __int64_t result = 0;
25
 
26
  init(ldbl);
27
 
28
  _simdstrtold ((char *)nptr, endptr, &ldbl);
29
 
30
  /* treat NAN as domain error, +/- infinity as saturation */
31
  ld_type = _simdldcheck (&ldbl);
32
  if (ld_type != 0)
33
    {
34
      if (ld_type == 1)
35
        {
36
          rptr->_errno = EDOM;
37
          return 0;
38
        }
39
      rptr->_errno = ERANGE;
40
      if (word0(ldbl) & Sign_bit)
41
        return LONG_LONG_MIN;
42
      return LONG_LONG_MAX;
43
    }
44
 
45
  /* strip off sign and exponent */
46
  sign = word0(ldbl) & Sign_bit;
47
  exp = ((word0(ldbl) & Exp_mask) >> Exp_shift) - Bias;
48
  negexp = -exp;
49
  if (negexp > 63)
50
    return 0;
51
  word0(ldbl) &= ~(Exp_mask | Sign_bit);
52
  /* add in implicit normalized bit */
53
  word0(ldbl) |= Exp_msk1;
54
  /* shift so result is contained in single word */
55
  tmp = word0(ldbl) << Ebits;
56
  tmp |= ((unsigned long)word1(ldbl) >> (32 - Ebits));
57
  tmp <<= 32;
58
  if (Ebits < 32)
59
    tmp |= ((unsigned long)word1(ldbl) << Ebits);
60
  tmp |= ((unsigned long)word2(ldbl) >> (32 - Ebits));
61
 
62
  /* check for saturation */
63
  if (sign)
64
    {
65
      if (exp > 0 || (exp == 0 && tmp != 0x8000000000000000LL))
66
        {
67
          rptr->_errno = ERANGE;
68
          return LONG_LONG_MIN;
69
        }
70
    }
71
  else
72
    {
73
      if (exp >= 0)
74
        {
75
          rptr->_errno = ERANGE;
76
          return LONG_LONG_MAX;
77
        }
78
    }
79
 
80
  /* otherwise we have normal number in range */
81
  if (negexp != 0)
82
    {
83
      /* perform rounding */
84
      tmp2 = tmp + (1 << (negexp - 1));
85
      result = (long long)(tmp2 >> negexp);
86
      /* check if rounding caused carry bit which must be added into result */
87
      if (tmp2 < tmp)
88
        result |= (1 << (64 - negexp));
89
      /* check if positive saturation has occurred because of rounding */
90
      if (!sign && result < 0)
91
        {
92
          rptr->_errno = ERANGE;
93
          return LONG_LONG_MAX;
94
        }
95
    }
96
  else
97
    {
98
      /* we have -1.0, no rounding necessary */
99
      return LONG_LONG_MIN;
100
    }
101
 
102
  return sign ? -result : result;
103
}
104
 
105
#ifndef _REENT_ONLY
106
 
107
__int64_t
108
_DEFUN (strtosfix64, (s, ptr, base),
109
        _CONST char *s _AND
110
        char **ptr)
111
{
112
  return _strtosfix64_r (_REENT, s, ptr);
113
}
114
 
115
#endif
116
 
117
#endif /* __SPE__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.