jslong.c revision 6b15695578f07a3f72c4c9475c1a261a3021472a
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm/* ***** BEGIN LICENSE BLOCK *****
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Version: MPL 1.1/GPL 2.0/LGPL 2.1
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm *
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * The contents of this file are subject to the Mozilla Public License Version
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * 1.1 (the "License"); you may not use this file except in compliance with
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * the License. You may obtain a copy of the License at
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * http://www.mozilla.org/MPL/
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen *
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen * Software distributed under the License is distributed on an "AS IS" basis,
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * for the specific language governing rights and limitations under the
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * License.
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm *
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * The Original Code is Mozilla Communicator client code, released
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * March 31, 1998.
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm *
6656f193fdace606d1b162d6dea0223bc295f0a6cilix * The Initial Developer of the Original Code is
6656f193fdace606d1b162d6dea0223bc295f0a6cilix * Netscape Communications Corporation.
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Portions created by the Initial Developer are Copyright (C) 1998
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * the Initial Developer. All Rights Reserved.
77a4a003111bd5cfb771d4849801c898aeb889b0cilix *
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix * Contributor(s):
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix *
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix * Alternatively, the contents of this file may be used under the terms of
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * either of the GNU General Public License Version 2 or later (the "GPL"),
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * in which case the provisions of the GPL or the LGPL are applicable instead
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * of those above. If you wish to allow use of your version of this file only
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * under the terms of either the GPL or the LGPL, and not to allow others to
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * use your version of this file under the terms of the MPL, indicate your
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * decision by deleting the provisions above and replace them with the notice
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * and other provisions required by the GPL or the LGPL. If you do not delete
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * the provisions above, a recipient may use your version of this file under
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen * the terms of any one of the MPL, the GPL or the LGPL.
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen *
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix * ***** END LICENSE BLOCK ***** */
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm#include "jsstddef.h"
8c39cbeab9949a0a7d6ae66b768a7352019e42f8johanengelen#include "jstypes.h"
072916d0ef7dccd696b59381f50bcf776abccefbjohanengelen#include "jslong.h"
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraudstatic JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraudstatic JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmstatic JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm#ifdef HAVE_WATCOM_BUG_2
8d9f5d586a04809427ce1df284a5720112177991cilixJSInt64 __pascal __loadds __export
70eb1fc448cb08acf3468f80fa2296c03b32afd2cilix JSLL_Zero(void) { return ll_zero; }
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyakJSInt64 __pascal __loadds __export
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen JSLL_MaxInt(void) { return ll_maxint; }
0cc5b8d2f7b87c4222ee3662071bef1cb1f22b06bgkJSInt64 __pascal __loadds __export
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen JSLL_MinInt(void) { return ll_minint; }
f4db63be4e929f4706410914295deccaceea19cdcilix#else
ab99111a42436818e6902e044c8f3af2b724263bcilixJS_PUBLIC_API(JSInt64) JSLL_Zero(void) { return ll_zero; }
76db360f5f052775326e6d406b9e1e9e2966e11acilixJS_PUBLIC_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; }
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilixJS_PUBLIC_API(JSInt64) JSLL_MinInt(void) { return ll_minint; }
64aee804a6a47424f7994e60558351b8cf2ea4dbcilix#endif
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
044d712d4d03f8354962d54e47cfac2346a69ccccilix#ifndef JS_HAVE_LONG_LONG
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix/*
2f5c0701b333a695eedb1680beb1adf95c0723dacilix** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen*/
0a75b58e47d3de42550c4f7960e253ea3befc09ajohanengelenstatic void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix{
ecf048161ae0284d01d34ca5844204775c0d3fdecilix JSUint32 d1, d0, q1, q0;
3515994554d167522343ce57417648b39370ccabcilix JSUint32 r1, r0, m;
e54ce05030e6aab675331e18f46f029f55ed1bf0cilix
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm d1 = jshi16(b);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm d0 = jslo16(b);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm r1 = a.hi % d1;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm q1 = a.hi / d1;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm m = q1 * d0;
72b7b31db250f20b90730d2888e6a554b434a407johanengelen r1 = (r1 << 16) | jshi16(a.lo);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (r1 < m) {
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen q1--, r1 += b;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen && r1 < m) {
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen q1--, r1 += b;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen }
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm r1 -= m;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen r0 = r1 % d1;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm q0 = r1 / d1;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen m = q0 * d0;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen r0 = (r0 << 16) | jslo16(a.lo);
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen if (r0 < m) {
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen q0--, r0 += b;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen if (r0 >= b
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen && r0 < m) {
3515994554d167522343ce57417648b39370ccabcilix q0--, r0 += b;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen }
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen }
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen *qp = (q1 << 16) | q0;
ecf048161ae0284d01d34ca5844204775c0d3fdecilix *rp = r0 - m;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen}
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelenstatic JSUint32 CountLeadingZeros(JSUint32 a)
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen{
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen JSUint32 t;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen JSUint32 r = 32;
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen if ((t = a >> 16) != 0)
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen r -= 16, a = t;
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix if ((t = a >> 8) != 0)
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen r -= 8, a = t;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if ((t = a >> 4) != 0)
72b7b31db250f20b90730d2888e6a554b434a407johanengelen r -= 4, a = t;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if ((t = a >> 2) != 0)
a45e91fd09273632e9acf849bb72621832156f07cilix r -= 2, a = t;
494c671e141564431d7d05f141c885d9a2789db5cilix if ((t = a >> 1) != 0)
a45e91fd09273632e9acf849bb72621832156f07cilix r -= 1, a = t;
a45e91fd09273632e9acf849bb72621832156f07cilix if (a & 1)
a45e91fd09273632e9acf849bb72621832156f07cilix r--;
a45e91fd09273632e9acf849bb72621832156f07cilix return r;
8791d7447034c34fdedc50f261bf5c89c34e59f5cilix}
8791d7447034c34fdedc50f261bf5c89c34e59f5cilix
a45e91fd09273632e9acf849bb72621832156f07cilixJS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
a45e91fd09273632e9acf849bb72621832156f07cilix{
a45e91fd09273632e9acf849bb72621832156f07cilix JSUint32 n0, n1, n2;
a45e91fd09273632e9acf849bb72621832156f07cilix JSUint32 q0, q1;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm JSUint32 rsh, lsh;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm n0 = a.lo;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm n1 = a.hi;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
8c39cbeab9949a0a7d6ae66b768a7352019e42f8johanengelen if (b.hi == 0) {
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen if (b.lo > n1) {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm /* (0 q0) = (n1 n0) / (0 D0) */
29f9623ba77fc735b89765ae3a13e0c06aabafcecilix
29f9623ba77fc735b89765ae3a13e0c06aabafcecilix lsh = CountLeadingZeros(b.lo);
29f9623ba77fc735b89765ae3a13e0c06aabafcecilix
072916d0ef7dccd696b59381f50bcf776abccefbjohanengelen if (lsh) {
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen /*
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen * Normalize, i.e. make the most significant bit of the
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud * denominator be set.
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen */
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud b.lo = b.lo << lsh;
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud n1 = (n1 << lsh) | (n0 >> (32 - lsh));
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen n0 = n0 << lsh;
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud }
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen a.lo = n0, a.hi = n1;
dc98accfae7a38326b92d74fa4330ac8ccb5b778jfbarraud norm_udivmod32(&q0, &n0, a, b.lo);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm q1 = 0;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen /* remainder is in n0 >> lsh */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm } else {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm /* (q1 q0) = (n1 n0) / (0 d0) */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen if (b.lo == 0) /* user wants to divide by zero! */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm b.lo = 1 / b.lo; /* so go ahead and crash */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen lsh = CountLeadingZeros(b.lo);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen if (lsh == 0) {
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen /*
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen * From (n1 >= b.lo)
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen * && (the most significant bit of b.lo is set),
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen * conclude that
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen * (the most significant bit of n1 is set)
8d9f5d586a04809427ce1df284a5720112177991cilix * && (the leading quotient digit q1 = 1).
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen *
8d9f5d586a04809427ce1df284a5720112177991cilix * This special case is necessary, not an optimization
70eb1fc448cb08acf3468f80fa2296c03b32afd2cilix * (Shifts counts of 32 are undefined).
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen */
70eb1fc448cb08acf3468f80fa2296c03b32afd2cilix n1 -= b.lo;
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyak q1 = 1;
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyak } else {
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyak /*
6f4a90e526af850ffc36064f58f09c190f3b633fjohanengelen * Normalize.
6f4a90e526af850ffc36064f58f09c190f3b633fjohanengelen */
6f4a90e526af850ffc36064f58f09c190f3b633fjohanengelen rsh = 32 - lsh;
f4db63be4e929f4706410914295deccaceea19cdcilix
f4db63be4e929f4706410914295deccaceea19cdcilix b.lo = b.lo << lsh;
f4db63be4e929f4706410914295deccaceea19cdcilix n2 = n1 >> rsh;
ab99111a42436818e6902e044c8f3af2b724263bcilix n1 = (n1 << lsh) | (n0 >> rsh);
ab99111a42436818e6902e044c8f3af2b724263bcilix n0 = n0 << lsh;
ab99111a42436818e6902e044c8f3af2b724263bcilix
76db360f5f052775326e6d406b9e1e9e2966e11acilix a.lo = n1, a.hi = n2;
76db360f5f052775326e6d406b9e1e9e2966e11acilix norm_udivmod32(&q1, &n1, a, b.lo);
b0c42c0dfcd02cc05126371948489a5a88b2e4b3cilix }
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilix
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilix /* n1 != b.lo... */
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilix
64aee804a6a47424f7994e60558351b8cf2ea4dbcilix a.lo = n0, a.hi = n1;
64aee804a6a47424f7994e60558351b8cf2ea4dbcilix norm_udivmod32(&q0, &n0, a, b.lo);
64aee804a6a47424f7994e60558351b8cf2ea4dbcilix
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* remainder in n0 >> lsh */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix }
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix
044d712d4d03f8354962d54e47cfac2346a69ccccilix if (rp) {
044d712d4d03f8354962d54e47cfac2346a69ccccilix rp->lo = n0 >> lsh;
044d712d4d03f8354962d54e47cfac2346a69ccccilix rp->hi = 0;
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix }
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix } else {
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix if (b.hi > n1) {
2f5c0701b333a695eedb1680beb1adf95c0723dacilix /* (0 0) = (n1 n0) / (D1 d0) */
2f5c0701b333a695eedb1680beb1adf95c0723dacilix
2f5c0701b333a695eedb1680beb1adf95c0723dacilix q0 = 0;
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen q1 = 0;
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen /* remainder in (n1 n0) */
0a75b58e47d3de42550c4f7960e253ea3befc09ajohanengelen if (rp) {
0a75b58e47d3de42550c4f7960e253ea3befc09ajohanengelen rp->lo = n0;
0a75b58e47d3de42550c4f7960e253ea3befc09ajohanengelen rp->hi = n1;
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix }
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix } else {
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix /* (0 q0) = (n1 n0) / (d1 d0) */
ecf048161ae0284d01d34ca5844204775c0d3fdecilix
ecf048161ae0284d01d34ca5844204775c0d3fdecilix lsh = CountLeadingZeros(b.hi);
ecf048161ae0284d01d34ca5844204775c0d3fdecilix if (lsh == 0) {
3515994554d167522343ce57417648b39370ccabcilix /*
3515994554d167522343ce57417648b39370ccabcilix * From (n1 >= b.hi)
3515994554d167522343ce57417648b39370ccabcilix * && (the most significant bit of b.hi is set),
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * conclude that
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * (the most significant bit of n1 is set)
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * && (the quotient digit q0 = 0 or 1).
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm *
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * This special case is necessary, not an optimization.
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm /*
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * The condition on the next line takes advantage of that
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * n1 >= b.hi (true due to control flow).
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (n1 > b.hi || n0 >= b.lo) {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm q0 = 1;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix a.lo = n0, a.hi = n1;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix JSLL_SUB(a, a, b);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix } else {
6656f193fdace606d1b162d6dea0223bc295f0a6cilix q0 = 0;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix }
6656f193fdace606d1b162d6dea0223bc295f0a6cilix q1 = 0;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix
6656f193fdace606d1b162d6dea0223bc295f0a6cilix if (rp) {
6656f193fdace606d1b162d6dea0223bc295f0a6cilix rp->lo = n0;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix rp->hi = n1;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix }
6656f193fdace606d1b162d6dea0223bc295f0a6cilix } else {
6656f193fdace606d1b162d6dea0223bc295f0a6cilix JSInt64 m;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix
6656f193fdace606d1b162d6dea0223bc295f0a6cilix /*
6656f193fdace606d1b162d6dea0223bc295f0a6cilix * Normalize.
6656f193fdace606d1b162d6dea0223bc295f0a6cilix */
6656f193fdace606d1b162d6dea0223bc295f0a6cilix rsh = 32 - lsh;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix
6656f193fdace606d1b162d6dea0223bc295f0a6cilix b.hi = (b.hi << lsh) | (b.lo >> rsh);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix b.lo = b.lo << lsh;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix n2 = n1 >> rsh;
6656f193fdace606d1b162d6dea0223bc295f0a6cilix n1 = (n1 << lsh) | (n0 >> rsh);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm n0 = n0 << lsh;
fbb4eb8b63e74d9441220a73a8ca858425be4bd4johanengelen
71146abe8aba032d73788a625fee5769a581bd3ccilix a.lo = n1, a.hi = n2;
04c99c338ffdc6e10cb6f5c18f6f06b3f555e8ebcilix norm_udivmod32(&q0, &n1, a, b.hi);
fbb4eb8b63e74d9441220a73a8ca858425be4bd4johanengelen JSLL_MUL32(m, q0, b.lo);
9ce14357bb94b9dd92ad40bf43ef435a257b355acilix
c27006137a3ad49e074b97b3297db753e1ac8eefcilix if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
c27006137a3ad49e074b97b3297db753e1ac8eefcilix q0--;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm JSLL_SUB(m, m, b);
71146abe8aba032d73788a625fee5769a581bd3ccilix }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm q1 = 0;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (rp) {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm a.lo = n0, a.hi = n1;
eaa9bdc7bf7b73397e536edd47490d84e4420bd8bryce JSLL_SUB(a, a, m);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm rp->lo = (a.hi << rsh) | (a.lo >> lsh);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm rp->hi = a.hi >> lsh;
72b7b31db250f20b90730d2888e6a554b434a407johanengelen }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm }
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (qp) {
c90010388b0d4045c26e81c2be28beedcb36c7d3cilix qp->lo = q0;
c90010388b0d4045c26e81c2be28beedcb36c7d3cilix qp->hi = q1;
c90010388b0d4045c26e81c2be28beedcb36c7d3cilix }
c90010388b0d4045c26e81c2be28beedcb36c7d3cilix}
c90010388b0d4045c26e81c2be28beedcb36c7d3cilix#endif /* !JS_HAVE_LONG_LONG */
77a4a003111bd5cfb771d4849801c898aeb889b0cilix