aboutsummaryrefslogtreecommitdiff
path: root/src/parseTools.js
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-01-22 16:56:29 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-01-22 16:56:29 -0800
commit857f0e302120bf5bd95be0982a5af56eeacd4474 (patch)
treef4dd25ec7c05701b1a9cf57ab548a2db52833963 /src/parseTools.js
parentd43e4bf77f2a5083f384c33fbc94cfc8995114e3 (diff)
asm coercions in splitI64
Diffstat (limited to 'src/parseTools.js')
-rw-r--r--src/parseTools.js14
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)) | ' +