Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
dmisc.c
Go to the documentation of this file.
1 /****************************************************************
2 
3 The author of this software is David M. Gay.
4 
5 Copyright (C) 1998 by Lucent Technologies
6 All Rights Reserved
7 
8 Permission to use, copy, modify, and distribute this software and
9 its documentation for any purpose and without fee is hereby
10 granted, provided that the above copyright notice appear in all
11 copies and that both that the copyright notice and this
12 permission notice and warranty disclaimer appear in supporting
13 documentation, and that the name of Lucent or any of its entities
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
16 permission.
17 
18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25 THIS SOFTWARE.
26 
27 ****************************************************************/
28 
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30  * with " at " changed at "@" and " dot " changed to "."). */
31 
32 #include "gdtoaimp.h"
33 
34 #ifndef MULTIPLE_THREADS
36 #endif
37 
38 char*
39 #ifdef KR_headers
40  rv_alloc(i) int i;
41 #else
42 rv_alloc(int i)
43 #endif
44 {
45  int k, *r;
46  size_t j;
47 
48  j = sizeof(ULong);
49  for(k = 0; sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (size_t)i; j <<= 1)
50  {
51  k++;
52  }
53  r = (int*)Balloc(k);
54  *r = k;
55  return
56 #ifndef MULTIPLE_THREADS
57  dtoa_result =
58 #endif
59  (char*)(r + 1);
60 }
61 
62 char *
63 #ifdef KR_headers
64  nrv_alloc(s, rve, n) char *s,
65  **rve;
66 int n;
67 #else
68  nrv_alloc(char* s, char** rve, int n)
69 #endif
70 {
71  char *rv, *t;
72 
73  t = rv = rv_alloc(n);
74  while((*t = *s++) != 0)
75  {
76  {
77  t++;
78  }
79  }
80  if(rve)
81  {
82  {
83  *rve = t;
84  }
85  }
86  return rv;
87 }
88 
89 /* freedtoa(s) must be used to free values s returned by dtoa
90  * when MULTIPLE_THREADS is #defined. It should be used in all cases,
91  * but for consistency with earlier versions of dtoa, it is optional
92  * when MULTIPLE_THREADS is not defined.
93  */
94 
95 void
96 #ifdef KR_headers
97  freedtoa(s) char* s;
98 #else
99 freedtoa(char *s)
100 #endif
101 {
102  Bigint* b = (Bigint*)((void*)(s - sizeof(int*)));
103  b->maxwds = 1 << (b->k = *(int*)b);
104  Bfree(b);
105 #ifndef MULTIPLE_THREADS
106  if(s == dtoa_result)
107  {
108  dtoa_result = 0;
109  }
110 #endif
111 }
112 
113 int quorem
114 #ifdef KR_headers
115  (b, S) Bigint *b,
116  *S;
117 #else
118  (Bigint* b, Bigint* S)
119 #endif
120 {
121  int n;
122  ULong *bx, *bxe, q, *sx, *sxe;
123 #ifdef ULLong
124  ULLong borrow, carry, y, ys;
125 #else
126  ULong borrow, carry, y, ys;
127 #ifdef Pack_32
128  ULong si, z, zs;
129 #endif
130 #endif
131 
132  n = S->wds;
133 #ifdef DEBUG
134  /*debug*/ if(b->wds > n)
135  /*debug*/ Bug("oversize b in quorem");
136 #endif
137  if(b->wds < n)
138  {
139  {
140  return 0;
141  }
142  }
143  sx = S->x;
144  sxe = sx + --n;
145  bx = b->x;
146  bxe = bx + n;
147  q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
148 #ifdef DEBUG
149  /*debug*/ if(q > 9)
150  /*debug*/ Bug("oversized quotient in quorem");
151 #endif
152  if(q)
153  {
154  borrow = 0;
155  carry = 0;
156  do
157  {
158 #ifdef ULLong
159  ys = *sx++ * (ULLong)q + carry;
160  carry = ys >> 32;
161  y = *bx - (ys & 0xffffffffUL) - borrow;
162  borrow = y >> 32 & 1UL;
163  *bx++ = y & 0xffffffffUL;
164 #else
165 #ifdef Pack_32
166  si = *sx++;
167  ys = (si & 0xffff) * q + carry;
168  zs = (si >> 16) * q + (ys >> 16);
169  carry = zs >> 16;
170  y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
171  borrow = (y & 0x10000) >> 16;
172  z = (*bx >> 16) - (zs & 0xffff) - borrow;
173  borrow = (z & 0x10000) >> 16;
174  Storeinc(bx, z, y);
175 #else
176  ys = *sx++ * q + carry;
177  carry = ys >> 16;
178  y = *bx - (ys & 0xffff) - borrow;
179  borrow = (y & 0x10000) >> 16;
180  *bx++ = y & 0xffff;
181 #endif
182 #endif
183  } while(sx <= sxe);
184  if(!*bxe)
185  {
186  bx = b->x;
187  while(--bxe > bx && !*bxe)
188  {
189  --n;
190  }
191  b->wds = n;
192  }
193  }
194  if(cmp(b, S) >= 0)
195  {
196  q++;
197  borrow = 0;
198  carry = 0;
199  bx = b->x;
200  sx = S->x;
201  do
202  {
203 #ifdef ULLong
204  ys = *sx++ + carry;
205  carry = ys >> 32;
206  y = *bx - (ys & 0xffffffffUL) - borrow;
207  borrow = y >> 32 & 1UL;
208  *bx++ = y & 0xffffffffUL;
209 #else
210 #ifdef Pack_32
211  si = *sx++;
212  ys = (si & 0xffff) + carry;
213  zs = (si >> 16) + (ys >> 16);
214  carry = zs >> 16;
215  y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
216  borrow = (y & 0x10000) >> 16;
217  z = (*bx >> 16) - (zs & 0xffff) - borrow;
218  borrow = (z & 0x10000) >> 16;
219  Storeinc(bx, z, y);
220 #else
221  ys = *sx++ + carry;
222  carry = ys >> 16;
223  y = *bx - (ys & 0xffff) - borrow;
224  borrow = (y & 0x10000) >> 16;
225  *bx++ = y & 0xffff;
226 #endif
227 #endif
228  } while(sx <= sxe);
229  bx = b->x;
230  bxe = bx + n;
231  if(!*bxe)
232  {
233  while(--bxe > bx && !*bxe)
234  {
235  --n;
236  }
237  b->wds = n;
238  }
239  }
240 
241  // TODO: why is an int being returned?
242  return (int)q;
243 }
ULong x[1]
Definition: gdtoaimp.h:488
int wds
Definition: gdtoaimp.h:487
#define UL
Definition: qnan.c:66
struct Bigint Bigint
Definition: gdtoaimp.h:491
void freedtoa(char *s)
Definition: dmisc.c:99
char * rv_alloc(int i)
Definition: dmisc.c:42
#define ULLong
Definition: gdtoaimp.h:461
int quorem(Bigint *b, Bigint *S)
Definition: dmisc.c:118
int maxwds
Definition: gdtoaimp.h:487
#define Storeinc(a, b, c)
Definition: gdtoaimp.h:318
char * nrv_alloc(char *s, char **rve, int n)
Definition: dmisc.c:68
unsigned Long ULong
Definition: gdtoa.h:41
char * dtoa_result
Definition: dmisc.c:35
void Bfree(Bigint *v)
Definition: misc.c:92
int cmp(Bigint *a, Bigint *b)
Definition: misc.c:570
Bigint * Balloc(int k)
Definition: misc.c:47
int k
Definition: gdtoaimp.h:487