aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-27 17:48:41 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-27 17:48:41 -0800
commit2c652b36d9df45fd70d6ff603bdf82a1a52e06d4 (patch)
treed6b3e1eda8ba474badb4531245890b29c233aa11
parentf12d967b9c81ba81306639f72f493b9679307fdc (diff)
first working part of legalizing stores
-rw-r--r--src/analyzer.js91
-rw-r--r--src/intertyper.js2
-rw-r--r--tests/cases/legalizer_ta2.ll14
-rw-r--r--tests/cases/legalizer_ta2.txt2
4 files changed, 99 insertions, 10 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 770eb2c4..758d0b59 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -113,7 +113,10 @@ function analyzer(data, sidePass) {
// functionality, since it would duplicate existing code from the code generation
// component. Therefore, we implement legalization here in Emscripten.
//
- // Currently we just legalize completely unrealistic types into bundles of i32s.
+ // 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.
+ //
// 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
// as they can appear in function arguments and we would also need to implement
@@ -121,6 +124,92 @@ function analyzer(data, sidePass) {
// has a single LLVM instruction).
substrate.addActor('Legalizer', {
processItem: function(data) {
+ // Legalization
+ if (USE_TYPED_ARRAYS == 2) {
+ function isIllegalType(type) {
+ return getBits(type) > 64;
+ }
+ function getLegalVars(base, bits) {
+ var ret = new Array(Math.ceil(bits/32));
+ var i = 0;
+ while (bits > 0) {
+ ret[i] = { ident: base + '$' + i, bits: Math.min(32, bits) };
+ bits -= 32;
+ i++;
+ }
+ return ret;
+ }
+ function getLegalLiterals(text, bits) {
+ var parsed = parseArbitraryInt(text, bits);
+ var ret = new Array(Math.ceil(bits/32));
+ var i = 0;
+ while (bits > 0) {
+ ret[i] = { ident: parsed[i], bits: Math.min(32, bits) };
+ bits -= 32;
+ i++;
+ }
+ return ret;
+ }
+ data.functions.forEach(function(func) {
+ func.labels.forEach(function(label) {
+ 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)
+ });
+ label.lines.splice(i+j*2+1, 0, {
+ intertype: 'store',
+ valueType: 'i32',
+ value: { intertype: 'value', ident: element.ident, type: 'i32' },
+ pointer: { intertype: 'value', ident: tempVar, type: 'i32' },
+ ident: tempVar,
+ pointerType: 'i32*',
+ align: item.align,
+ lineNum: item.lineNum + ((j+0.5)/100)
+ });
+ j++;
+ });
+ Types.needAnalysis['[0 x i32]'] = 0;
+ i += j*2;
+ }
+ break;
+ }
+ i++;
+ continue;
+ }
+ });
+ });
+ }
+
// Add function lines to func.lines, after our modifications to the label lines
data.functions.forEach(function(func) {
func.labels.forEach(function(label) {
diff --git a/src/intertyper.js b/src/intertyper.js
index ae9794b8..cf1d28ed 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -864,7 +864,7 @@ function intertyper(data, sidePass, baseLineNums) {
var ret = {
intertype: 'store',
valueType: item.tokens[1].text,
- value: parseLLVMSegment(segments[0]), // TODO: Make everything use this method, with finalizeLLVMParameter too
+ value: parseLLVMSegment(segments[0]),
pointer: parseLLVMSegment(segments[1]),
lineNum: item.lineNum
};
diff --git a/tests/cases/legalizer_ta2.ll b/tests/cases/legalizer_ta2.ll
index a87d6c2b..2e27feac 100644
--- a/tests/cases/legalizer_ta2.ll
+++ b/tests/cases/legalizer_ta2.ll
@@ -20,7 +20,7 @@ entry:
store i104 31079605376604435891501163880, i104* %bundled1, align 1 ; unaligned
call i32 (i8*)* @puts(i8* %buffer)
- ; shifts
+; shifts
%shifted = lshr i104 %loaded, 16
store i104 %shifted, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
@@ -28,7 +28,7 @@ entry:
store i104 %shifted2, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
- ; store %loaded, make sure has not been modified
+; store %loaded, make sure has not been modified
store i104 %loaded, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
@@ -37,7 +37,7 @@ entry:
store i8 113, i8* %buffer ; remove initial 0
call i32 (i8*)* @puts(i8* %buffer)
- ; trunc
+; trunc
store i104 0, i104* %bundled, align 4 ; wipe it out
%small32 = trunc i104 %loaded to i32
%buffer32 = bitcast i8* %buffer to i32*
@@ -51,12 +51,12 @@ entry:
call i32 (i8*)* @puts(i8* %buffer)
store i104 0, i104* %bundled, align 4 ; wipe it out
- %small48 = trunc i104 %loaded to i48
- %buffer48 = bitcast i8* %buffer to i48*
- store i48 %small48, i48* %buffer48, align 4
+ %small64 = trunc i104 %loaded to i64
+ %buffer64 = bitcast i8* %buffer to i64*
+ store i64 %small64, i64* %buffer64, align 4
call i32 (i8*)* @puts(i8* %buffer)
- ; zext
+; zext
%big = zext i32 6382179 to i104
store i104 %big, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
diff --git a/tests/cases/legalizer_ta2.txt b/tests/cases/legalizer_ta2.txt
index 26944bc2..bfb1213c 100644
--- a/tests/cases/legalizer_ta2.txt
+++ b/tests/cases/legalizer_ta2.txt
@@ -7,5 +7,5 @@ hello, world
qhello, world
hell
he
-hello,
+hello, w
cba