diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-11-11 15:30:21 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-11-11 15:30:21 -0800 |
commit | 43c47cb2593903f64949c2d6d2ba60cb39480307 (patch) | |
tree | 9db6e45ae977dbe501368d9488878fe8af825618 /src/parseTools.js | |
parent | 7ea5dd5b4ecba3f678fe846e78560fbd9d3b3d1c (diff) |
roundy math ops (add etc.) in i64=1
Diffstat (limited to 'src/parseTools.js')
-rw-r--r-- | src/parseTools.js | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index da4c4352..bdb5c533 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -540,10 +540,15 @@ function makeI64(low, high) { } } -// Splits a number (an integer in a double, possibly > 32 bits) into an I64_MODE 1 i64 value +// Splits a number (an integer in a double, possibly > 32 bits) into an I64_MODE 1 i64 value. +// Will suffer from rounding. margeI64 does the opposite. function splitI64(value) { assert(I64_MODE == 1); - return makeI64(value + '|0', 'Math.floor(' + value + '/4294967296)'); + return '(tempInt=' + value + ',' + makeI64('tempInt|0', 'Math.floor(tempInt/4294967296)') + ')'; +} +function mergeI64(value) { + assert(I64_MODE == 1); + return '(tempI64=' + value + ',tempI64[0]+tempI64[1]*4294967296)'; } function makeCopyI64(value) { @@ -1469,6 +1474,12 @@ function processMathop(item) { with(item) { } case 'select': return ident1 + ' ? ' + makeCopyI64(ident2) + ' : ' + makeCopyI64(ident3); case 'ptrtoint': case 'inttoptr': throw 'Pointers cannot be 64-bit!'; + // Dangerous, rounded operations. TODO: Fully emulate + case 'add': return handleOverflow(splitI64(mergeI64(ident1) + '+' + mergeI64(ident2)), bits); + case 'sub': return handleOverflow(splitI64(mergeI64(ident1) + '-' + mergeI64(ident2)), bits); + case 'sdiv': case 'udiv': return splitI64(makeRounding(mergeI64(ident1) + '/' + mergeI64(ident2), bits, op[0] === 's')); + case 'mul': return handleOverflow(splitI64(mergeI64(ident1) + '*' + mergeI64(ident2)), bits); + case 'urem': return splitI64(mergeI64(ident1) + '%' + mergeI64(ident2)); default: throw 'Unsupported i64 mode 1 op: ' + item.op; } } |