diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-27 17:48:41 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-27 17:48:41 -0800 |
commit | 2c652b36d9df45fd70d6ff603bdf82a1a52e06d4 (patch) | |
tree | d6b3e1eda8ba474badb4531245890b29c233aa11 | |
parent | f12d967b9c81ba81306639f72f493b9679307fdc (diff) |
first working part of legalizing stores
-rw-r--r-- | src/analyzer.js | 91 | ||||
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | tests/cases/legalizer_ta2.ll | 14 | ||||
-rw-r--r-- | tests/cases/legalizer_ta2.txt | 2 |
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 |