aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-23 15:58:23 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-23 15:58:23 -0800
commit19fc5147a448901be239e6d4f9d777e75cfb15d6 (patch)
tree6836af935fc139820cea709bffd0e4260608d096
parentc5792d7e865ac6b41aa1a056c71a9e1ed1ea7f77 (diff)
support unaligned reads/writes in ta2; fixes test_cubescript
-rw-r--r--src/parseTools.js57
-rw-r--r--src/preamble.js1
-rw-r--r--src/settings.js7
-rwxr-xr-xtests/runner.py3
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|.