diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-23 15:58:23 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-23 15:58:23 -0800 |
commit | 19fc5147a448901be239e6d4f9d777e75cfb15d6 (patch) | |
tree | 6836af935fc139820cea709bffd0e4260608d096 | |
parent | c5792d7e865ac6b41aa1a056c71a9e1ed1ea7f77 (diff) |
support unaligned reads/writes in ta2; fixes test_cubescript
-rw-r--r-- | src/parseTools.js | 57 | ||||
-rw-r--r-- | src/preamble.js | 1 | ||||
-rw-r--r-- | src/settings.js | 7 | ||||
-rwxr-xr-x | tests/runner.py | 3 |
4 files changed, 38 insertions, 30 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 18ce807e..d6c883dd 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -912,23 +912,30 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa 'tempDoubleF64[0])'; } - if (EMULATE_UNALIGNED_ACCESSES && USE_TYPED_ARRAYS == 2 && align && isIntImplemented(type)) { // TODO: support unaligned doubles and floats + if (USE_TYPED_ARRAYS == 2 && align) { // Alignment is important here. May need to split this up var bytes = Runtime.getNativeTypeSize(type); if (bytes > align) { - var ret = '/* unaligned */('; - if (bytes <= 4) { - for (var i = 0; i < bytes; i++) { - ret += 'tempInt' + (i == 0 ? '=' : (i < bytes-1 ? '+=((' : '+((')); - ret += makeSignOp(makeGetValue(ptr, getFastValue(pos, '+', i), 'i8', noNeedFirst, unsigned, ignore), 'i8', 'un', true); - if (i > 0) ret += ')<<' + (8*i) + ')'; - if (i < bytes-1) ret += ','; + var ret = '('; + if (isIntImplemented(type)) { + if (bytes <= 4) { + for (var i = 0; i < bytes; i++) { + ret += 'tempInt' + (i == 0 ? '=' : (i < bytes-1 ? '+=((' : '+((')); + ret += makeGetValue(ptr, getFastValue(pos, '+', i), 'i8', noNeedFirst, 1, ignore); + if (i > 0) ret += ')<<' + (8*i) + ')'; + if (i < bytes-1) ret += ','; + } + if (signed) { + ret += ',' + makeSignOp('tempInt', type, 're', true); + } + } else { + assert(bytes == 8); + ret += 'tempBigInt=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, true, ignore, align) + ','; + ret += 'tempBigInt2=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, true, ignore, align) + ','; + ret += makeI64('tempBigInt', 'tempBigInt2'); } } else { - assert(bytes == 8); - ret += 'tempBigInt=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, true, ignore, align) + ','; - ret += 'tempBigInt2=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, true, ignore, align) + ','; - ret += makeI64('tempBigInt', 'tempBigInt2'); + assert(0, 'We do not support unaligned float/double reads yet'); } ret += ')'; return ret; @@ -994,22 +1001,26 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe) makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align) + ')'; } - if (EMULATE_UNALIGNED_ACCESSES && USE_TYPED_ARRAYS == 2 && align && isIntImplemented(type)) { // TODO: support unaligned doubles and floats + if (USE_TYPED_ARRAYS == 2 && align) { // Alignment is important here. May need to split this up var bytes = Runtime.getNativeTypeSize(type); if (bytes > align) { - var ret = '/* unaligned */'; - if (bytes <= 4) { - ret += 'tempBigInt=' + value + ';'; - for (var i = 0; i < bytes; i++) { - ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore) + ';'; - if (i < bytes-1) ret += 'tempBigInt>>=8;'; + var ret = ''; + if (isIntImplemented(type)) { + if (bytes <= 4) { + ret += 'tempBigInt=' + value + ';'; + for (var i = 0; i < bytes; i++) { + ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore) + ';'; + if (i < bytes-1) ret += 'tempBigInt>>=8;'; + } + } else { + assert(bytes == 8); + ret += 'tempPair=' + ensureI64_1(value) + ';'; + ret += makeSetValue(ptr, pos, 'tempPair[0]', 'i32', noNeedFirst, ignore, align) + ';'; + ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align) + ';'; } } else { - assert(bytes == 8); - ret += 'tempPair=' + ensureI64_1(value) + ';'; - ret += makeSetValue(ptr, pos, 'tempPair[0]', 'i32', noNeedFirst, ignore, align) + ';'; - ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align) + ';'; + assert(0, 'We do not support unaligned float/double writes yet'); } return ret; } diff --git a/src/preamble.js b/src/preamble.js index 5c5c21ea..229699a9 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -347,6 +347,7 @@ var tempI64, tempI64b; #if DOUBLE_MODE == 1 #if USE_TYPED_ARRAYS == 2 var tempDoubleBuffer = new ArrayBuffer(8); +//var tempDoubleI8 = new Int8Array(tempDoubleBuffer); var tempDoubleI32 = new Int32Array(tempDoubleBuffer); var tempDoubleF64 = new Float64Array(tempDoubleBuffer); #endif diff --git a/src/settings.js b/src/settings.js index 7e900ea9..ae07b1f4 100644 --- a/src/settings.js +++ b/src/settings.js @@ -73,13 +73,6 @@ var DOUBLE_MODE = 1; // How to load and store 64-bit doubles. Without typed arra // then load it aligned, and that load-store will make JS engines alter it if it is being // stored to a typed array for security reasons. That will 'fix' the number from being a // NaN or an infinite number. -var EMULATE_UNALIGNED_ACCESSES = 0; // If set, the compiler will 'emulate' loads and stores that are not known to - // be sufficiently aligned, by working on individual bytes. This can be - // important in USE_TYPED_ARRAYS == 2, where unaligned accesses do not work, - // specifically in the case where unsafe LLVM optimizations have generated possibly - // unaligned code. (Without unsafe LLVM optimizations, there should be no - // need for this option.) - // Currently this only works for integers, not doubles and floats. var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure // compiler. This potentially lets closure optimize the code better. diff --git a/tests/runner.py b/tests/runner.py index 24cf78af..8016a26a 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -5545,6 +5545,9 @@ f.close() output = Popen([NODE_JS, JS_OPTIMIZER, input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] self.assertIdentical(expected, output.replace('\n\n', '\n')) + def test_reminder(self): + assert False, 'Optimize makeGet/SetValue to do 16-bit reads/writes when possible, not just 8' + elif 'benchmark' in str(sys.argv): # Benchmarks. Run them with argument |benchmark|. To run a specific test, do # |benchmark.test_X|. |