diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-05-25 07:16:26 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-05-25 07:16:26 -0700 |
commit | f0b0519c989c4b3a418857ac2d54c09c36966b76 (patch) | |
tree | 1e96dd016a63566a625ab1424673b5524bc409fc | |
parent | a33bd79873b6872c7fab3fa4992ef9749f2c0aa5 (diff) |
64-bit bitops
-rw-r--r-- | src/library.js | 2 | ||||
-rw-r--r-- | src/parseTools.js | 27 | ||||
-rw-r--r-- | src/runtime.js | 16 | ||||
-rw-r--r-- | tests/runner.py | 13 |
4 files changed, 54 insertions, 4 deletions
diff --git a/src/library.js b/src/library.js index ff485bc3..471bbc96 100644 --- a/src/library.js +++ b/src/library.js @@ -113,7 +113,7 @@ var Library = { } next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; } - if (next == 'l'.charCodeAt(0)) { + if (next == 'l'.charCodeAt(0) || next == 'L'.charCodeAt(0)) { textIndex++; next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; } diff --git a/src/parseTools.js b/src/parseTools.js index bc83e4ea..03b88c0f 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -916,9 +916,30 @@ function processMathop(item) { with(item) { case 'sdiv': case 'udiv': return makeRounding(ident1 + '/' + ident2, bits, op[0] === 's'); case 'mul': return handleOverflow(ident1 + ' * ' + ident2, bits); case 'urem': case 'srem': return ident1 + ' % ' + ident2; - case 'or': return ident1 + ' | ' + ident2; // TODO this forces into a 32-bit int - add overflow-style checks? also other bitops below us - case 'and': return ident1 + ' & ' + ident2; - case 'xor': return ident1 + ' ^ ' + ident2; + case 'or': { + if (bits > 32) { + assert(bits === 64, 'Too many bits for or: ' + bits); + dprint('Warning: 64 bit OR - precision limit may be hit'); + return 'Runtime.or64(' + ident1 + ', ' + ident2 + ')'; + } + return ident1 + ' | ' + ident2; + } + case 'and': { + if (bits > 32) { + assert(bits === 64, 'Too many bits for and: ' + bits); + dprint('Warning: 64 bit AND - precision limit may be hit'); + return 'Runtime.and64(' + ident1 + ', ' + ident2 + ')'; + } + return ident1 + ' & ' + ident2; + } + case 'xor': { + if (bits > 32) { + assert(bits === 64, 'Too many bits for xor: ' + bits); + dprint('Warning: 64 bit XOR - precision limit may be hit'); + return 'Runtime.xor64(' + ident1 + ', ' + ident2 + ')'; + } + return ident1 + ' ^ ' + ident2; + } case 'shl': { // Note: Increases in size may reach the 32-bit limit... where our sign can flip. But this may be expected by the code... /* diff --git a/src/runtime.js b/src/runtime.js index b0378e08..1aefc135 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -85,6 +85,22 @@ Runtime = { INT_TYPES: set('i1', 'i8', 'i16', 'i32', 'i64'), FLOAT_TYPES: set('float', 'double'), + or64: function(x, y) { + var l = (x | 0) | (y | 0); + var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296; + return l + h; + }, + and64: function(x, y) { + var l = (x | 0) & (y | 0); + var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296; + return l + h; + }, + xor64: function(x, y) { + var l = (x | 0) ^ (y | 0); + var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296; + return l + h; + }, + getNativeFieldSize: getNativeFieldSize, dedup: dedup, diff --git a/tests/runner.py b/tests/runner.py index c0814c52..4fb8e2d7 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -422,6 +422,19 @@ if 'benchmark' not in sys.argv: global CORRECT_OVERFLOWS; CORRECT_OVERFLOWS = 0 # We should not need overflow correction to get this right self.do_test(src, output, force_c=True) + def test_bigint(self): + src = ''' + #include <stdio.h> + int main() + { + long long x = 0x0000def123450789ULL; // any bigger than this, and we + long long y = 0x00020ef123456089ULL; // start to run into the double precision limit! + printf("*%Ld,%Ld,%Ld,%Ld,%Ld*\\n", x, y, x | y, x & y, x ^ y, x >> 2, y << 2); + return 0; + } + ''' + self.do_test(src, '*245127260211081,579378795077769,808077213656969,16428841631881,791648372025088*') + def test_unsigned(self): global CORRECT_SIGNS; CORRECT_SIGNS = 1 # We test for exactly this sort of thing here src = ''' |