1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Mozilla Public License Version
6
* 1.1 (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/MPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is Mozilla Communicator client code, released
18
* The Initial Developer of the Original Code is
19
* Netscape Communications Corporation.
20
* Portions created by the Initial Developer are Copyright (C) 1998
21
* the Initial Developer. All Rights Reserved.
25
* Alternatively, the contents of this file may be used under the terms of
26
* either of the GNU General Public License Version 2 or later (the "GPL"),
27
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
* in which case the provisions of the GPL or the LGPL are applicable instead
29
* of those above. If you wish to allow use of your version of this file only
30
* under the terms of either the GPL or the LGPL, and not to allow others to
31
* use your version of this file under the terms of the MPL, indicate your
32
* decision by deleting the provisions above and replace them with the notice
33
* and other provisions required by the GPL or the LGPL. If you do not delete
34
* the provisions above, a recipient may use your version of this file under
35
* the terms of any one of the MPL, the GPL or the LGPL.
37
* ***** END LICENSE BLOCK ***** */
43
static JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
44
static JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
45
static JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
47
#ifdef HAVE_WATCOM_BUG_2
48
JSInt64 __pascal __loadds __export
49
JSLL_Zero(void) { return ll_zero; }
50
JSInt64 __pascal __loadds __export
51
JSLL_MaxInt(void) { return ll_maxint; }
52
JSInt64 __pascal __loadds __export
53
JSLL_MinInt(void) { return ll_minint; }
55
JS_PUBLIC_API(JSInt64) JSLL_Zero(void) { return ll_zero; }
56
JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; }
57
JS_PUBLIC_API(JSInt64) JSLL_MinInt(void) { return ll_minint; }
60
#ifndef JS_HAVE_LONG_LONG
62
** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
64
static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
66
JSUint32 d1, d0, q1, q0;
74
r1 = (r1 << 16) | jshi16(a.lo);
77
if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */
86
r0 = (r0 << 16) | jslo16(a.lo);
94
*qp = (q1 << 16) | q0;
98
static JSUint32 CountLeadingZeros(JSUint32 a)
103
if ((t = a >> 16) != 0)
105
if ((t = a >> 8) != 0)
107
if ((t = a >> 4) != 0)
109
if ((t = a >> 2) != 0)
111
if ((t = a >> 1) != 0)
118
JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
129
/* (0 q0) = (n1 n0) / (0 D0) */
131
lsh = CountLeadingZeros(b.lo);
135
* Normalize, i.e. make the most significant bit of the
136
* denominator be set.
139
n1 = (n1 << lsh) | (n0 >> (32 - lsh));
143
a.lo = n0, a.hi = n1;
144
norm_udivmod32(&q0, &n0, a, b.lo);
147
/* remainder is in n0 >> lsh */
149
/* (q1 q0) = (n1 n0) / (0 d0) */
151
if (b.lo == 0) /* user wants to divide by zero! */
152
b.lo = 1 / b.lo; /* so go ahead and crash */
154
lsh = CountLeadingZeros(b.lo);
159
* && (the most significant bit of b.lo is set),
161
* (the most significant bit of n1 is set)
162
* && (the leading quotient digit q1 = 1).
164
* This special case is necessary, not an optimization
165
* (Shifts counts of 32 are undefined).
177
n1 = (n1 << lsh) | (n0 >> rsh);
180
a.lo = n1, a.hi = n2;
181
norm_udivmod32(&q1, &n1, a, b.lo);
186
a.lo = n0, a.hi = n1;
187
norm_udivmod32(&q0, &n0, a, b.lo);
189
/* remainder in n0 >> lsh */
198
/* (0 0) = (n1 n0) / (D1 d0) */
203
/* remainder in (n1 n0) */
209
/* (0 q0) = (n1 n0) / (d1 d0) */
211
lsh = CountLeadingZeros(b.hi);
215
* && (the most significant bit of b.hi is set),
217
* (the most significant bit of n1 is set)
218
* && (the quotient digit q0 = 0 or 1).
220
* This special case is necessary, not an optimization.
224
* The condition on the next line takes advantage of that
225
* n1 >= b.hi (true due to control flow).
227
if (n1 > b.hi || n0 >= b.lo) {
229
a.lo = n0, a.hi = n1;
248
b.hi = (b.hi << lsh) | (b.lo >> rsh);
251
n1 = (n1 << lsh) | (n0 >> rsh);
254
a.lo = n1, a.hi = n2;
255
norm_udivmod32(&q0, &n1, a, b.hi);
256
JSLL_MUL32(m, q0, b.lo);
258
if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
265
/* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
267
a.lo = n0, a.hi = n1;
269
rp->lo = (a.hi << rsh) | (a.lo >> lsh);
270
rp->hi = a.hi >> lsh;
281
#endif /* !JS_HAVE_LONG_LONG */