Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/ip_t/fv.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2000-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* Phong Vo <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
/*
23
* unsigned fixed vector arithmetic
24
*/
25
26
#include <fv.h>
27
28
#undef _BLD_DEBUG
29
30
int
31
fvcmp(int n, const unsigned char* a, const unsigned char* b)
32
{
33
register int i;
34
35
for (i = 0; i < n; i++)
36
if (a[i] < b[i])
37
return -1;
38
else if (a[i] > b[i])
39
return 1;
40
return 0;
41
}
42
43
int
44
fvset(int n, unsigned char* r, long v)
45
{
46
register int i;
47
48
i = n;
49
while (i--)
50
{
51
r[i] = v;
52
v >>= 8;
53
}
54
return v ? -1 : 0;
55
}
56
57
int
58
fvior(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
59
{
60
register int i;
61
62
for (i = 0; i < n; i++)
63
r[i] = a[i] | b[i];
64
return 0;
65
}
66
67
int
68
fvxor(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
69
{
70
register int i;
71
72
for (i = 0; i < n; i++)
73
r[i] = a[i] ^ b[i];
74
return 0;
75
}
76
77
int
78
fvand(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
79
{
80
register int i;
81
82
for (i = 0; i < n; i++)
83
r[i] = a[i] & b[i];
84
return 0;
85
}
86
87
int
88
fvodd(int n, const unsigned char* a)
89
{
90
return a[n-1] & 1;
91
}
92
93
int
94
fvlsh(int n, unsigned char* r, const unsigned char* a, int v)
95
{
96
register int i;
97
register int b;
98
register int g;
99
100
if (g = v / 8)
101
{
102
for (i = 0; i < n - g; i++)
103
r[i] = r[i + g];
104
for (; i < n; i++)
105
r[i] = 0;
106
}
107
if (b = v % 8)
108
{
109
for (i = 0; i < n - 1; i++)
110
r[i] = (r[i] << b) | (r[i + 1] >> (8 - b));
111
r[i] <<= b;
112
}
113
return 0;
114
}
115
116
int
117
fvrsh(int n, unsigned char* r, const unsigned char* a, int v)
118
{
119
register int i;
120
register int b;
121
register int g;
122
123
if (g = v / 8)
124
{
125
for (i = n - 1; i >= g; i--)
126
r[i] = r[i - g];
127
for (; i >= 0; i--)
128
r[i] = 0;
129
}
130
if (b = v % 8)
131
{
132
for (i = n - 1; i > 0; i--)
133
r[i] = (r[i] >> b) | (r[i - 1] << (8 - b));
134
r[i] >>= b;
135
}
136
return 0;
137
}
138
139
int
140
fvnot(int n, unsigned char* r, const unsigned char* a)
141
{
142
register int i;
143
144
for (i = 0; i < n; i++)
145
r[i] = ~a[i];
146
return 0;
147
}
148
149
int
150
fvadd(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
151
{
152
register int i;
153
register int c;
154
register int t;
155
156
c = 0;
157
i = n;
158
while (i--)
159
{
160
c = (t = a[i] + b[i] + c) > 0xff;
161
r[i] = t;
162
}
163
return -c;
164
}
165
166
int
167
fvsub(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
168
{
169
register int i;
170
register int c;
171
register int t;
172
173
c = 0;
174
i = n;
175
while (i--)
176
{
177
c = (t = a[i] - b[i] - c) < 0;
178
r[i] = t;
179
}
180
#if _BLD_DEBUG
181
sfprintf(sfstdout, "fvsub ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) - ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) = ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) [%d]\n",
182
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
183
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15],
184
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15],
185
-c);
186
#endif
187
return -c;
188
}
189
190
int
191
fvmpy(int n, unsigned char* r, const unsigned char* a, const unsigned char* b)
192
{
193
register int i;
194
register int j;
195
register int m;
196
register int c;
197
register int t;
198
199
fvset(n, r, 0);
200
for (i = 0; i < n - 1 && !a[i]; i++);
201
while (i < n)
202
{
203
m = a[i++];
204
c = 0;
205
j = n;
206
while (j--)
207
{
208
c = (t = m * b[j] + c) >> 8;
209
r[j] += t;
210
}
211
if (c)
212
return -1;
213
}
214
return 0;
215
}
216
217
int
218
fvdiv(int n, unsigned char* r, unsigned char* m, const unsigned char* a, const unsigned char* b)
219
{
220
register int i;
221
register int j;
222
register int k;
223
register int s;
224
register int x;
225
register int y;
226
unsigned char* d;
227
unsigned char* t;
228
unsigned char* u;
229
unsigned char* v;
230
231
for (j = 0; j < n && !b[j]; j++);
232
#if _BLD_DEBUG
233
sfprintf(sfstdout, "fvdiv ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) / ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) [%d]\n",
234
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
235
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15],
236
j);
237
#endif
238
if (j == n)
239
return -1;
240
if (!(d = newof(0, unsigned char, 3 * n, 0)))
241
return -1;
242
fvcpy(n, u = d + n, a);
243
v = u + n;
244
fvset(n, r, 0);
245
for (;;)
246
{
247
for (i = 0; i < n && !u[i]; i++);
248
if (i > j)
249
break;
250
x = u[i];
251
y = b[j];
252
if (x >= y)
253
{
254
if (j == 0)
255
break;
256
for (s = 0; x >= (y << (s + 1)); s++);
257
for (;;)
258
{
259
for (k = 0; k < i; k++)
260
d[k] = 0;
261
for (x = j; x < n; x++)
262
{
263
d[k - 1] |= b[x] >> (8 - s);
264
d[k] = b[x] << s;
265
k++;
266
}
267
while (k < n)
268
d[k++] = 0;
269
if (!fvsub(n, v, u, d))
270
break;
271
if (!s--)
272
goto done;
273
}
274
r[i] |= 1<<s;
275
}
276
else if (i == (n - 1))
277
break;
278
else
279
{
280
for (s = 0; x < (y >> (s + 1)); s++);
281
for (;;)
282
{
283
for (k = 0; k < i; k++)
284
d[k] = 0;
285
d[k] = 0;
286
for (x = j; x < n; x++)
287
{
288
d[k] |= b[x] >> s;
289
if (++k < n)
290
d[k] = b[x] << (8 - s);
291
}
292
while (++k < n)
293
d[k] = 0;
294
if (!fvsub(n, v, u, d))
295
break;
296
if (++s >= 8)
297
goto done;
298
}
299
r[i + 1] |= 1<<(8 - s);
300
}
301
t = u;
302
u = v;
303
v = t;
304
}
305
done:
306
free(d);
307
fvcpy(n, m, u);
308
#if _BLD_DEBUG
309
sfprintf(sfstdout, "fvdiv ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ) R ( %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x )\n",
310
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15],
311
m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
312
#endif
313
return 0;
314
}
315
316
char*
317
fmtfv(int n, const unsigned char* a, int x, int c, int g)
318
{
319
register int i;
320
register int p;
321
char* s;
322
char* o;
323
unsigned char* b;
324
unsigned char* d;
325
unsigned char* r;
326
int m;
327
328
static const char digit[] = "0123456789abcdef";
329
330
if (x != 8 && x != 10 && x != 16)
331
x = 10;
332
m = n * 3 + 4;
333
if (g > 0)
334
m += n / g;
335
s = fmtbuf(m) + m;
336
*--s = 0;
337
o = s;
338
p = c ? g : 0;
339
if (b = newof(0, unsigned char, 3 * n, 0))
340
{
341
fvcpy(n, b, a);
342
fvset(n, d = b + n, x);
343
r = d + n;
344
for (;;)
345
{
346
i = n;
347
while (--i && !b[i]);
348
if (!i && !b[i])
349
break;
350
fvdiv(n, b, r, b, d);
351
*--s = digit[r[n - 1]];
352
if (!--p)
353
{
354
p = g;
355
*--s = c;
356
}
357
}
358
free(b);
359
}
360
if (*s == c)
361
s++;
362
if (s == o)
363
*--s = '0';
364
else if (x == 8)
365
*--s = '0';
366
else if (x == 16)
367
{
368
*--s = 'x';
369
*--s = '0';
370
}
371
return s;
372
}
373
374
int
375
strfv(int n, unsigned char* r, const char* s, char** e, int b, int d)
376
{
377
register int c;
378
register int i;
379
register int t;
380
register int x;
381
382
static unsigned char dig[256];
383
384
if (!dig[0])
385
{
386
memset(dig, 0xff, sizeof(dig));
387
for (i = '0'; i <= '9'; i++)
388
dig[i] = i - '0';
389
for (i = 'A'; i <= 'F'; i++)
390
dig[i] = 10 + i - 'A';
391
for (i = 'a'; i <= 'f'; i++)
392
dig[i] = 10 + i - 'a';
393
}
394
fvset(n, r, 0);
395
while (*s == ' ' || *s == '\t')
396
s++;
397
if (*s != '0')
398
{
399
if (!b)
400
b = 10;
401
}
402
else if (*(s + 1) == 'x' || *(s + 1) == 'X')
403
{
404
if (!b || b == 16)
405
{
406
s += 2;
407
b = 16;
408
}
409
}
410
else if (!b)
411
b = *(s + 1) >= '0' && *(s + 1) <= '9' ? 8 : 10;
412
while (c = *s++)
413
{
414
if (c == d)
415
continue;
416
else if ((c = dig[c]) == 0xff)
417
{
418
c = 0;
419
break;
420
}
421
x = 0;
422
i = n;
423
while (i--)
424
{
425
t = r[i] * b + x;
426
x = t >> 8;
427
r[i] = t;
428
}
429
i = n;
430
while (i--)
431
{
432
c = (t = r[i] + c) > 0xff;
433
r[i] = t;
434
if (!c)
435
break;
436
}
437
if (c)
438
break;
439
}
440
if (e)
441
*e = (char*)s - 1;
442
return -c;
443
}
444
445
#undef fvcpy
446
447
int
448
fvcpy(int n, unsigned char* r, const unsigned char* a)
449
{
450
memcpy(r, a, n);
451
return 0;
452
}
453
454
/*
455
* return the minimum prefix of a limited to m bits
456
*/
457
458
unsigned char*
459
fvplo(int z, int m, unsigned char* r, const unsigned char* a)
460
{
461
int i;
462
int n;
463
464
if (m)
465
{
466
fvcpy(z, r, a);
467
m = z * 8 - m;
468
n = m / 8;
469
m -= n * 8;
470
n++;
471
for (i = 1; i < n; i++)
472
r[z - i] = 0;
473
if (m)
474
r[z - n] &= ~((1<<m) - 1);
475
}
476
else
477
fvset(z, r, 0);
478
return r;
479
}
480
481
/*
482
* return the maximum prefix of a limited to m bits
483
*/
484
485
unsigned char*
486
fvphi(int z, int m, unsigned char* r, const unsigned char* a)
487
{
488
int i;
489
int n;
490
491
if (m)
492
{
493
fvcpy(z, r, a);
494
m = z * 8 - m;
495
n = m / 8;
496
m -= n * 8;
497
n++;
498
for (i = 1; i < n; i++)
499
r[z - i] = 0xFF;
500
if (m)
501
r[z - n] |= ((1<<m) - 1);
502
}
503
else
504
for (i = 0; i < z; i++)
505
r[i] = 0xFF;
506
return r;
507
}
508
509