aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py6
-rw-r--r--src/fastLong.js51
-rw-r--r--src/long.js42
-rw-r--r--src/parseTools.js4
-rw-r--r--system/lib/compiler-rt/divdi3.c16
-rw-r--r--system/lib/compiler-rt/readme.txt5
-rw-r--r--system/lib/compiler-rt/udivdi3.c11
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;
+}
+