diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-01-22 16:56:29 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-01-22 16:56:29 -0800 |
commit | 857f0e302120bf5bd95be0982a5af56eeacd4474 (patch) | |
tree | f4dd25ec7c05701b1a9cf57ab548a2db52833963 /src/parseTools.js | |
parent | d43e4bf77f2a5083f384c33fbc94cfc8995114e3 (diff) |
asm coercions in splitI64
Diffstat (limited to 'src/parseTools.js')
-rw-r--r-- | src/parseTools.js | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 9e478cb7..97864602 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -641,14 +641,16 @@ function makeI64(low, high) { // Splits a number (an integer in a double, possibly > 32 bits) into an USE_TYPED_ARRAYS == 2 i64 value. // Will suffer from rounding. mergeI64 does the opposite. -function splitI64(value) { +function splitI64(value, floatConversion) { // We need to min here, since our input might be a double, and large values are rounded, so they can // be slightly higher than expected. And if we get 4294967296, that will turn into a 0 if put into a // HEAP32 or |0'd, etc. + var lowInput = legalizedI64s ? value : 'VALUE'; + if (floatConversion && ASM_JS) lowInput = asmFloatToInt(lowInput); if (legalizedI64s) { - return [value + '>>>0', 'Math.min(Math.floor((' + value + ')/4294967296), 4294967295)']; + return [lowInput + '>>>0', 'Math.min(Math.floor((' + value + ')/' + asmEnsureFloat(4294967296, 'float') + '), ' + asmEnsureFloat(4294967295, 'float') + ')>>>0']; } else { - return makeInlineCalculation(makeI64('VALUE>>>0', 'Math.min(Math.floor(VALUE/4294967296), 4294967295)'), value, 'tempBigIntP'); + return makeInlineCalculation(makeI64(lowInput + '>>>0', 'Math.min(Math.floor(VALUE/' + asmEnsureFloat(4294967296, 'float') + '), ' + asmEnsureFloat(4294967295, 'float') + ')>>>0'), value, 'tempBigIntP'); } } function mergeI64(value, unsigned) { @@ -1044,6 +1046,10 @@ function asmMultiplyI32(a, b) { return '(~~(+((' + a + ')|0) * +((' + b + ')|0)))'; } +function asmFloatToInt(x) { + return '(~~(' + x + '))'; +} + function makeGetTempDouble(i, type, forSet) { // get an aliased part of the tempDouble temporary storage // Cannot use makeGetValue because it uses us // this is a unique case where we *can* use HEAPF64 @@ -2002,7 +2008,7 @@ function processMathop(item) { } } case 'uitofp': case 'sitofp': return RuntimeGenerator.makeBigInt(low1, high1, op[0] == 'u'); - case 'fptoui': case 'fptosi': return finish(splitI64(idents[0])); + case 'fptoui': case 'fptosi': return finish(splitI64(idents[0], true)); case 'icmp': { switch (variant) { case 'uge': return '((' + high1 + '>>>0) >= (' + high2 + '>>>0)) & ((((' + high1 + '>>>0) > (' + high2 + '>>>0)) | ' + |