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