aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-05-25 07:16:26 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-05-25 07:16:26 -0700
commitf0b0519c989c4b3a418857ac2d54c09c36966b76 (patch)
tree1e96dd016a63566a625ab1424673b5524bc409fc /src
parenta33bd79873b6872c7fab3fa4992ef9749f2c0aa5 (diff)
64-bit bitops
Diffstat (limited to 'src')
-rw-r--r--src/library.js2
-rw-r--r--src/parseTools.js27
-rw-r--r--src/runtime.js16
3 files changed, 41 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,