aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-08 12:07:17 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-08 12:07:17 -0800
commitef59283debcb71ddadf5d9e9c2444d463f165557 (patch)
tree4d45bcf00b6a0620e3c3aa77adb03eff54dd4bd9
parentcd7d64a1945a7309804008feead7ebe4acb5a722 (diff)
refactor legalizer code, and handle stores of <32 bits but not i8 or i16, properly
-rw-r--r--src/analyzer.js27
-rw-r--r--src/parseTools.js10
-rw-r--r--src/runtime.js10
-rw-r--r--src/utility.js2
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');
}
}