diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 9 | ||||
-rw-r--r-- | src/jsifier.js | 8 | ||||
-rw-r--r-- | src/parseTools.js | 20 | ||||
-rw-r--r-- | src/runtime.js | 21 |
4 files changed, 36 insertions, 22 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index d91bbe73..229bda9f 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -654,9 +654,12 @@ function analyzer(data, sidePass) { // We can't statically legalize this, do the operation at runtime TODO: optimize assert(sourceBits == 64, 'TODO: handle nonconstant shifts on != 64 bits'); value.intertype = 'value'; - value.ident = 'Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + sourceElements[0].ident + ', ' + - sourceElements[1].ident + ',"' + value.op + '",' + value.params[1].ident + '$0);' + - 'var ' + value.assignTo + '$0 = ' + makeGetTempDouble(0, 'i32') + ', ' + value.assignTo + '$1 = ' + makeGetTempDouble(1, 'i32') + ';'; + value.ident = 'Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + + 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') + ';'; value.assignTo = null; i++; continue; diff --git a/src/jsifier.js b/src/jsifier.js index 83ddc62e..5fbea5ba 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1313,8 +1313,12 @@ function JSify(data, functionsOnly, givenFunctions) { }); args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); - if (ASM_JS && shortident in Functions.libraryFunctions) { - args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); + if (ASM_JS) { + if (shortident in Functions.libraryFunctions) { + args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); + } else { + args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) }); + } } varargs = varargs.map(function(vararg, i) { diff --git a/src/parseTools.js b/src/parseTools.js index 268d0e24..3ff5e710 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1019,14 +1019,18 @@ function asmCoercion(value, type, signedness) { if (type == 'void') { return value; } else if (type in Runtime.FLOAT_TYPES) { - if (signedness) { - if (signedness == 'u') { - value = '(' + value + ')>>>0'; - } else { - value = '(' + value + ')|0'; + if (isNumber(value)) { + return asmEnsureFloat(value, type); + } else { + if (signedness) { + if (signedness == 'u') { + value = '(' + value + ')>>>0'; + } else { + value = '(' + value + ')|0'; + } } + return '(+(' + value + '))'; } - return '(+(' + value + '))'; } else { return '((' + value + ')|0)'; } @@ -1887,7 +1891,7 @@ function processMathop(item) { function i64PreciseOp(type, lastArg) { Types.preciseI64MathUsed = true; return finish(['(i64Math' + (ASM_JS ? '_' : '.') + type + '(' + asmCoercion(low1, 'i32') + ',' + asmCoercion(high1, 'i32') + ',' + asmCoercion(low2, 'i32') + ',' + asmCoercion(high2, 'i32') + - (lastArg ? ',' + asmCoercion(lastArg, 'i32') : '') + '),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')', makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32'), 'i32')]); + (lastArg ? ',' + asmCoercion(+lastArg, 'i32') : '') + '),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')', makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32'), 'i32')]); } switch (op) { // basic integer ops @@ -1904,7 +1908,7 @@ function processMathop(item) { case 'ashr': case 'lshr': { if (!isNumber(idents[1])) { - return '(Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0),' + + return '(Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],' + Runtime['BITSHIFT64_' + op.toUpperCase()] + ',' + stripCorrections(idents[1]) + '[0]|0),' + '[' + makeGetTempDouble(0, 'i32') + ',' + makeGetTempDouble(1, 'i32') + '])'; } bits = parseInt(idents[1]); diff --git a/src/runtime.js b/src/runtime.js index 9d5e5e1f..d1475bd4 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -123,42 +123,45 @@ var Runtime = { 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 'shl': + case Runtime.BITSHIFT64_SHL: ret = [low << bits, (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits))]; break; - case 'ashr': + case Runtime.BITSHIFT64_ASHR: ret = [(((low >>> bits ) | ((high&ander) << (32 - bits))) >> 0) >>> 0, (high >> bits) >>> 0]; break; - case 'lshr': + case Runtime.BITSHIFT64_LSHR: ret = [((low >>> bits) | ((high&ander) << (32 - bits))) >>> 0, high >>> bits]; break; } } else if (bits == 32) { switch (op) { - case 'shl': + case Runtime.BITSHIFT64_SHL: ret = [0, low]; break; - case 'ashr': + case Runtime.BITSHIFT64_ASHR: ret = [high, (high|0) < 0 ? ander : 0]; break; - case 'lshr': + case Runtime.BITSHIFT64_LSHR: ret = [high, 0]; break; } } else { // bits > 32 switch (op) { - case 'shl': + case Runtime.BITSHIFT64_SHL: ret = [0, low << (bits - 32)]; break; - case 'ashr': + case Runtime.BITSHIFT64_ASHR: ret = [(high >> (bits - 32)) >>> 0, (high|0) < 0 ? ander : 0]; break; - case 'lshr': + case Runtime.BITSHIFT64_LSHR: ret = [high >>> (bits - 32) , 0]; break; } |