diff options
-rwxr-xr-x | emscripten.py | 6 | ||||
-rw-r--r-- | src/fastLong.js | 51 | ||||
-rw-r--r-- | src/long.js | 42 | ||||
-rw-r--r-- | src/parseTools.js | 4 | ||||
-rw-r--r-- | system/lib/compiler-rt/divdi3.c | 16 | ||||
-rw-r--r-- | system/lib/compiler-rt/readme.txt | 5 | ||||
-rw-r--r-- | system/lib/compiler-rt/udivdi3.c | 11 |
7 files changed, 76 insertions, 59 deletions
diff --git a/emscripten.py b/emscripten.py index bae6d8cd..b49008cd 100755 --- a/emscripten.py +++ b/emscripten.py @@ -392,12 +392,6 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8'] basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT'] basic_float_vars = ['NaN', 'Infinity'] - if forwarded_json['Types']['preciseI64MathUsed']: - basic_funcs += ['i64Math_' + op for op in ['divide', 'modulo']] - asm_setup += ''' -var i64Math_divide = function(a, b, c, d, e) { i64Math.divide(a, b, c, d, e) }; -var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; -''' if forwarded_json['Types']['preciseI64MathUsed'] or \ forwarded_json['Functions']['libraryFunctions'].get('llvm_cttz_i32') or \ diff --git a/src/fastLong.js b/src/fastLong.js index b4bdece0..95f398db 100644 --- a/src/fastLong.js +++ b/src/fastLong.js @@ -31,6 +31,28 @@ function ___divdi3($a$0, $a$1, $b$0, $b$1) { $10$0 = _i64Subtract($8$0 ^ $7$0, tempRet0 ^ $7$1, $7$0, $7$1); return (tempRet0 = tempRet0, $10$0) | 0; } +function ___remdi3($a$0, $a$1, $b$0, $b$1) { + $a$0 = $a$0 | 0; + $a$1 = $a$1 | 0; + $b$0 = $b$0 | 0; + $b$1 = $b$1 | 0; + var $rem = 0, $1$0 = 0, $1$1 = 0, $2$0 = 0, $2$1 = 0, $4$0 = 0, $4$1 = 0, $6$0 = 0, $10$0 = 0, $10$1 = 0, __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $rem = __stackBase__ | 0; + $1$0 = $a$1 >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1; + $1$1 = (($a$1 | 0) < 0 ? -1 : 0) >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1; + $2$0 = $b$1 >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1; + $2$1 = (($b$1 | 0) < 0 ? -1 : 0) >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1; + $4$0 = _i64Subtract($1$0 ^ $a$0, $1$1 ^ $a$1, $1$0, $1$1); + $4$1 = tempRet0; + $6$0 = _i64Subtract($2$0 ^ $b$0, $2$1 ^ $b$1, $2$0, $2$1); + ___udivmoddi4($4$0, $4$1, $6$0, tempRet0, $rem); + $10$0 = _i64Subtract(HEAP32[$rem >> 2] ^ $1$0, HEAP32[$rem + 4 >> 2] ^ $1$1, $1$0, $1$1); + $10$1 = tempRet0; + STACKTOP = __stackBase__; + return (tempRet0 = $10$1, $10$0) | 0; +} function ___muldi3($a$0, $a$1, $b$0, $b$1) { $a$0 = $a$0 | 0; $a$1 = $a$1 | 0; @@ -53,6 +75,19 @@ function ___udivdi3($a$0, $a$1, $b$0, $b$1) { $1$0 = ___udivmoddi4($a$0, $a$1, $b$0, $b$1, 0) | 0; return (tempRet0 = tempRet0, $1$0) | 0; } +function ___uremdi3($a$0, $a$1, $b$0, $b$1) { + $a$0 = $a$0 | 0; + $a$1 = $a$1 | 0; + $b$0 = $b$0 | 0; + $b$1 = $b$1 | 0; + var $rem = 0, __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $rem = __stackBase__ | 0; + ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem); + STACKTOP = __stackBase__; + return (tempRet0 = HEAP32[$rem + 4 >> 2] | 0, HEAP32[$rem >> 2] | 0) | 0; +} function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) { $a$0 = $a$0 | 0; $a$1 = $a$1 | 0; @@ -117,11 +152,11 @@ function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) { HEAP32[$rem + 4 >> 2] = $37 & $n_sroa_1_4_extract_trunc | $a$1 & 0; } $_0$1 = 0; - $_0$0 = $n_sroa_1_4_extract_trunc >>> ((_llvm_cttz_i32($d_sroa_1_4_extract_trunc) | 0) >>> 0); + $_0$0 = $n_sroa_1_4_extract_trunc >>> ((_llvm_cttz_i32($d_sroa_1_4_extract_trunc | 0) | 0) >>> 0); return (tempRet0 = $_0$1, $_0$0) | 0; } - $49 = _llvm_ctlz_i32($d_sroa_1_4_extract_trunc) | 0; - $51 = $49 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc) | 0) | 0; + $49 = _llvm_ctlz_i32($d_sroa_1_4_extract_trunc | 0) | 0; + $51 = $49 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc | 0) | 0) | 0; if ($51 >>> 0 <= 30) { $57 = $51 + 1 | 0; $58 = 31 - $51 | 0; @@ -144,8 +179,8 @@ function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) { return (tempRet0 = $_0$1, $_0$0) | 0; } else { if (!$17) { - $117 = _llvm_ctlz_i32($d_sroa_1_4_extract_trunc) | 0; - $119 = $117 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc) | 0) | 0; + $117 = _llvm_ctlz_i32($d_sroa_1_4_extract_trunc | 0) | 0; + $119 = $117 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc | 0) | 0) | 0; if ($119 >>> 0 <= 31) { $125 = $119 + 1 | 0; $126 = 31 - $119 | 0; @@ -170,8 +205,8 @@ function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) { } $66 = $d_sroa_0_0_extract_trunc - 1 | 0; if (($66 & $d_sroa_0_0_extract_trunc | 0) != 0) { - $86 = (_llvm_ctlz_i32($d_sroa_0_0_extract_trunc) | 0) + 33 | 0; - $88 = $86 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc) | 0) | 0; + $86 = (_llvm_ctlz_i32($d_sroa_0_0_extract_trunc | 0) | 0) + 33 | 0; + $88 = $86 - (_llvm_ctlz_i32($n_sroa_1_4_extract_trunc | 0) | 0) | 0; $89 = 64 - $88 | 0; $91 = 32 - $88 | 0; $92 = $91 >> 31; @@ -193,7 +228,7 @@ function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) { $_0$0 = 0 | $a$0 & -1; return (tempRet0 = $_0$1, $_0$0) | 0; } else { - $78 = _llvm_cttz_i32($d_sroa_0_0_extract_trunc) | 0; + $78 = _llvm_cttz_i32($d_sroa_0_0_extract_trunc | 0) | 0; $_0$1 = 0 | $n_sroa_1_4_extract_trunc >>> ($78 >>> 0); $_0$0 = $n_sroa_1_4_extract_trunc << 32 - $78 | $n_sroa_0_0_extract_trunc >>> ($78 >>> 0) | 0; return (tempRet0 = $_0$1, $_0$0) | 0; diff --git a/src/long.js b/src/long.js index 9550a48a..42c86c23 100644 --- a/src/long.js +++ b/src/long.js @@ -1562,48 +1562,6 @@ var i64Math = (function() { // Emscripten wrapper c.addTo(b, d); return d; }, - divide: function(xl, xh, yl, yh, unsigned) { - Wrapper.ensureTemps(); - if (!unsigned) { - var x = new goog.math.Long(xl, xh); - var y = new goog.math.Long(yl, yh); - var ret = x.div(y); - HEAP32[tempDoublePtr>>2] = ret.low_; - HEAP32[tempDoublePtr+4>>2] = ret.high_; - } else { - // slow precise bignum division - var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); - var y = Wrapper.lh2bignum(yl >>> 0, yh >>> 0); - var z = new BigInteger(); - x.divRemTo(y, z, null); - var l = new BigInteger(); - var h = new BigInteger(); - z.divRemTo(Wrapper.two32, h, l); - HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; - HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; - } - }, - modulo: function(xl, xh, yl, yh, unsigned) { - Wrapper.ensureTemps(); - if (!unsigned) { - var x = new goog.math.Long(xl, xh); - var y = new goog.math.Long(yl, yh); - var ret = x.modulo(y); - HEAP32[tempDoublePtr>>2] = ret.low_; - HEAP32[tempDoublePtr+4>>2] = ret.high_; - } else { - // slow precise bignum division - var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); - var y = Wrapper.lh2bignum(yl >>> 0, yh >>> 0); - var z = new BigInteger(); - x.divRemTo(y, null, z); - var l = new BigInteger(); - var h = new BigInteger(); - z.divRemTo(Wrapper.two32, h, l); - HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; - HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; - } - }, stringify: function(l, h, unsigned) { var ret = new goog.math.Long(l, h).toString(); if (unsigned && ret[0] == '-') { diff --git a/src/parseTools.js b/src/parseTools.js index 8a6daaf3..2eb456f1 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -2073,7 +2073,7 @@ function processMathop(item) { } case 'sdiv': case 'udiv': { if (PRECISE_I64_MATH) { - return i64PreciseOp('divide', op[0] === 'u'); + return preciseCall(op[0] === 'u' ? '___udivdi3' : '___divdi3'); } else { warnI64_1(); return finish(splitI64(makeRounding(mergeI64(idents[0], op[0] === 'u') + '/' + mergeI64(idents[1], op[0] === 'u'), bits, op[0] === 's'), true)); @@ -2089,7 +2089,7 @@ function processMathop(item) { } case 'urem': case 'srem': { if (PRECISE_I64_MATH) { - return i64PreciseOp('modulo', op[0] === 'u'); + return preciseCall(op[0] === 'u' ? '___uremdi3' : '___remdi3'); } else { warnI64_1(); return finish(splitI64(mergeI64(idents[0], op[0] === 'u') + '%' + mergeI64(idents[1], op[0] === 'u'), true)); diff --git a/system/lib/compiler-rt/divdi3.c b/system/lib/compiler-rt/divdi3.c index 2c2bcc26..09f4a04e 100644 --- a/system/lib/compiler-rt/divdi3.c +++ b/system/lib/compiler-rt/divdi3.c @@ -29,3 +29,19 @@ __divdi3(di_int a, di_int b) s_a ^= s_b; /*sign of quotient */ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ } + +/* XXX EMSCRIPTEN */ + +COMPILER_RT_ABI di_int +__remdi3(di_int a, di_int b) +{ + const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1; + di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */ + di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */ + a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ + b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ + du_int rem; + __udivmoddi4(a, b, &rem); + return (rem ^ s_a) - s_a; /* negate if s_a == -1 */ +} + diff --git a/system/lib/compiler-rt/readme.txt b/system/lib/compiler-rt/readme.txt index d32e4600..d10f53e4 100644 --- a/system/lib/compiler-rt/readme.txt +++ b/system/lib/compiler-rt/readme.txt @@ -5,7 +5,10 @@ Last Changed Date: 2013-04-12 07:57:03 -0700 (Fri, 12 Apr 2013) =========================================================================== -Changes: add emscripten endianness to int_endianness.h +Changes: + + * add emscripten endianness to int_endianness.h + * add rem functions =========================================================================== diff --git a/system/lib/compiler-rt/udivdi3.c b/system/lib/compiler-rt/udivdi3.c index 6c0303df..3d55785c 100644 --- a/system/lib/compiler-rt/udivdi3.c +++ b/system/lib/compiler-rt/udivdi3.c @@ -23,3 +23,14 @@ __udivdi3(du_int a, du_int b) { return __udivmoddi4(a, b, 0); } + +/* XXX EMSCRIPTEN */ + +COMPILER_RT_ABI du_int +__uremdi3(du_int a, du_int b) +{ + du_int rem; + __udivmoddi4(a, b, &rem); + return rem; +} + |