aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-27 18:47:38 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-27 18:47:38 -0800
commitdb2b596981a31368422f9379d4965c5a3436696a (patch)
tree5fa968a1bbad70f568916bbd66b8d727b4b8c817 /src
parent9d4067101193ec2cb1a9691c4d835fd8960fb069 (diff)
legalization for load
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js147
1 files changed, 99 insertions, 48 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index ece8fd53..b3d9183c 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -115,7 +115,7 @@ function analyzer(data, sidePass) {
//
// Currently we just legalize completely unrealistic types into bundles of i32s, and just
// the most common instructions that can be involved with such types: load, store, shifts,
- // bitcast, trunc and zext.
+ // trunc and zext.
//
// TODO: Expand this also into legalization of i64 into i32,i32, which can then
// replace our i64 mode 1 implementation. Legalizing i64s is harder though
@@ -155,54 +155,105 @@ function analyzer(data, sidePass) {
var i = 0, bits;
while (i < label.lines.length) {
var item = label.lines[i];
- if (item.intertype == 'assign') item = item.value;
- switch (item.intertype) {
- case 'store':
- if (isIllegalType(item.valueType)) {
- bits = getBits(item.valueType);
- assert(item.value.intertype == 'value', 'TODO: unfolding');
- var elements;
- if (isNumber(item.value.ident)) {
- elements = getLegalLiterals(item.value.ident, bits);
- } else {
- elements = getLegalVars(item.value.ident, bits);
- }
- label.lines.splice(i, 1);
- var j = 0;
- elements.forEach(function(element) {
- var tempVar = '$st$' + j;
- label.lines.splice(i+j*2, 0, {
- intertype: 'assign',
- ident: tempVar,
- value: {
- intertype: 'getelementptr',
- ident: item.pointer.ident,
- type: '[0 x i32]*',
- params: [
- { intertype: 'value', ident: item.pointer.ident, type: '[0 x i32]*' }, // technically a bitcase is needed in llvm, but not for us
- { intertype: 'value', ident: '0', type: 'i32' },
- { intertype: 'value', ident: j.toString(), type: 'i32' }
- ],
- },
- lineNum: item.lineNum + (j/100)
- });
- var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits
- label.lines.splice(i+j*2+1, 0, {
- intertype: 'store',
- valueType: actualSizeType,
- value: { intertype: 'value', ident: element.ident, type: actualSizeType },
- pointer: { intertype: 'value', ident: tempVar, type: actualSizeType + '*' },
- ident: tempVar,
- pointerType: actualSizeType + '*',
- align: item.align,
- lineNum: item.lineNum + ((j+0.5)/100)
- });
- j++;
- });
- Types.needAnalysis['[0 x i32]'] = 0;
- i += j*2;
+ if (item.intertype == 'store') {
+ if (isIllegalType(item.valueType)) {
+ dprint('legalizer', 'Legalizing store at line ' + item.lineNum);
+ bits = getBits(item.valueType);
+ assert(item.value.intertype == 'value', 'TODO: unfolding');
+ var elements;
+ if (isNumber(item.value.ident)) {
+ elements = getLegalLiterals(item.value.ident, bits);
+ } else {
+ elements = getLegalVars(item.value.ident, bits);
}
- break;
+ label.lines.splice(i, 1);
+ var j = 0;
+ elements.forEach(function(element) {
+ var tempVar = '$st$' + i + '$' + j;
+ label.lines.splice(i+j*2, 0, {
+ intertype: 'assign',
+ ident: tempVar,
+ value: {
+ intertype: 'getelementptr',
+ ident: item.pointer.ident,
+ type: '[0 x i32]*',
+ params: [
+ { intertype: 'value', ident: item.pointer.ident, type: '[0 x i32]*' }, // technically a bitcase is needed in llvm, but not for us
+ { intertype: 'value', ident: '0', type: 'i32' },
+ { intertype: 'value', ident: j.toString(), type: 'i32' }
+ ],
+ },
+ lineNum: item.lineNum + (j/100)
+ });
+ var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits
+ label.lines.splice(i+j*2+1, 0, {
+ intertype: 'store',
+ valueType: actualSizeType,
+ value: { intertype: 'value', ident: element.ident, type: actualSizeType },
+ pointer: { intertype: 'value', ident: tempVar, type: actualSizeType + '*' },
+ ident: tempVar,
+ pointerType: actualSizeType + '*',
+ align: item.align,
+ lineNum: item.lineNum + ((j+0.5)/100)
+ });
+ j++;
+ });
+ Types.needAnalysis['[0 x i32]'] = 0;
+ i += j*2;
+ continue;
+ }
+ } else if (item.intertype == 'assign') {
+ var value = item.value;
+ switch (value.intertype) {
+ case 'load':
+ if (isIllegalType(value.valueType)) {
+ dprint('legalizer', 'Legalizing load at line ' + item.lineNum);
+ bits = getBits(value.valueType);
+ assert(value.pointer.intertype == 'value', 'TODO: unfolding');
+ var elements;
+ elements = getLegalVars(item.ident, bits);
+ label.lines.splice(i, 1);
+ var j = 0;
+ elements.forEach(function(element) {
+ var tempVar = '$st$' + i + '$' + j;
+ label.lines.splice(i+j*2, 0, {
+ intertype: 'assign',
+ ident: tempVar,
+ value: {
+ intertype: 'getelementptr',
+ ident: value.pointer.ident,
+ type: '[0 x i32]*',
+ params: [
+ { intertype: 'value', ident: value.pointer.ident, type: '[0 x i32]*' }, // technically a bitcase is needed in llvm, but not for us
+ { intertype: 'value', ident: '0', type: 'i32' },
+ { intertype: 'value', ident: j.toString(), type: 'i32' }
+ ],
+ },
+ lineNum: item.lineNum + (j/100)
+ });
+ var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits
+ label.lines.splice(i+j*2+1, 0, {
+ intertype: 'assign',
+ ident: element.ident,
+ value: {
+ intertype: 'load',
+ pointerType: actualSizeType + '*',
+ valueType: actualSizeType,
+ type: actualSizeType, // XXX why is this missing from intertyper?
+ pointer: { intertype: 'value', ident: tempVar, type: actualSizeType + '*' },
+ ident: tempVar,
+ pointerType: actualSizeType + '*',
+ align: value.align,
+ },
+ lineNum: item.lineNum + ((j+0.5)/100)
+ });
+ j++;
+ });
+ Types.needAnalysis['[0 x i32]'] = 0;
+ i += j*2;
+ continue;
+ }
+ }
}
i++;
continue;