diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-02-27 11:39:30 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-02-27 11:39:30 -0800 |
commit | 2de8bb327d67075c339531ab23300200fb8714de (patch) | |
tree | be441ac15fee6ade2baadad8971daf741fa7816a /src | |
parent | f5601d0f69dda3fca34beb84537d52f6b8d0e927 (diff) |
legalize switch i64
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 28 | ||||
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rw-r--r-- | src/parseTools.js | 14 |
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. |