diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 09:28:44 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 09:28:44 -0800 |
commit | bbab542ca777f91cae76244dc8455c800de58ce7 (patch) | |
tree | 1470abc99ffce2b94c18d86438dcf9977bdb099c | |
parent | f8d4a502913713757355a700bda4ddf7270121ed (diff) |
legalize lshr
-rw-r--r-- | src/analyzer.js | 53 | ||||
-rw-r--r-- | src/jsifier.js | 3 | ||||
-rw-r--r-- | src/parseTools.js | 2 |
3 files changed, 57 insertions, 1 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 4839134f..2eb6f8d5 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -254,7 +254,7 @@ function analyzer(data, sidePass) { } } case 'mathop': { - if (isIllegalType(value.valueType)) { + if (isIllegalType(value.type)) { dprint('legalizer', 'Legalizing mathop at line ' + item.lineNum); bits = getBits(value.type); var targetElements = getLegalVars(item.ident, bits); @@ -263,6 +263,57 @@ function analyzer(data, sidePass) { label.lines.splice(i, 1); switch (value.op) { case 'lshr': { + assert(value.param2.intertype == 'value', 'TODO: unfolding'); + var shifts = parseInt(value.param2.ident); + assert(isNumber(shifts), 'TODO: handle nonconstant shifts'); + // Shift right makes values smaller. Towards the 0 index of the elements + var whole = Math.floor(shifts/32); + var fraction = shifts % 32; + var toAdd = []; + for (var j = 0; j < targetElements.length; j++) { + var result = { + intertype: 'value', + ident: (j + whole) < sourceElements.length ? sourceElements[j + whole].ident : '0', + type: 'i32', + }; + if (fraction > 0) { + var other = { + intertype: 'value', + ident: (j + 1 + whole) < sourceElements.length ? sourceElements[j + 1 + whole].ident : '0', + type: 'i32', + }; + other = { + intertype: 'mathop', + op: 'shl', + type: 'i32', + param1: other, + param2: { intertype: 'value', ident: (32 - fraction).toString(), type: 'i32' } + }; + result = { + intertype: 'mathop', + op: 'lshr', + type: 'i32', + param1: result, + param2: { intertype: 'value', ident: fraction.toString(), type: 'i32' } + }; + result = { + intertype: 'mathop', + op: 'or', + type: 'i32', + param1: result, + param2: other + } + } + toAdd.push({ + intertype: 'assign', + ident: targetElements[j].ident, + value: result, + lineNum: item.lineNum + (j/100) + }); + } + Array.prototype.splice.apply(label.lines, [i, 0].concat(toAdd)); + i += toAdd.length; + continue; } default: throw 'Invalid mathop for legalization: ' + [value.op, item.lineNum]; } diff --git a/src/jsifier.js b/src/jsifier.js index d7d161d3..62cab3d5 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -719,6 +719,9 @@ function JSify(data, functionsOnly, givenFunctions) { } }); } + makeFuncLineActor('value', function(item) { + return item.ident; + }); makeFuncLineActor('noop', function(item) { return ';'; }); diff --git a/src/parseTools.js b/src/parseTools.js index 45cee958..635fa411 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1464,6 +1464,8 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) { return finalizeBlockAddress(param); } else if (param.intertype === 'type') { return param.ident; // we don't really want the type here + } else if (param.intertype == 'mathop') { + return processMathop(param); } else { throw 'invalid llvm parameter: ' + param.intertype; } |