diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-01 14:19:52 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-07 14:23:22 -0800 |
commit | 74c843c55f0238bd75a919fdd5b2dc2f57f48fe2 (patch) | |
tree | f10d06d0da4c5cd88ec6f2c2fc93af2b349a4c39 | |
parent | 61e57490b2f55f57291f8d28a79805d5bd84f176 (diff) |
i64Math in asm
-rwxr-xr-x | emscripten.py | 15 | ||||
-rw-r--r-- | src/library.js | 6 | ||||
-rw-r--r-- | src/long.js | 29 | ||||
-rw-r--r-- | src/parseTools.js | 6 | ||||
-rwxr-xr-x | tests/runner.py | 17 |
5 files changed, 33 insertions, 40 deletions
diff --git a/emscripten.py b/emscripten.py index c0c40da7..7c064850 100755 --- a/emscripten.py +++ b/emscripten.py @@ -291,11 +291,19 @@ def emscript(infile, settings, outfile, libraries=[]): function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()]) if settings.get('ASM_JS'): + asm_setup = '' fundamentals = ['buffer', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array'] basics = ['abort', 'assert', 'STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT'] if not settings['NAMED_GLOBALS']: basics += ['GLOBAL_BASE'] - #if forwarded_json['Types']['preciseI64MathUsed']: - # basics += ['i64Math'] + if forwarded_json['Types']['preciseI64MathUsed']: + basics += ['i64Math_' + op for op in ['add', 'subtract', 'multiply', 'divide', 'modulo']] + asm_setup += ''' +var i64Math_add = function(a, b, c, d) { i64Math.add(a, b, c, d) }; +var i64Math_subtract = function(a, b, c, d) { i64Math.subtract(a, b, c, d) }; +var i64Math_multiply = function(a, b, c, d) { i64Math.multiply(a, b, c, d) }; +var i64Math_divide = function(a, b, c, d) { i64Math.divide(a, b, c, d) }; +var i64Math_modulo = function(a, b, c, d) { i64Math.modulo(a, b, c, d) }; +''' asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore'] # function tables function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']] @@ -329,6 +337,7 @@ def emscript(infile, settings, outfile, libraries=[]): receiving = ';\n'.join(['var ' + s + ' = Module["' + s + '"] = asm.' + s for s in exported_implemented_functions + function_tables]) # finalize funcs_js = ''' +%s var asmPre = (function(env, buffer) { 'use asm'; var HEAP8 = new env.Int8Array(buffer); @@ -339,7 +348,7 @@ var asmPre = (function(env, buffer) { var HEAPU32 = new env.Uint32Array(buffer); var HEAPF32 = new env.Float32Array(buffer); var HEAPF64 = new env.Float64Array(buffer); -''' + asm_globals + ''' +''' % (asm_setup,) + asm_globals + ''' function stackAlloc(size) { var ret = STACKTOP; STACKTOP = (STACKTOP + size)|0; diff --git a/src/library.js b/src/library.js index f8e1022b..9e447232 100644 --- a/src/library.js +++ b/src/library.js @@ -5064,16 +5064,16 @@ LibraryManager.library = { llvm_uadd_with_overflow_i64: function(xl, xh, yl, yh) { i64Math.add(xl, xh, yl, yh); return { - f0: i64Math.result, + f0: [HEAP32[tempDoublePtr>>2], HEAP32[tempDoublePtr+4>>2]], f1: 0 // XXX Need to hack support for this in long.js }; }, llvm_umul_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) { - i64Math.mul(xl, xh, yl, yh); + i64Math.multiply(xl, xh, yl, yh); return { - f0: i64Math.result, + f0: [HEAP32[tempDoublePtr>>2], HEAP32[tempDoublePtr+4>>2]], f1: 0 // XXX Need to hack support for this in long.js }; }, diff --git a/src/long.js b/src/long.js index d5770e48..865540db 100644 --- a/src/long.js +++ b/src/long.js @@ -1530,27 +1530,26 @@ var i64Math = (function() { // Emscripten wrapper // Emscripten wrapper var Wrapper = { - result: [0, 0], // return result stored here add: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.add(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, subtract: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.subtract(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, multiply: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.multiply(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, makeTwo32: function() { Wrapper.two32 = new BigInteger(); @@ -1573,8 +1572,8 @@ var i64Math = (function() { // Emscripten wrapper var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.div(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; } else { // slow precise bignum division var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); @@ -1584,8 +1583,8 @@ var i64Math = (function() { // Emscripten wrapper var l = new BigInteger(); var h = new BigInteger(); z.divRemTo(Wrapper.two32, h, l); - Wrapper.result[0] = parseInt(l.toString()) | 0; - Wrapper.result[1] = parseInt(h.toString()) | 0; + HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; + HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; } }, modulo: function(xl, xh, yl, yh, unsigned) { @@ -1594,8 +1593,8 @@ var i64Math = (function() { // Emscripten wrapper var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.modulo(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; } else { // slow precise bignum division var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); @@ -1605,8 +1604,8 @@ var i64Math = (function() { // Emscripten wrapper var l = new BigInteger(); var h = new BigInteger(); z.divRemTo(Wrapper.two32, h, l); - Wrapper.result[0] = parseInt(l.toString()) | 0; - Wrapper.result[1] = parseInt(h.toString()) | 0; + HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; + HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; } }, stringify: function(l, h, unsigned) { diff --git a/src/parseTools.js b/src/parseTools.js index e31a3027..258ef40a 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1737,8 +1737,8 @@ function processMathop(item) { } function i64PreciseOp(type, lastArg) { Types.preciseI64MathUsed = true; - return finish(['(i64Math.' + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + - (lastArg ? ',' + lastArg : '') + '),i64Math.result[0])', 'i64Math.result[1]']); + return finish(['(i64Math' + (ASM_JS ? '_' : '.') + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + + (lastArg ? ',' + lastArg : '') + '),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')', makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32'), 'i32')]); } switch (op) { // basic integer ops @@ -1898,7 +1898,7 @@ function processMathop(item) { case 'mul': { if (bits == 32 && PRECISE_I32_MUL) { Types.preciseI64MathUsed = true; - return '(i64Math.multiply(' + idents[0] + ',0,' + idents[1] + ',0),i64Math.result[0])'; + return '(i64Math' + (ASM_JS ? '_' : '.') + 'multiply(' + idents[0] + ',0,' + idents[1] + ',0),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')'; } else { return handleOverflow(getFastValue(idents[0], '*', idents[1], item.type), bits); } diff --git a/tests/runner.py b/tests/runner.py index 6c176254..fa7be147 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -487,8 +487,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows self.do_run(src, 'hello, world!') def test_intvars(self): - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') - src = ''' #include <stdio.h> int global = 20; @@ -574,7 +572,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows def test_i64(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('i64 mode 1 requires ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = ''' #include <stdio.h> @@ -790,7 +787,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows def test_i64_b(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <stdio.h> @@ -816,7 +812,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows def test_i64_cmp(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <stdio.h> @@ -841,7 +836,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows def test_i64_cmp2(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <inttypes.h> @@ -888,7 +882,7 @@ m_divisor is 1091269979 def test_i64_double(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') + src = r''' #include <stdio.h> @@ -932,7 +926,6 @@ m_divisor is 1091269979 def test_i64_umul(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <inttypes.h> @@ -958,7 +951,6 @@ m_divisor is 1091269979 def test_i64_precise(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <inttypes.h> @@ -1039,7 +1031,6 @@ m_divisor is 1091269979 def test_i64_zextneg(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <stdint.h> @@ -1061,7 +1052,6 @@ m_divisor is 1091269979 def test_i64_7z(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <stdint.h> @@ -1083,7 +1073,6 @@ m_divisor is 1091269979 def test_i64_i16(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') src = r''' #include <stdio.h> @@ -1126,7 +1115,6 @@ m_divisor is 1091269979 def test_i32_mul_precise(self): if self.emcc_args == None: return self.skip('needs ta2') - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') self.emcc_args += ['-s', 'PRECISE_I32_MUL=1'] src = r''' @@ -1209,7 +1197,6 @@ c5,de,15,8a self.do_run(open(path_from_root('tests', 'cube2md5.cpp')).read(), open(path_from_root('tests', 'cube2md5.ok')).read()) def test_cube2hash(self): - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') try: old_chunk_size = os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or '' @@ -7106,8 +7093,6 @@ def process(filename): assert 'Assertion failed' in str(e), str(e) def test_linespecific(self): - if Settings.ASM_JS: return self.skip('asm does not support i64 yet') - if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g') if self.emcc_args: self.emcc_args += ['--llvm-opts', '0'] # llvm full opts make the expected failures here not happen |