aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js9
-rw-r--r--src/jsifier.js8
-rw-r--r--src/parseTools.js20
-rw-r--r--src/runtime.js21
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;
}