aboutsummaryrefslogtreecommitdiff
path: root/src/parseTools.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/parseTools.js')
-rw-r--r--src/parseTools.js38
1 files changed, 32 insertions, 6 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index 2ab43ebf..c1eff803 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -546,7 +546,7 @@ function splitI64(value) {
// 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.
if (legalizedI64s) {
- return [value + '>>>0', 'Math.min(Math.floor(' + value + '/4294967296), 4294967295)'];
+ return [value + '>>>0', 'Math.min(Math.floor((' + value + ')/4294967296), 4294967295)'];
} else {
return makeInlineCalculation(makeI64('VALUE>>>0', 'Math.min(Math.floor(VALUE/4294967296), 4294967295)'), value, 'tempBigIntP');
}
@@ -606,6 +606,22 @@ function parseArbitraryInt(str, bits) {
}
}
+ function mul2(v) { // v *= 2
+ for (var i = v.length-1; i >= 0; i--) {
+ var d = v[i]*2;
+ r = d >= 10;
+ v[i] = d%10;
+ var j = i-1;
+ if (r) {
+ if (j < 0) {
+ v.unshift(1);
+ break;
+ }
+ v[j] += 0.5; // will be multiplied
+ }
+ }
+ }
+
function subtract(v, w) { // v -= w. we assume v >= w
while (v.length > w.length) w.splice(0, 0, 0);
for (var i = 0; i < v.length; i++) {
@@ -635,9 +651,11 @@ function parseArbitraryInt(str, bits) {
if (str[0] == '-') {
// twos-complement is needed
- assert(bits == 64, "we only support 64-bit two's complement so far");
str = str.substr(1);
- v = str2vec('18446744073709551616'); // 2^64
+ v = str2vec('1');
+ for (var i = 0; i < bits; i++) {
+ mul2(v);
+ }
subtract(v, str2vec(str));
} else {
v = str2vec(str);
@@ -1644,7 +1662,7 @@ function processMathop(item) {
case 'fptoui': case 'fptosi': return finish(splitI64(ident1));
case 'icmp': {
switch (variant) {
- case 'uge': return high1 + ' >= ' + high2 + ' && (' + high1 + ' > ' + high + ' || ' +
+ case 'uge': return high1 + ' >= ' + high2 + ' && (' + high1 + ' > ' + high2 + ' || ' +
low1 + ' >= ' + low2 + ')';
case 'sge': return '(' + high1 + '|0) >= (' + high2 + '|0) && ((' + high1 + '|0) > (' + high2 + '|0) || ' +
'(' + low1 + '|0) >= (' + low2 + '|0))';
@@ -1685,9 +1703,17 @@ function processMathop(item) {
var inType = item.param1.type;
var outType = item.type;
if (inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) {
- return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', ident1, 'tempI64');
+ if (legalizedI64s) {
+ return '(tempDoubleI32[0]=' + ident1 + '$0, tempDoubleI32[1]=' + ident1 + '$1, tempDoubleF64[0])';
+ } else {
+ return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', ident1, 'tempI64');
+ }
} else if (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES) {
- return '(tempDoubleF64[0]=' + ident1 + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ if (legalizedI64s) {
+ return 'tempDoubleF64[0]=' + ident1 + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']);
+ } else {
+ return '(tempDoubleF64[0]=' + ident1 + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ }
} else {
throw 'Invalid I64_MODE1 bitcast: ' + dump(item) + ' : ' + item.param1.type;
}