6 * SMB file system wrapper for AmigaOS, using the AmiTCP V3 API
8 * Copyright (C) 2000-2016 by Olaf `Olsen' Barthel <obarthel -at- gmx -dot- net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "quad_math.h"
27 #endif /* _QUAD_MATH_H */
29 /****************************************************************************/
31 /* Divide a 64 bit integer by a 32 bit integer, filling in a 64 bit quotient
32 and returning a 32 bit remainder. */
34 divide_64_by_32(QUAD
* dividend
,ULONG divisor
,QUAD
* quotient
)
36 QUAD dividend_cdef
= (*dividend
);
37 ULONG dividend_ab
= 0;
40 quotient
->High
= quotient
->Low
= 0;
42 for(i
= 0 ; i
< 64 ; i
++)
44 /* Shift the quotient left by one bit. */
45 quotient
->High
= (quotient
->High
<< 1);
47 if((quotient
->Low
& 0x80000000UL
) != 0)
50 quotient
->Low
= (quotient
->Low
<< 1);
52 /* Shift the dividend left by one bit. We start
53 * with the most significant 32 bit portion.
55 dividend_ab
= (dividend_ab
<< 1);
57 if((dividend_cdef
.High
& 0x80000000UL
) != 0)
60 /* Now for the middle 32 bit portion. */
61 dividend_cdef
.High
= (dividend_cdef
.High
<< 1);
63 if((dividend_cdef
.Low
& 0x80000000UL
) != 0)
64 dividend_cdef
.High
|= 1;
66 /* Finally, the least significant portion. */
67 dividend_cdef
.Low
= (dividend_cdef
.Low
<< 1);
69 /* Does the divisor actually divide the dividend? */
70 if(dividend_ab
>= divisor
)
72 dividend_ab
-= divisor
;
74 /* We could divide the divisor. Keep track of
75 * this and take care of an overflow condition.
78 if(quotient
->Low
== 0)
86 /****************************************************************************/
88 /* Subtract a 64 bit integer from another 64 bit integer, producing a
89 64 bit integer difference, returning a 32 bit integer that indicates
90 whether or not an underflow occured. */
92 subtract_64_from_64_to_64(const QUAD
* const minuend
,const QUAD
* const subtrahend
,QUAD
* difference
)
94 QUAD extended_minuend
;
96 /* We may have to borrow if the minuend is less than the
97 subtrahend, so we set up a local variable to track
98 any underflow this might produce. */
99 extended_minuend
.High
= 0;
100 extended_minuend
.Low
= minuend
->High
;
102 /* First step: take care of the least significant word. If
103 that produces a local underflow, borrow from the most
105 if(minuend
->Low
< subtrahend
->Low
)
107 /* Borrow, and if there's nothing to be borrowed,
108 remember that we had an underflow. */
109 if(extended_minuend
.Low
-- == 0)
110 extended_minuend
.High
--;
113 difference
->Low
= minuend
->Low
- subtrahend
->Low
;
115 /* Second step: take care of the most significant word. If
116 that produces a local underflow, remember that. */
117 if(extended_minuend
.Low
< subtrahend
->High
)
118 extended_minuend
.High
--;
120 difference
->High
= extended_minuend
.Low
- subtrahend
->High
;
122 /* Return the underflow, if any. */
123 return(extended_minuend
.High
);