aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-30 13:41:06 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-30 13:41:06 -0800
commitc707fc8a860649099ba475a61aa1f8c8203774f4 (patch)
tree6dfc597699ed9d312a402aca3b0d4687cae2a27f /src
parent764e81bd041395d4e3bd78c9c53b0676e34ef377 (diff)
handle 32-bit bitcasts int <-> float properly
Diffstat (limited to 'src')
-rw-r--r--src/intertyper.js2
-rw-r--r--src/jsifier.js5
-rw-r--r--src/parseTools.js17
3 files changed, 21 insertions, 3 deletions
diff --git a/src/intertyper.js b/src/intertyper.js
index cf1d28ed..d03810d4 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -647,7 +647,7 @@ function intertyper(data, sidePass, baseLineNums) {
item.type = item.tokens[4].text; // The final type
Types.needAnalysis[item.type] = 0;
var to = getTokenIndexByText(item.tokens, 'to');
- item.params = [parseLLVMSegment(item.tokens.slice(2, to))];
+ item.params = [parseLLVMSegment(item.tokens.slice(1, to))];
item.ident = item.params[0].ident;
item.type2 = item.tokens[1].text; // The original type
Types.needAnalysis[item.type2] = 0;
diff --git a/src/jsifier.js b/src/jsifier.js
index 62cab3d5..e52d3a00 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1032,7 +1032,10 @@ function JSify(data, functionsOnly, givenFunctions) {
makeFuncLineActor('mathop', processMathop);
makeFuncLineActor('bitcast', function(item) {
- return finalizeLLVMParameter(item.params[0]);
+ return processMathop({
+ op: 'bitcast', variant: null, type: item.type,
+ param1: item.params[0]
+ });
});
function makeFunctionCall(ident, params, funcData, type) {
diff --git a/src/parseTools.js b/src/parseTools.js
index d4ef27eb..cc59f150 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1815,7 +1815,22 @@ function processMathop(item) {
assert(bitsLeft <= 32, 'Cannot truncate to more than 32 bits, since we use a native & op');
return '((' + ident1 + ') & ' + (Math.pow(2, bitsLeft)-1) + ')';
}
- case 'bitcast': return ident1;
+ case 'bitcast': {
+ // Most bitcasts are no-ops for us. However, the exception is int to float and float to int
+ var inType = item.param1.type;
+ var outType = item.type;
+ if ((inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) ||
+ (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES)) {
+ assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2');
+ assert(inType == 'i32' || inType == 'float', 'Can only bitcast ints <-> floats with 32 bits, for now');
+ if (inType in Runtime.INT_TYPES) {
+ return '(tempDoubleI32[0] = ' + ident1 + ',tempDoubleF32[0])';
+ } else {
+ return '(tempDoubleF32[0] = ' + ident1 + ',tempDoubleI32[0])';
+ }
+ }
+ return ident1;
+ }
default: throw 'Unknown mathcmp op: ' + item.op;
}
}