diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 7 | ||||
-rw-r--r-- | src/jsifier.js | 10 | ||||
-rw-r--r-- | src/library.js | 52 | ||||
-rw-r--r-- | src/runtime.js | 51 |
4 files changed, 56 insertions, 64 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index b73cc943..92b7d8cf 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -653,13 +653,14 @@ function analyzer(data, sidePass) { if (!isNumber(shifts)) { // We can't statically legalize this, do the operation at runtime TODO: optimize assert(sourceBits == 64, 'TODO: handle nonconstant shifts on != 64 bits'); + assert(PRECISE_I64_MATH, 'Must have precise i64 math for non-constant 64-bit shifts'); + Types.preciseI64MathUsed = 1; value.intertype = 'value'; - value.ident = 'Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + + value.ident = 'var ' + value.assignTo + '$0 = _bitshift64' + value.op[0].toUpperCase() + value.op.substr(1) + '(' + asmCoercion(sourceElements[0].ident, 'i32') + ',' + asmCoercion(sourceElements[1].ident, 'i32') + ',' + - Runtime['BITSHIFT64_' + value.op.toUpperCase()] + ',' + asmCoercion(value.params[1].ident + '$0', 'i32') + ');' + - 'var ' + value.assignTo + '$0 = ' + makeGetTempDouble(0, 'i32') + ', ' + value.assignTo + '$1 = ' + makeGetTempDouble(1, 'i32') + ';'; + 'var ' + value.assignTo + '$1 = tempRet0;'; value.assignTo = null; i++; continue; diff --git a/src/jsifier.js b/src/jsifier.js index 18740e74..4263618a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1570,10 +1570,12 @@ function JSify(data, functionsOnly, givenFunctions) { // rest of the output that we started to print out earlier (see comment on the // "Final shape that will be created"). if (PRECISE_I64_MATH && Types.preciseI64MathUsed) { - ['i64Add'].forEach(function(func) { - print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code - Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig']; - }); + if (!INCLUDE_FULL_LIBRARY) { + ['i64Add', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr'].forEach(function(func) { + print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code + Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig']; + }); + } print('// EMSCRIPTEN_END_FUNCS\n'); print(read('long.js')); } else { diff --git a/src/library.js b/src/library.js index 62ef6db2..2daef933 100644 --- a/src/library.js +++ b/src/library.js @@ -4168,7 +4168,7 @@ LibraryManager.library = { return ret; }, - memcpy__asm: 'true', + memcpy__asm: true, memcpy__sig: 'iiii', memcpy: function (dest, src, num) { dest = dest|0; src = src|0; num = num|0; @@ -4329,7 +4329,7 @@ LibraryManager.library = { } }, - strcpy__asm: 'true', + strcpy__asm: true, strcpy__sig: 'iii', strcpy: function(pdest, psrc) { pdest = pdest|0; psrc = psrc|0; @@ -4350,7 +4350,7 @@ LibraryManager.library = { return pdest + i - 1; }, - strncpy__asm: 'true', + strncpy__asm: true, strncpy__sig: 'iiii', strncpy: function(pdest, psrc, num) { pdest = pdest|0; psrc = psrc|0; num = num|0; @@ -4462,7 +4462,7 @@ LibraryManager.library = { return 0; }, - memcmp__asm: 'true', + memcmp__asm: true, memcmp__sig: 'iiii', memcmp: function(p1, p2, num) { p1 = p1|0; p2 = p2|0; num = num|0; @@ -7363,7 +7363,7 @@ LibraryManager.library = { // i64 math //============================ - i64Add__asm: 'true', + i64Add__asm: true, i64Add__sig: 'iiiii', i64Add: function(a, b, c, d) { /* @@ -7380,7 +7380,7 @@ LibraryManager.library = { } {{{ makeStructuralReturn(['l|0', 'h'], true) }}}; }, - llvm_uadd_with_overflow_i64__asm: 'true', + llvm_uadd_with_overflow_i64__asm: true, llvm_uadd_with_overflow_i64__sig: 'iiiii', llvm_uadd_with_overflow_i64: function(a, b, c, d) { a = a|0; b = b|0; c = c|0; d = d|0; @@ -7393,6 +7393,46 @@ LibraryManager.library = { } {{{ makeStructuralReturn(['l|0', 'h', 'overflow'], true) }}}; }, + + bitshift64Shl__asm: true, + bitshift64Shl__sig: 'iiii', + bitshift64Shl: function(low, high, bits) { + low = low|0; high = high|0; bits = bits|0; + var ander = 0; + ander = ((1 << bits) - 1)|0; + if ((bits|0) < 32) { + tempRet0 = (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits)); + return low << bits; + } + tempRet0 = low << (bits - 32); + return 0; + }, + bitshift64Ashr__asm: true, + bitshift64Ashr__sig: 'iiii', + bitshift64Ashr: function(low, high, bits) { + low = low|0; high = high|0; bits = bits|0; + var ander = 0; + ander = ((1 << bits) - 1)|0; + if ((bits|0) < 32) { + tempRet0 = high >> bits; + return (low >>> bits) | ((high&ander) << (32 - bits)); + } + tempRet0 = (high|0) < 0 ? ander : 0; + return (high >> (bits - 32))|0; + }, + bitshift64Lshr__asm: true, + bitshift64Lshr__sig: 'iiii', + bitshift64Lshr: function(low, high, bits) { + low = low|0; high = high|0; bits = bits|0; + var ander = 0; + ander = ((1 << bits) - 1)|0; + if ((bits|0) < 32) { + tempRet0 = high >>> bits; + return (low >>> bits) | ((high&ander) << (32 - bits)); + } + tempRet0 = 0; + return (high >>> (bits - 32))|0; + }, }; function autoAddDeps(object, name) { diff --git a/src/runtime.js b/src/runtime.js index d5c0fabc..2a26db28 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -122,57 +122,6 @@ var Runtime = { INT_TYPES: set('i1', 'i8', 'i16', 'i32', 'i64'), FLOAT_TYPES: set('float', 'double'), - // Mirrors processMathop's treatment of constants (which we optimize directly) - BITSHIFT64_SHL: 0, - BITSHIFT64_ASHR: 1, - BITSHIFT64_LSHR: 2, - bitshift64: function(low, high, op, bits) { - var ret; - var ander = Math.pow(2, bits)-1; - if (bits < 32) { - switch (op) { - case Runtime.BITSHIFT64_SHL: - ret = [low << bits, (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits))]; - break; - case Runtime.BITSHIFT64_ASHR: - ret = [(((low >>> bits ) | ((high&ander) << (32 - bits))) >> 0) >>> 0, (high >> bits) >>> 0]; - break; - case Runtime.BITSHIFT64_LSHR: - ret = [((low >>> bits) | ((high&ander) << (32 - bits))) >>> 0, high >>> bits]; - break; - } - } else if (bits == 32) { - switch (op) { - case Runtime.BITSHIFT64_SHL: - ret = [0, low]; - break; - case Runtime.BITSHIFT64_ASHR: - ret = [high, (high|0) < 0 ? ander : 0]; - break; - case Runtime.BITSHIFT64_LSHR: - ret = [high, 0]; - break; - } - } else { // bits > 32 - switch (op) { - case Runtime.BITSHIFT64_SHL: - ret = [0, low << (bits - 32)]; - break; - case Runtime.BITSHIFT64_ASHR: - ret = [(high >> (bits - 32)) >>> 0, (high|0) < 0 ? ander : 0]; - break; - case Runtime.BITSHIFT64_LSHR: - ret = [high >>> (bits - 32) , 0]; - break; - } - } -#if ASSERTIONS - assert(ret); -#endif - HEAP32[tempDoublePtr>>2] = ret[0]; // cannot use utility functions since we are in runtime itself - HEAP32[tempDoublePtr+4>>2] = ret[1]; - }, - // Imprecise bitops utilities or64: function(x, y) { var l = (x | 0) | (y | 0); |