diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-02-08 12:07:17 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-02-08 12:07:17 -0800 |
commit | ef59283debcb71ddadf5d9e9c2444d463f165557 (patch) | |
tree | 4d45bcf00b6a0620e3c3aa77adb03eff54dd4bd9 | |
parent | cd7d64a1945a7309804008feead7ebe4acb5a722 (diff) |
refactor legalizer code, and handle stores of <32 bits but not i8 or i16, properly
-rw-r--r-- | src/analyzer.js | 27 | ||||
-rw-r--r-- | src/parseTools.js | 10 | ||||
-rw-r--r-- | src/runtime.js | 10 | ||||
-rw-r--r-- | src/utility.js | 2 |
4 files changed, 29 insertions, 20 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index e1f2f6c1..41d46b95 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -169,6 +169,15 @@ function analyzer(data, sidePass) { item[slot] = { intertype: 'value', ident: tempIdent, type: item[slot].type }; return i+1; } + function removeAndAdd(lines, i, toAdd) { + var item = lines[i]; + var interp = getInterp(lines, i, toAdd.length); + for (var k = 0; k < toAdd.length; k++) { + toAdd[k].lineNum = item.lineNum + (k*interp); + } + Array.prototype.splice.apply(lines, [i, 1].concat(toAdd)); + return toAdd.length; + } // Assuming we will replace the item at line i, with num items, returns // the right factor to multiply line numbers by so that they fit in between // the removed line and the line after it @@ -184,16 +193,15 @@ function analyzer(data, sidePass) { if (item.intertype == 'store') { if (isIllegalType(item.valueType)) { dprint('legalizer', 'Legalizing store at line ' + item.lineNum); + var toAdd = []; bits = getBits(item.valueType); i = unfold(label.lines, i, item, 'value'); - var interp = getInterp(label.lines, i, Math.ceil(bits/32)); - label.lines.splice(i, 1); var elements; elements = getLegalVars(item.value.ident, bits); var j = 0; elements.forEach(function(element) { var tempVar = '$st$' + i + '$' + j; - label.lines.splice(i+j*2, 0, { + toAdd.push({ intertype: 'getelementptr', assignTo: tempVar, ident: item.pointer.ident, @@ -203,10 +211,9 @@ function analyzer(data, sidePass) { { intertype: 'value', ident: '0', type: 'i32' }, { intertype: 'value', ident: j.toString(), type: 'i32' } ], - lineNum: item.lineNum + (j*interp) }); var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits - label.lines.splice(i+j*2+1, 0, { + toAdd.push({ intertype: 'store', valueType: actualSizeType, value: { intertype: 'value', ident: element.ident, type: actualSizeType }, @@ -214,12 +221,11 @@ function analyzer(data, sidePass) { ident: tempVar, pointerType: actualSizeType + '*', align: item.align, - lineNum: item.lineNum + ((j+0.5)*interp) }); j++; }); Types.needAnalysis['[0 x i32]'] = 0; - i += j*2; + i += removeAndAdd(label.lines, i, toAdd); continue; } } else if (item.assignTo) { @@ -412,12 +418,7 @@ function analyzer(data, sidePass) { legalValue.assignTo = item.assignTo; toAdd.push(legalValue); } - var interp = getInterp(label.lines, i, toAdd.length); - for (var k = 0; k < toAdd.length; k++) { - toAdd[k].lineNum = item.lineNum + (k*interp); - } - Array.prototype.splice.apply(label.lines, [i, 1].concat(toAdd)); - i += toAdd.length; + i += removeAndAdd(label.lines, i, toAdd); continue; } } diff --git a/src/parseTools.js b/src/parseTools.js index f2f72fa3..29b8bdbf 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -966,8 +966,11 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')'; } + if (!align && isIntImplemented(type) && !isPowerOfTwo(getBits(type))) { + align = 1; // we need to split this up, as if alignment were 1, this is an unnatural type like i24 + } if (USE_TYPED_ARRAYS == 2 && align) { - // Alignment is important here. May need to split this up + // Alignment is important here, or we need to split this up for other reasons. var bytes = Runtime.getNativeTypeSize(type); if (bytes > align) { var ret = ''; @@ -977,14 +980,13 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, ret += 'tempBigInt=' + value + sep; ret += makeSetValue(ptr, pos, 'tempBigInt&0xffff', 'i16', noNeedFirst, ignore, 2) + sep; ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2); - } else if (bytes <= 4) { + } else if (bytes != 8) { ret += 'tempBigInt=' + value + sep; for (var i = 0; i < bytes; i++) { ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1); if (i < bytes-1) ret += sep + 'tempBigInt>>=8' + sep; } - } else { - assert(bytes == 8); + } else { // bytes == 8, specific optimization ret += 'tempPair=' + ensureI64_1(value) + sep; ret += makeSetValue(ptr, pos, 'tempPair[0]', 'i32', noNeedFirst, ignore, align) + sep; ret += makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempPair[1]', 'i32', noNeedFirst, ignore, align); diff --git a/src/runtime.js b/src/runtime.js index 190260e6..b5663045 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -185,8 +185,14 @@ var Runtime = { "%float": 4, "%double": 8 }['%'+type]; // add '%' since float and double confuse Closure compiler as keys, and also spidermonkey as a compiler will remove 's from '_i8' etc - if (!size && type[type.length-1] == '*') { - size = Runtime.QUANTUM_SIZE; // A pointer + if (!size) { + if (type[type.length-1] == '*') { + size = Runtime.QUANTUM_SIZE; // A pointer + } else if (type[0] == 'i') { + var bits = parseInt(type.substr(1)); + assert(bits % 8 == 0); + size = bits/8; + } } return size; }, diff --git a/src/utility.js b/src/utility.js index 5ddccfd4..31eff100 100644 --- a/src/utility.js +++ b/src/utility.js @@ -21,7 +21,7 @@ function dump(item) { ret.push(i + ': [?]'); } } - return lineify(ret.join(', ')); + return ret.join(',\n'); } } |