aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-27 11:39:30 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-27 11:39:30 -0800
commit2de8bb327d67075c339531ab23300200fb8714de (patch)
treebe441ac15fee6ade2baadad8971daf741fa7816a /src
parentf5601d0f69dda3fca34beb84537d52f6b8d0e927 (diff)
legalize switch i64
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js28
-rw-r--r--src/jsifier.js2
-rw-r--r--src/parseTools.js14
3 files changed, 37 insertions, 7 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 33441697..15d66285 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -120,10 +120,6 @@ function analyzer(data, sidePass) {
processItem: function(data) {
// Legalization
if (USE_TYPED_ARRAYS == 2) {
- function isIllegalType(type) {
- var bits = getBits(type);
- return bits > 0 && (bits >= 64 || !isPowerOfTwo(bits));
- }
function getLegalVars(base, bits) {
assert(!isNumber(base));
var ret = new Array(Math.ceil(bits/32));
@@ -230,6 +226,19 @@ function analyzer(data, sidePass) {
unfolded.unshift(subItem);
fixUnfolded(subItem);
return { intertype: 'value', ident: tempIdent, type: subItem.type };
+ } else if (subItem.intertype == 'switch' && isIllegalType(subItem.type)) {
+ subItem.switchLabels.forEach(function(switchLabel) {
+ if (switchLabel.value[0] != '$') {
+ var tempIdent = '$$emscripten$temp$' + (tempId++);
+ unfolded.unshift({
+ assignTo: tempIdent,
+ intertype: 'value',
+ ident: switchLabel.value,
+ type: subItem.type
+ });
+ switchLabel.value = tempIdent;
+ }
+ });
}
});
if (unfolded.length > 0) {
@@ -383,6 +392,10 @@ function analyzer(data, sidePass) {
i += removeAndAdd(label.lines, i, toAdd);
continue;
}
+ case 'switch': {
+ i++;
+ continue; // special case, handled in makeComparison
+ }
case 'bitcast': {
var inType = item.type2;
var outType = item.type;
@@ -570,8 +583,11 @@ function analyzer(data, sidePass) {
}
if (targetBits <= 32) {
// We are generating a normal legal type here
- legalValue = { intertype: 'value', ident: targetElements[0].ident, type: 'rawJS' };
- // truncation to smaller than 32 bits has already been done, if necessary
+ legalValue = {
+ intertype: 'value',
+ ident: targetElements[0].ident + (targetBits < 32 ? '&' + (Math.pow(2, targetBits)-1) : ''),
+ type: 'rawJS'
+ };
legalValue.assignTo = item.assignTo;
toAdd.push(legalValue);
}
diff --git a/src/jsifier.js b/src/jsifier.js
index fccfaa74..56e49788 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -924,7 +924,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
first = false;
}
- ret += 'if (' + targetLabels[targetLabel].map(function(value) { return item.ident + ' == ' + value }).join(' || ') + ') {\n';
+ ret += 'if (' + targetLabels[targetLabel].map(function(value) { return makeComparison(item.ident, value, item.type) }).join(' || ') + ') {\n';
ret += ' ' + getPhiSetsForLabel(phiSets, targetLabel) + makeBranch(targetLabel, item.currLabelId || null) + '\n';
ret += '}\n';
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 0eb0bac9..41caeaad 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -140,6 +140,11 @@ function getBits(type) {
return parseInt(left);
}
+function isIllegalType(type) {
+ var bits = getBits(type);
+ return bits > 0 && (bits >= 64 || !isPowerOfTwo(bits));
+}
+
function isVoidType(type) {
return type == 'void';
}
@@ -1465,6 +1470,15 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
return ret;
}
+function makeComparison(a, b, type) {
+ if (!isIllegalType(type)) {
+ return a + ' == ' + b;
+ } else {
+ assert(type == 'i64');
+ return a + '$0 == ' + b + '$0 && ' + a + '$1 == ' + b + '$1';
+ }
+}
+
function makeSignOp(value, type, op, force, ignore) {
if (USE_TYPED_ARRAYS == 2 && type == 'i64') {
return value; // these are always assumed to be two 32-bit unsigneds.