1 /*
2 * Copyright (c) 1998-2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include "global.h"
19
20 /* This file provides the necessary routines for 64-bit integer formatted
21 * I/O support. This file is essentially a copy of the utils.c with
22 * the exception that TM_I8 => integer*4 is the natural integer and
23 * integer*8 is an extension. All of these support routines could be
24 * rewritten to use the appropriate C type which represents a 64-bit
25 * integer rather than DBLINT64/DBLUINT64.
26 */
27 int __ftn_32in64_;
28
29 extern void __utl_i_add64(), __utl_i_sub64();
30 extern void __utl_i_div64(), __utl_i_mul64();
31 static void neg64(), shf64();
32 static int toi64(), ucmp64();
33
34 extern int __fort_atoxi32();
35 extern int __fort_atoxi64();
36 extern void __fort_i64toax();
37
38 /* has native support for 8-byte integers*/
39 #if !defined(WIN64)
40 typedef long I8_T;
41 typedef unsigned long UI8_T;
42 #else
43 typedef __int64 I8_T;
44 typedef unsigned __int64 UI8_T;
45 #endif
46
47 typedef union {
48 UI8_T u8;
49 I8_T i8;
50 struct {
51 int lsw;
52 int msw;
53 } ovl8;
54 } OVL8;
55 #define NATIVEI8
56
57 /* ***************************************************************
58 *
59 * char string to 32-bit integer.
60 *
61 * Arguments:
62 *
63 * s Input string containing number to be converted
64 * (string is NOT null terminated.)
65 * i Pointer to returned integer value
66 * n Number of chars from str to convert
67 * base Radix of conversion -- 2, 8, 10, 16. If
68 * base is 16, then the digits a-f or A-F are
69 * allowed.
70 *
71 * Return Value:
72 *
73 * -1 str does not represent a valid number in radix base
74 * -2 overflow occurred on conversion
75 * 0 No error -- *ival contains the converted number.
76 *
77 * Description:
78 *
79 * This routine accepts char strings representing integers
80 * in any base of 16 or less. The numbers must fit into
81 * a 32-bit signed or unsigned integer. Only one preceding
82 * sign char is allowed for all bases of numbers.
83 *
84 * NOTE:
85 * This routine only works on 2's complement machines.
86 *
87 ****************************************************************/
88
89 int
__fort_atoxi32(char * s,INT * i,int n,int base)90 __fort_atoxi32(char *s, INT *i, int n, int base)
91 {
92 register char *end;
93 register INT value;
94 int sign;
95 UINT xval, yval;
96
97 /* Skip any leading blanks. */
98 end = s + n;
99 *i = 0;
100 for (; s < end && *s == ' '; s++)
101 ;
102
103 /* Are there any chars left? */
104 if (s >= end)
105 return (-1);
106
107 /* Look for a sign char. */
108 sign = 1;
109 if (*s == '-') {
110 sign = -1;
111 s++;
112 } else if (*s == '+')
113 s++;
114
115 /* Are there any chars left? */
116 if (s >= end)
117 return (-1);
118
119 switch (base) {
120 case 2:
121 for (value = 0; s < end; s++) {
122 if ((value & 0x80000000L) != 0)
123 goto ovflo;
124
125 value <<= 1;
126
127 if (*s < '0' || *s > '1')
128 return (-1);
129
130 if (*s == '1')
131 value |= 1L;
132 }
133 break;
134 case 8:
135 for (value = 0; s < end; s++) {
136 if ((value & 0xE0000000L) != 0)
137 goto ovflo;
138
139 value <<= 3;
140
141 if (*s < '0' || *s > '7')
142 return (-1);
143
144 value |= (*s - '0');
145 }
146 break;
147 case 16:
148 for (value = 0; s < end; s++) {
149 if ((value & 0xF0000000L) != 0)
150 goto ovflo;
151
152 value <<= 4;
153
154 if (*s < '0')
155 return (-1);
156 else if (*s <= '9')
157 value |= (*s - '0');
158 else if (*s < 'A')
159 return (-1);
160 else if (*s <= 'F')
161 value |= (*s - 'A' + 10);
162 else if (*s < 'a')
163 return (-1);
164 else if (*s <= 'f')
165 value |= (*s - 'a' + 10);
166 else
167 return (-1);
168 }
169 break;
170 case 10:
171 /* use unsigned */
172 xval = yval = 0;
173 for (; s < end; s++) {
174 if (*s < '0' || *s > '9')
175 return -1;
176 xval *= 10;
177 xval += (*s - '0');
178 if ((xval & 0x80000000u) || (xval < yval)) {
179 value = 0xffffffffu; /* 4294967295u */
180 goto ovflo;
181 }
182 if (yval >= 0x0ccccccc && (xval - (*s - '0')) / 10 != yval) {
183 /* Limit this check to when yval >= max_int/10 */
184 value = 0xffffffffu; /* 4294967295u */
185 goto ovflo;
186 }
187 yval = xval;
188 }
189 value = xval;
190 break;
191 default:
192 return (-1);
193 }
194
195 if (sign == -1) {
196 if (((UINT)value & 0x80000000u) != 0 && (UINT)value != 0x80000000u)
197 goto ovflo;
198 *i = (~value) + 1;
199 } else
200 *i = value;
201 return (0);
202 ovflo:
203 *i = value;
204 return -2;
205 }
206
207 /* ***************************************************************
208 *
209 * char string to 64-bit integer.
210 *
211 * Arguments:
212 *
213 * s Input string containing number to be converted
214 * (string is NOT null terminated.)
215 * ir DBLUINT64 output value
216 * n Number of chars from str to convert
217 * radix Radix of conversion -- 2, 8, 10, 16. If
218 * base is 16, then the digits a-f or A-F are
219 * allowed.
220 *
221 * Return Value:
222 *
223 * -1 str does not represent a valid number in radix base
224 * -2 overflow occurred on conversion
225 * 0 No error -- *ir contains the converted number.
226 *
227 * Description:
228 *
229 * This routine accepts char strings representing integers
230 * in any base of 16 or less. The numbers must fit into
231 * a 64-bit signed. Only one preceding sign char is allowed
232 * for all bases of numbers.
233 *
234 * NOTE:
235 * This routine only works on 2's complement machines.
236 *
237 ****************************************************************/
238
239 int
__fort_atoxi64(char * s,DBLINT64 ir,int n,int radix)240 __fort_atoxi64(char *s, DBLINT64 ir, int n, int radix)
241 {
242 int err;
243 char *sp;
244 char *end;
245
246 /* eat whitespace */
247 end = s + n;
248 sp = s;
249 for (; sp < end && *sp == ' '; sp++)
250 n--;
251
252 if (n <= 0)
253 return (-1);
254
255 err = toi64(sp, ir, end, radix);
256
257 return (err);
258 }
259 /* **** __fort_i64toax
260 *
261 * Converts [un]signed 64 integer into a char string of
262 * the selected radix.
263 *
264 */
265
266 #define ASCII_OFFSET 48
267 #define ASTERISK '*'
268 #define BLANK ' '
269 #define HEX_OFFSET 7
270 #define MINUS '-'
271 #define ZERO '0'
272
273 void
__fort_i64toax(DBLINT64 from,char * to,int count,int sign,int radix)274 __fort_i64toax(DBLINT64 from, char *to, int count, int sign, int radix)
275 {
276 int bit_width; /* width of the bit field for a particular
277 * radix */
278 int bits_to_shift; /* number of bits to shift */
279 int idx; /* for loop control variable */
280 INT mask; /* mask for bit_width of a particular radix */
281 int max_shift; /* maximum number of bits from will will need
282 * to be shifted */
283 int msd; /* index of the most-signingicant digit in to */
284 int num_bits; /* number of bits to be shifted */
285 DBLINT64 quot; /* the quotient part of a 64 bit division */
286 DBLINT64 remain; /* the remainder part of a 64 bit division */
287 DBLINT64 temp_from; /* temp from (=(abs(from)) */
288 DBLINT64 temp64; /* temporary 64 bit integer */
289
290 /* 64 bit integer equal to 10 */
291 static DBLINT64 ten64 = {0, 10};
292
293 /* the result of dividing a 64 bit unsigned integer with only the
294 * sign bit on by 10
295 */
296 static INT msbdiv10[2] = {0xccccccc, 0xcccccccc};
297
298 if ((from[0] == 0) && (from[1] == 0)) {
299 msd = count - 1;
300 to[msd] = ASCII_OFFSET;
301 }
302 else if (radix == 10) {
303 OVL8 temp;
304 I8_T rem, quot;
305 if (sign == 0 && I64_MSH(from) == 0x80000000 && I64_LSH(from) == 0) {
306 if (count <= strlen("-9223372036854775808")) {
307 to[0] = ASTERISK;
308 to[1] = '\0';
309 } else
310 strcpy(to, "-9223372036854775808");
311 return;
312 }
313 if (sign == 1 && from[0] == -1 && from[1] == -1) {
314 strcpy(to, "-1");
315 return;
316 }
317 temp.ovl8.msw = I64_MSH(from);
318 temp.ovl8.lsw = I64_LSH(from);
319 if ((sign == 1) && (temp.ovl8.msw < 0)) {
320 temp.ovl8.msw = temp.ovl8.msw & 0x7fffffff; /* negate sign bit */
321 quot = temp.i8 / 10;
322 rem = temp.i8 - quot * 10;
323 rem = rem + 8; /* 8 = 2^63 % 10 */
324 temp.i8 = quot + 922337203685477580LL; /* add msbdiv10 */
325
326 if (rem >= 10) {
327 rem = rem - 10;
328 temp.i8 += 1;
329 }
330 msd = count - 2;
331 to[msd + 1] = ASCII_OFFSET + rem;
332 } else {
333 temp.ovl8.msw = I64_MSH(from);
334 temp.ovl8.lsw = I64_LSH(from);
335 if ((sign == 0) && (temp.ovl8.msw < 0))
336 temp.i8 = -temp.i8;
337 msd = count - 1;
338 }
339
340 while ((msd >= 0) && temp.i8 != 0) {
341 quot = temp.i8 / 10;
342 rem = temp.i8 - quot * 10;
343 to[msd] = ASCII_OFFSET + rem;
344 temp.i8 = quot;
345 msd = msd - 1;
346 }
347
348 if (msd == -1) {
349 if (temp.i8 == 0)
350 msd = 0;
351 } else
352 msd = msd + 1;
353 }
354 else {
355 temp_from[0] = I64_MSH(from);
356 temp_from[1] = I64_LSH(from);
357 if ((sign == 0) && (I64_MSH(from) < 0))
358 neg64(temp_from, temp_from);
359
360 switch (radix) {
361 case 2:
362 max_shift = 63;
363 bit_width = 1;
364 mask = 1;
365 break;
366 case 8:
367 max_shift = 63;
368 bit_width = 3;
369 mask = 7;
370 break;
371 case 16:
372 max_shift = 60;
373 bit_width = 4;
374 mask = 15;
375 break;
376 }
377
378 idx = count - 1;
379 for (num_bits = 0; num_bits <= max_shift; num_bits = num_bits + bit_width) {
380 if ((radix == 8) && (num_bits == 63))
381 mask = 1;
382
383 bits_to_shift = -num_bits;
384 shf64(temp_from, bits_to_shift, temp64);
385
386 to[idx] = ASCII_OFFSET + (temp64[1] & mask);
387
388 if (to[idx] != ASCII_OFFSET)
389 msd = idx;
390
391 if (to[idx] > '9')
392 to[idx] = to[idx] + HEX_OFFSET;
393
394 if (idx == 0) {
395 bits_to_shift = -(num_bits + bit_width);
396 shf64(temp_from, bits_to_shift, temp64);
397 if ((temp64[0] != 0) || (temp64[1] != 0))
398 msd = -1;
399 break; /* out of for loop */
400 } else
401 idx = idx - 1;
402 }
403 }
404
405 if ((msd == -1) || ((sign == 0) && (msd == 0) && (I64_MSH(from) < 0)))
406 to[0] = ASTERISK;
407 else if (msd == 0) {
408 to[0] = '0';
409 to[1] = '\0';
410 } else {
411 if ((sign == 0) && (I64_MSH(from) < 0)) {
412 msd = msd - 1;
413 to[msd] = MINUS;
414 }
415 for (idx = msd; idx < count; ++idx)
416 to[idx - msd] = to[idx];
417
418 idx = count - msd;
419 to[idx] = '\0';
420 }
421 }
422
423 /*
424 * error return value:
425 * -1 = bad format
426 * -2 = overflow / underflow
427 * 0 = no error.
428 */
toi64(char * s,DBLINT64 toi,char * end,int radix)429 static int toi64(char *s, DBLINT64 toi, char *end, int radix)
430 {
431 DBLINT64 base; /* 64 bit integer equal to radix */
432 DBLINT64 diff; /* difference between 2 64 bit integers, used
433 * in determining if overflow has occured */
434 DBLINT64 num; /* numerical value of a particular digit */
435 DBLINT64 to;
436 int negate;
437 int ch;
438
439 /* 64-bit integer with only its sign bit on */
440 static DBLINT64 sign_bit = {0x80000000, 0};
441
442 /* maximum 64-bit signed integer */
443 static DBLINT64 max_int = {0x7fffffff, 0xffffffff};
444 static DBLINT64 max_neg = {0x80000000, 0};
445
446 OVL8 pto;
447
448 negate = 0;
449 if (*s == '+')
450 s++;
451 else if (*s == '-') {
452 negate = 1;
453 s++;
454 }
455
456 if (s >= end)
457 return -1;
458
459 to[0] = 0;
460 to[1] = 0;
461 base[0] = 0;
462 base[1] = radix;
463 num[0] = 0;
464 toi[0] = 0;
465 toi[1] = 0;
466
467 switch (radix) {
468 case 2:
469 for (; s < end; s++) {
470 if (to[0] & 0x80000000L)
471 goto ovflo;
472
473 shf64(to, 1, to);
474
475 if (*s < '0' || *s > '1')
476 return -1;
477
478 if (*s == '1')
479 to[1] |= 1;
480 }
481 break;
482 case 8:
483 for (; s < end; s++) {
484 if (to[0] & 0xE0000000L)
485 goto ovflo;
486
487 shf64(to, 3, to);
488
489 if (*s < '0' || *s > '7')
490 return -1;
491
492 to[1] |= (*s - '0');
493 }
494 break;
495 case 16:
496 for (; s < end; s++) {
497 if (to[0] & 0xF0000000L)
498 goto ovflo;
499 shf64(to, 4, to);
500 ch = *s & 0xff;
501 if (ch < '0')
502 return (-1);
503 else if (ch <= '9')
504 to[1] |= (ch - '0');
505 else if (ch < 'A')
506 return (-1);
507 else if (ch <= 'F')
508 to[1] |= (ch - 'A' + 10);
509 else if (ch < 'a')
510 return (-1);
511 else if (ch <= 'f')
512 to[1] |= (ch - 'a' + 10);
513 else
514 return (-1);
515 }
516 break;
517 case 10:
518 pto.u8 = 0;
519 for (; s < end; s++) {
520 UI8_T prev;
521 prev = pto.u8;
522 ch = *s & 0xff;
523 if (ch < '0' || ch > '9')
524 return -1;
525 pto.u8 *= 10;
526 pto.u8 += ch - '0';
527 if (pto.u8 < prev) {
528 to[0] = max_int[0];
529 to[1] = max_int[1];
530 goto ovflo;
531 }
532 }
533 to[0] = pto.ovl8.msw;
534 to[1] = pto.ovl8.lsw;
535 break;
536 default:
537 return -1;
538 }
539
540 if (negate) {
541 if (ucmp64(to, sign_bit) == 1)
542 return -2;
543 neg64(to, to);
544 }
545
546 I64_MSH(toi) = to[0];
547 I64_LSH(toi) = to[1];
548 return 0;
549 ovflo:
550 return -2;
551 }
552
neg64(DBLINT64 arg,DBLINT64 result)553 static void neg64(DBLINT64 arg, DBLINT64 result)
554 {
555 int sign; /* sign of the low-order word of arg prior to
556 * being complemented */
557 sign = (unsigned)arg[1] >> 31;
558 result[0] = ~arg[0];
559 result[1] = (~arg[1]) + 1;
560 if (sign == 0 && result[1] >= 0)
561 result[0]++;
562 }
563
shf64(DBLINT64 arg1,INT arg2,DBLINT64 result)564 static void shf64(DBLINT64 arg1, INT arg2, DBLINT64 result)
565 {
566 DBLUINT64 u_arg; /* 'copy-in' unsigned value of arg */
567
568 if (arg2 >= 64 || arg2 <= -64) {
569 result[0] = 0;
570 result[1] = 0;
571 return;
572 }
573 u_arg[0] = arg1[0];
574 u_arg[1] = arg1[1];
575 if (arg2 >= 0) {
576 if (arg2 < 32) {
577 result[0] = (u_arg[0] << arg2) | (u_arg[1] >> (32 - arg2));
578 result[1] = u_arg[1] << arg2;
579 } else {
580 result[0] = u_arg[1] << (arg2 - 32);
581 result[1] = 0;
582 }
583 } else if (arg2 > -32) {
584 result[0] = arg1[0] >> -arg2; /* sign extend */
585 result[1] = (u_arg[1] >> -arg2) | (u_arg[0] << (arg2 + 32));
586 } else {
587 result[0] = arg1[0] >> 31; /* sign extend */
588 result[1] = arg1[0] >> (-arg2 - 32);
589 }
590 }
591
ucmp64(DBLUINT64 arg1,DBLUINT64 arg2)592 static int ucmp64(DBLUINT64 arg1, DBLUINT64 arg2)
593 {
594 if (arg1[0] == arg2[0]) {
595 if (arg1[1] == arg2[1])
596 return 0;
597 if (arg1[1] < arg2[1])
598 return -1;
599 return 1;
600 }
601 if (arg1[0] < arg2[0])
602 return -1;
603 return 1;
604 }
605
606 #ifdef MTHI64
607 static void __utl_i_mul128();
608 static void neg128(), uneg64(), ushf64(), shf128();
609
610 /*
611 * Add 2 64-bit integers
612 *
613 * Arguments:
614 * arg1, arg2 64-bit addends
615 * result 64-bit result of arg1 + arg2
616 *
617 * Return value:
618 * none
619 */
__utl_i_add64(DBLINT64 arg1,DBLINT64 arg2,DBLINT64 result)620 void __utl_i_add64(DBLINT64 arg1, DBLINT64 arg2, DBLINT64 result)
621 {
622 int carry; /* value to be carried from adding the lower
623 * 32 bits */
624 int sign_sum; /* sum of the sign bits of the low-order
625 * words of arg1 and arg2 */
626 sign_sum = ((unsigned)arg1[1] >> 31) + ((unsigned)arg2[1] >> 31);
627 result[1] = arg1[1] + arg2[1];
628 /*
629 * sign_sum = 2 -> carry guaranteed
630 * = 1 -> if sum sign bit off then carry
631 * = 0 -> carry not possible
632 */
633 carry = sign_sum > (int)((unsigned)result[1] >> 31);
634 result[0] = arg1[0] + arg2[0] + carry;
635 }
636
637 /*
638 * Subtract two 64-bit integers
639 *
640 * Arguments:
641 * arg1 minuend
642 * arg2 subtrahend
643 * result arg1 - arg2
644 *
645 * Return value:
646 * none
647 */
__utl_i_sub64(DBLINT64 arg1,DBLINT64 arg2,DBLINT64 result)648 void __utl_i_sub64(DBLINT64 arg1, DBLINT64 arg2, DBLINT64 result)
649
650 {
651 int borrow; /* value to be borrowed from adding the lower
652 * 32 bits */
653 int sign_diff; /* difference of the sign bits of the
654 * low-order words of arg1 and arg2 */
655
656 sign_diff = ((unsigned)arg1[1] >> 31) - ((unsigned)arg2[1] >> 31);
657 result[1] = arg1[1] - arg2[1];
658 /*
659 * sign_diff = -1 -> borrow guaranteed
660 * = 0 -> if diff sign bit on (arg2 > arg1) then borrow
661 * 1 -> borrow not possible
662 */
663 borrow = sign_diff < (int)((unsigned)result[1] >> 31);
664 result[0] = (arg1[0] - borrow) - arg2[0];
665 }
666
667 /*
668 *
669 * Multiply two 64-bit integers to produce a 64-bit
670 * integer product.
671 */
672
__utl_i_mul64(DBLINT64 arg1,DBLINT64 arg2,DBLINT64 result)673 void __utl_i_mul64(DBLINT64 arg1, DBLINT64 arg2, DBLINT64 result)
674 {
675 INT temp_result[4]; /* the product returned by MUL128 */
676
677 __utl_i_mul128(arg1, arg2, temp_result);
678 result[0] = temp_result[2];
679 result[1] = temp_result[3];
680 }
681
__utl_i_mul128(DBLINT64 arg1,DBLINT64 arg2,INT result[4])682 static void __utl_i_mul128(DBLINT64 arg1, DBLINT64 arg2, INT result[4])
683 {
684 int i; /* for loop control variable */
685 DBLINT64 temp_arg; /* temporary argument used in calculating the
686 * product */
687 INT temp_result[4]; /* temporary result */
688 int negate; /* flag which indicated the result needs to
689 * be negated */
690
691 if ((arg1[0] == 0 && arg1[1] == 0) || (arg2[0] == 0 && arg2[1] == 0)) {
692 result[0] = 0;
693 result[1] = 0;
694 result[2] = 0;
695 result[3] = 0;
696 return;
697 }
698 temp_result[0] = 0;
699 temp_result[1] = 0;
700
701 if (arg1[0] < 0) {
702 neg64(arg1, &temp_result[2]);
703 negate = 1;
704 } else {
705 temp_result[2] = arg1[0];
706 temp_result[3] = arg1[1];
707 negate = 0;
708 }
709
710 if (arg2[0] < 0) {
711 neg64(arg2, temp_arg);
712 negate = !negate;
713 } else {
714 temp_arg[0] = arg2[0];
715 temp_arg[1] = arg2[1];
716 }
717
718 for (i = 0; i < 64; ++i) {
719 if ((temp_result[3] & 1) == 1)
720 __utl_i_add64(temp_result, temp_arg, temp_result);
721
722 shf128(temp_result, -1, temp_result);
723 }
724
725 if (negate)
726 neg128(temp_result, result);
727 else
728 for (i = 0; i < 4; ++i)
729 result[i] = temp_result[i];
730 }
731
__utl_i_div64(DBLINT64 arg1,DBLINT64 arg2,DBLINT64 result)732 void __utl_i_div64(DBLINT64 arg1, DBLINT64 arg2, DBLINT64 result)
733 {
734 DBLINT64 den; /* denominator used in calculating the
735 * quotient */
736 int i; /* for loop control variable */
737 int temp_result[4]; /* temporary result used in
738 * calculating the quotient */
739 int negate; /* flag which indicates the result needs to
740 * be negated */
741 int one; /* one passed to shf128 */
742
743 if ((arg1[0] == 0 && arg1[1] == 0) || (arg2[0] == 0 && arg2[1] == 0)) {
744 result[0] = 0;
745 result[1] = 0;
746 return;
747 }
748 temp_result[0] = 0;
749 temp_result[1] = 0;
750
751 if (arg1[0] < 0) {
752 neg64(arg1, &temp_result[2]);
753 negate = 1;
754 } else {
755 temp_result[2] = arg1[0];
756 temp_result[3] = arg1[1];
757 negate = 0;
758 }
759
760 if (arg2[0] < 0) {
761 neg64(arg2, den);
762 negate = !negate;
763 } else {
764 den[0] = arg2[0];
765 den[1] = arg2[1];
766 }
767
768 one = 1;
769
770 for (i = 0; i < 64; ++i) {
771 shf128(temp_result, one, temp_result);
772 if (ucmp64(temp_result, den) >= 0) {
773 __utl_i_sub64(temp_result, den, temp_result);
774 temp_result[3] = temp_result[3] + 1;
775 }
776 }
777
778 if (negate)
779 neg64(&temp_result[2], result);
780 else {
781 result[0] = temp_result[2];
782 result[1] = temp_result[3];
783 }
784 }
785
neg128(INT arg[4],INT result[4])786 static void neg128(INT arg[4], INT result[4])
787
788 {
789 int i; /* loop control variable */
790 int sign; /* sign of the word of arg prior to being */
791
792 for (i = 0; i < 4; ++i)
793 result[i] = ~arg[i];
794
795 i = 3;
796 sign = (unsigned)result[i] >> 31;
797 result[i] = result[i] + 1;
798 while (i > 0 && sign == 1 && result[i] >= 0) {
799 i = i - 1;
800 sign = (unsigned)result[i] >> 31;
801 result[i] = result[i] + 1;
802 }
803 }
804
__utl_i_udiv64(DBLUINT64 arg1,DBLUINT64 arg2,DBLUINT64 result)805 void __utl_i_udiv64(DBLUINT64 arg1, DBLUINT64 arg2, DBLUINT64 result)
806 {
807 DBLUINT64 den; /* denominator used in calculating the
808 * quotient */
809 int i; /* for loop control variable */
810 int temp_result[4]; /* temporary result used in
811 * calculating the quotient */
812 int negate; /* flag which indicates the result needs to
813 * be negated */
814 int one; /* one passed to shf128 */
815
816 if ((arg1[0] == 0 && arg1[1] == 0) || (arg2[0] == 0 && arg2[1] == 0)) {
817 result[0] = 0;
818 result[1] = 0;
819 return;
820 }
821 temp_result[0] = 0;
822 temp_result[1] = 0;
823
824 if ((int)arg1[0] < 0) {
825 uneg64(arg1, &temp_result[2]);
826 negate = 1;
827 } else {
828 temp_result[2] = arg1[0];
829 temp_result[3] = arg1[1];
830 negate = 0;
831 }
832
833 if ((int)arg2[0] < 0) {
834 uneg64(arg2, den);
835 negate = !negate;
836 } else {
837 den[0] = arg2[0];
838 den[1] = arg2[1];
839 }
840
841 one = 1;
842
843 for (i = 0; i < 64; ++i) {
844 shf128(temp_result, one, temp_result);
845 if (ucmp64(temp_result, den) >= 0) {
846 __utl_i_sub64(temp_result, den, temp_result);
847 temp_result[3] = temp_result[3] + 1;
848 }
849 }
850
851 if (negate)
852 uneg64(&temp_result[2], result);
853 else {
854 result[0] = temp_result[2];
855 result[1] = temp_result[3];
856 }
857 }
858
uneg64(DBLUINT64 arg,DBLUINT64 result)859 static void uneg64(DBLUINT64 arg, DBLUINT64 result)
860 {
861 int sign; /* sign of the low-order word of arg prior to
862 * being complemented */
863
864 sign = (unsigned)arg[1] >> 31;
865 result[0] = ~arg[0];
866 result[1] = (~arg[1]) + 1;
867 if (sign == 0 && (int)result[1] >= 0)
868 result[0]++;
869 }
870
871 static void ushf64(DBLUINT64 arg, int count, DBLINT64 result)
872 int count;
873 DBLINT64 result;
874 {
875 DBLUINT64 u_arg; /* 'copy-in' unsigned value of arg */
876
877 if (count >= 64 || count <= -64) {
878 result[0] = 0;
879 result[1] = 0;
880 return;
881 }
882 if (count == 0) {
883 result[0] = arg[0];
884 result[1] = arg[1];
885 return;
886 }
887 u_arg[0] = arg[0];
888 u_arg[1] = arg[1];
889 if (count >= 0) {
890 if (count < 32) {
891 result[0] = (u_arg[0] << count) | (u_arg[1] >> 32 - count);
892 result[1] = u_arg[1] << count;
893 } else {
894 result[0] = u_arg[1] << count - 32;
895 result[1] = 0;
896 }
897 } else if (count > -32) {
898 result[0] = arg[0] >> -count;
899 result[1] = (u_arg[1] >> -count) | (u_arg[0] << count + 32);
900 } else {
901 result[0] = 0;
902 result[1] = arg[0] >> -count - 32;
903 }
904 }
905
shf128(INT arg[4],int count,INT result[4])906 static void shf128(INT arg[4], int count, INT result[4])
907 {
908
909 /* Local variables */
910
911 int i; /* for loop control variable */
912 int idx; /* index into result */
913 int num_bits; /* number of bits to be shifted */
914 UINT u_arg[4]; /* unsigned arg used in shift */
915
916 /* Function declarations */
917
918 #define _ABS(x) ((x) < 0 ? -(x) : (x))
919
920 if (_ABS(count) >= 128) {
921 for (i = 0; i < 4; ++i)
922 result[i] = 0;
923 return;
924 } /* end_if */
925 if (count == 0) {
926 for (i = 0; i < 4; ++i)
927 result[i] = arg[i];
928 return;
929 }
930 for (i = 0; i < 4; ++i)
931 u_arg[i] = arg[i];
932
933 if (count > 0) {
934 num_bits = count % 32;
935 idx = 0;
936
937 for (i = (count / 32); i < 3; ++i) {
938 result[idx] = (u_arg[i] << num_bits) | (u_arg[i + 1] >> (32 - num_bits));
939 idx = idx + 1;
940 } /* end_for */
941
942 result[idx] = (u_arg[3] << num_bits);
943
944 if (idx < 3)
945 for (i = idx + 1; i < 4; ++i)
946 result[i] = 0;
947 } else {
948 num_bits = (-(count)) % 32;
949 idx = 3;
950
951 for (i = 3 - ((-(count)) / 32); i > 0; --i) {
952 result[idx] = (u_arg[i] >> num_bits) | (u_arg[i - 1] << (32 - num_bits));
953 idx--;
954 }
955
956 result[idx] = (u_arg[0] >> num_bits);
957
958 if (idx > 0)
959 for (i = 0; i < idx; ++i)
960 result[i] = 0;
961 }
962 }
963 #endif /* #ifdef MTHI64 */
964
965