diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 10:02:21 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 10:02:21 -0800 |
commit | e5e9311cfc5c2b7929e4b791b2aef3197b26e648 (patch) | |
tree | 8fbfbe645743bc45871dfb52331ca9c685d91754 /src | |
parent | 25293737bd69e8e284e6896da0ddf58977002c2a (diff) |
legalize shl
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 1c6e9a17..b0810a91 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -260,6 +260,7 @@ function analyzer(data, sidePass) { bits = getBits(value.type); var targetElements = getLegalVars(item.ident, bits); assert(value.param1.intertype == 'value', 'TODO: unfolding'); + // All mathops can be parametrized by how many shifts we do, and how big the source is var shifts = 0; var sourceBits; switch (value.op) { @@ -269,35 +270,45 @@ function analyzer(data, sidePass) { sourceBits = bits; break; } + case 'shl': { + assert(value.param2.intertype == 'value', 'TODO: unfolding'); + shifts = -parseInt(value.param2.ident); + sourceBits = bits; + break; + } default: throw 'Invalid mathop for legalization: ' + [value.op, item.lineNum]; } + // Do the legalization assert(isNumber(shifts), 'TODO: handle nonconstant shifts'); var sourceElements = getLegalVars(value.param1.ident, sourceBits); - var whole = Math.floor(shifts/32); - var fraction = shifts % 32; + var sign = shifts >= 0 ? 1 : -1; + var shiftOp = shifts >= 0 ? 'shl' : 'lshr'; + var shiftOpReverse = shifts >= 0 ? 'lshr' : 'shl'; + var whole = shifts >= 0 ? Math.floor(shifts/32) : Math.ceil(shifts/32); + var fraction = Math.abs(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', + ident: (j + whole >= 0 && j + whole < sourceElements.length) ? sourceElements[j + whole].ident : '0', type: 'i32', }; - if (fraction > 0) { + if (fraction != 0) { var other = { intertype: 'value', - ident: (j + 1 + whole) < sourceElements.length ? sourceElements[j + 1 + whole].ident : '0', + ident: (j + sign + whole >= 0 && j + sign + whole < sourceElements.length) ? sourceElements[j + sign + whole].ident : '0', type: 'i32', }; other = { intertype: 'mathop', - op: 'shl', + op: shiftOp, type: 'i32', param1: other, param2: { intertype: 'value', ident: (32 - fraction).toString(), type: 'i32' } }; result = { intertype: 'mathop', - op: 'lshr', + op: shiftOpReverse, type: 'i32', param1: result, param2: { intertype: 'value', ident: fraction.toString(), type: 'i32' } |