aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-07 19:09:36 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-07 19:09:36 -0800
commitcd7d64a1945a7309804008feead7ebe4acb5a722 (patch)
tree831a8c939c33cc8205aa284b363498f2fc68e031
parentc3e992c15d5aa3ff6e36f51818845fadb32fa60c (diff)
fix for unaligned stores of non-nativized doubles
-rw-r--r--src/parseTools.js12
-rw-r--r--tests/cases/unaligneddouble.ll24
2 files changed, 30 insertions, 6 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index a5752e67..f2f72fa3 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -962,8 +962,8 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe,
if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') {
return '(tempDoubleF64[0]=' + value + ',' +
- makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align) + ',' +
- makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align) + ')';
+ makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' +
+ makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')';
}
if (USE_TYPED_ARRAYS == 2 && align) {
@@ -976,18 +976,18 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe,
// Special case that we can optimize
ret += 'tempBigInt=' + value + sep;
ret += makeSetValue(ptr, pos, 'tempBigInt&0xffff', 'i16', noNeedFirst, ignore, 2) + sep;
- ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2) + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2);
} else if (bytes <= 4) {
ret += 'tempBigInt=' + value + sep;
for (var i = 0; i < bytes; i++) {
- ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1) + sep;
- if (i < bytes-1) ret += 'tempBigInt>>=8' + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1);
+ if (i < bytes-1) ret += sep + 'tempBigInt>>=8' + sep;
}
} else {
assert(bytes == 8);
ret += 'tempPair=' + ensureI64_1(value) + sep;
ret += makeSetValue(ptr, pos, 'tempPair[0]', 'i32', noNeedFirst, ignore, align) + sep;
- ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align) + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align);
}
} else {
ret += makeSetValue('tempDoublePtr', 0, value, type, noNeedFirst, ignore, 8) + sep;
diff --git a/tests/cases/unaligneddouble.ll b/tests/cases/unaligneddouble.ll
new file mode 100644
index 00000000..22b92741
--- /dev/null
+++ b/tests/cases/unaligneddouble.ll
@@ -0,0 +1,24 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4 ; [#uses=1 type=i32*]
+ %doub = alloca double, align 4
+ store i32 0, i32* %retval
+ %0 = bitcast double* %doub to i32
+ %1 = uitofp i32 %0 to double
+ store double %1, double* %doub, align 1
+ store double %1, double* %doub, align 2
+ store double %1, double* %doub, align 4
+ store double %1, double* %doub, align 8
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
+ ret i32 1
+}
+
+; [#uses=1]
+declare i32 @printf(i8*, ...)