windows-virtual-memory-20041224
[openafs.git] / src / WINNT / afsd / largeint95.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* Large integer support for DJGPP */
11
12 #include <stdlib.h>
13 #include "largeint95.h"
14
15 LARGE_INTEGER LargeIntegerAdd(LARGE_INTEGER a, LARGE_INTEGER b)
16 {
17   LARGE_INTEGER c;
18   long long *c1 = (long long *) &c;
19   long long *a1 = (long long *) &a;
20   long long *b1 = (long long *) &b;
21   *c1 = *a1 + *b1;
22   return c;
23 }
24   
25 LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b)
26 {
27   LARGE_INTEGER c;
28   long long *c1 = (long long *) &c;
29   long long *a1 = (long long *) &a;
30   long long *b1 = (long long *) &b;
31   *c1 = *a1 - *b1;
32   return c;
33 }
34   
35 LARGE_INTEGER ConvertLongToLargeInteger(unsigned long a)
36 {
37   LARGE_INTEGER n;
38
39   n.LowPart = a;
40   n.HighPart = 0;
41   return n;
42 }
43
44 LARGE_INTEGER LargeIntegerMultiplyLongByLong(unsigned long a, unsigned long b)
45 {
46   LARGE_INTEGER c;
47   long long *c1 = (long long *) &c;
48
49   *c1 = (long long) a * (long long) b;
50   return c;
51 }
52   
53 LARGE_INTEGER LargeIntegerMultiplyByLong(LARGE_INTEGER a, unsigned long b)
54 {
55   LARGE_INTEGER c;
56   long long *c1 = (long long *) &c;
57   long long *a1 = (long long *) &a;
58
59   *c1 = *a1 * (long long) b;
60   return c;
61 }
62   
63 unsigned long LargeIntegerDivideByLong(LARGE_INTEGER a, unsigned long b)
64 {
65   lldiv_t q;
66   long long *a1 = (long long *) &a;
67
68   q = lldiv(*a1, (long long) b);
69   return (unsigned long) q.quot;
70 }
71
72 #if 0
73 LARGE_INTEGER LargeIntegerAdd(LARGE_INTEGER a, LARGE_INTEGER b)
74 {
75   LARGE_INTEGER c;
76
77   c.LowPart = a.LowPart + b.LowPart;
78   c.HighPart = a.HighPart + b.HighPart;
79
80   /* not sure how to do a real carry */
81   if (c.LowPart < a.LowPart)
82     c.HighPart++;
83
84   return c;
85 }
86
87 LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b)
88 {
89   LARGE_INTEGER c;
90
91   c.LowPart = a.LowPart - b.LowPart;
92   c.HighPart = a.HighPart - b.HighPart;
93
94   /* borrow */
95   if (c.LowPart > a.LowPart)
96     c.HighPart--;
97
98   return c;
99 }
100
101 __inline__ unsigned long mult32(unsigned long a, unsigned long b,
102                                 unsigned long *ov)
103 {
104   unsigned long p, o;
105   
106   /* multiply low part and save the overflow bits */
107   __asm__ __volatile__ ("movl %2, %%eax\n
108                          mull %3, %%eax\n
109                          movl %%eax, %0\n
110                          movl %%edx, %1"
111                         : "=g" (p), "=g" (o)
112                         : "g" (a), "g" (b)
113                         : "ax", "dx", "memory"
114                         );
115   *ov = o;
116   return p;
117 }
118
119 __inline__ unsigned long div32(unsigned long a, unsigned long b,
120                                unsigned long *rem)
121 {
122   unsigned long q, r;
123   
124   /* multiply low part and save the overflow bits */
125   __asm__ __volatile__ ("movl %2, %%eax\n
126                          divl %3, %%eax\n
127                          movl %%eax, %0\n
128                          movl %%edx, %1"
129                         : "=g" (q), "=g" (r)
130                         : "g" (a), "g" (b)
131                         : "ax", "dx", "memory"
132                         );
133   *rem = r;
134   return q;
135 }
136
137 LARGE_INTEGER LargeIntegerMultiplyLongByLong(unsigned long a, unsigned long b)
138 {
139   LARGE_INTEGER prod;
140
141   prod.LowPart = mult32(a, b, &prod.HighPart);
142   return prod;
143 }
144   
145 LARGE_INTEGER LargeIntegerMultiplyByLong(LARGE_INTEGER a, unsigned long b)
146 {
147   LARGE_INTEGER prod;
148   unsigned long x, prodl, prodh, ovl, ovh;
149   
150   /* multiply low part and save the overflow bits */
151   prod.LowPart = mult32(a.LowPart, b, &ovl);
152   
153   /* multiply high part */
154   prod.HighPart = mult32(a.HighPart, b, &ovh);
155   
156   /* add overflow from low part */
157   prod.HighPart += ovl;
158
159   return prod;
160 }
161   
162 unsigned long LargeIntegerDivideByLong(LARGE_INTEGER a, unsigned long b, unsigned long *rem)
163 {
164   unsigned long n, r, q; 
165   LARGE_INTEGER t;
166   
167   if (b == 0) { return 0; }
168   if (b == 1) { *rem = 0; return a.LowPart; }
169
170   n = div32(a.LowPart, b, &r);
171   if (a.HighPart == 0)
172   {
173     *rem = r;
174     return n;
175   }
176   else
177   {
178     q = div32(0xffffffff-b+1, b, &r);
179     q++;
180     n += q * a.HighPart;
181     n += LargeIntegerDivideByLong(LargeIntegerMultiplyLongByLong(r, a.HighPart), b, rem);
182     return n;
183   }
184 }
185 #endif
186   
187 #if 0
188 int LargeIntegerGreaterThan(LARGE_INTEGER a, LARGE_INTEGER b)
189 {
190   if (a.HighPart > b.HighPart) return 1;
191   else if (a.HighPart == b.HighPart && a.LowPart > b.LowPart) return 1;
192   else return 0;
193 }
194
195 int LargeIntegerGreaterThanOrEqualTo(LARGE_INTEGER a, LARGE_INTEGER b)
196 {
197   if (a.HighPart > b.HighPart) return 1;
198   else if (a.HighPart == b.HighPart && a.LowPart >= b.LowPart) return 1;
199   else return 0;
200 }
201   
202 int LargeIntegerEqualTo(LARGE_INTEGER a, LARGE_INTEGER b)
203 {
204   if (a.HighPart == b.HighPart && a.LowPart == b.LowPart) return 1;
205   else return 0;
206 }
207
208 int LargeIntegerGreaterOrEqualToZero(LARGE_INTEGER a)
209 {
210   return ((a.HighPart & 0x8fffffff) ? 0 : 1);
211 }
212
213 int LargeIntegerLessThanZero(LARGE_INTEGER a)
214 {
215   return ((a.HighPart & 0x8fffffff) ? 1 : 0);
216 }
217 #endif