aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-29 16:13:09 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-29 16:13:09 -0800
commit8efbb37510e08619735217ea6690461d6fd9969e (patch)
tree7ef653830b7bcbd6ad7a7de1425ca99fdb9b0a56
parent63abeaa88d35575419f87c594df1830b957e0b4e (diff)
legalization for and, or, xor
-rw-r--r--src/analyzer.js29
-rw-r--r--tests/cases/legalizer_ta2.ll14
-rw-r--r--tests/cases/legalizer_ta2.txt3
3 files changed, 40 insertions, 6 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 7eca1d5a..2c42fa43 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -130,6 +130,9 @@ function analyzer(data, sidePass) {
return getBits(type) > 64;
}
function getLegalVars(base, bits) {
+ if (isNumber(base)) {
+ return getLegalLiterals(base, bits);
+ }
var ret = new Array(Math.ceil(bits/32));
var i = 0;
while (bits > 0) {
@@ -144,7 +147,7 @@ function analyzer(data, sidePass) {
var ret = new Array(Math.ceil(bits/32));
var i = 0;
while (bits > 0) {
- ret[i] = { ident: parsed[i], bits: Math.min(32, bits) };
+ ret[i] = { ident: parsed[i].toString(), bits: Math.min(32, bits) };
bits -= 32;
i++;
}
@@ -161,11 +164,7 @@ function analyzer(data, sidePass) {
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);
- }
+ elements = getLegalVars(item.value.ident, bits);
label.lines.splice(i, 1);
var j = 0;
elements.forEach(function(element) {
@@ -282,6 +281,7 @@ function analyzer(data, sidePass) {
// All mathops can be parametrized by how many shifts we do, and how big the source is
var shifts = 0;
var targetBits;
+ var processor = null;
switch (value.op) {
case 'lshr': {
assert(value.param2.intertype == 'value', 'TODO: unfolding');
@@ -300,6 +300,20 @@ function analyzer(data, sidePass) {
targetBits = getBits(value.param2.ident);
break;
}
+ case 'or': case 'and': case 'xor': {
+ targetBits = sourceBits;
+ var otherElements = getLegalVars(value.param2.ident, sourceBits);
+ processor = function(result, j) {
+ return {
+ intertype: 'mathop',
+ op: value.op,
+ type: 'i' + otherElements[j].bits,
+ param1: result,
+ param2: { intertype: 'value', ident: otherElements[j].ident, type: 'i' + otherElements[j].bits }
+ };
+ };
+ break;
+ }
default: throw 'Invalid mathop for legalization: ' + [value.op, item.lineNum, dump(item)];
}
// Do the legalization
@@ -354,6 +368,9 @@ function analyzer(data, sidePass) {
param2: { intertype: 'value', ident: (Math.pow(2, targetElements[j].bits)-1).toString(), type: 'i32' }
}
}
+ if (processor) {
+ result = processor(result, j);
+ }
toAdd.push({
intertype: 'assign',
ident: targetElements[j].ident,
diff --git a/tests/cases/legalizer_ta2.ll b/tests/cases/legalizer_ta2.ll
index 45cdf432..cde3ec10 100644
--- a/tests/cases/legalizer_ta2.ll
+++ b/tests/cases/legalizer_ta2.ll
@@ -78,6 +78,20 @@ entry:
store i104 %bigb, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
+; or, and, xor
+ %ored = or i104 %loaded, 119683656141956040435433472 ; constant
+ store i104 %ored, i104* %bundled, align 4
+ call i32 (i8*)* @puts(i8* %buffer)
+
+ %ander = trunc i128 79037149320135189491510935551 to i104
+ %anded = and i104 %loaded, %ander ; variable
+ store i104 %anded, i104* %bundled, align 4
+ call i32 (i8*)* @puts(i8* %buffer)
+
+ %xored = xor i104 %loaded, 78580178274950896355901440
+ store i104 %xored, i104* %bundled, align 4
+ call i32 (i8*)* @puts(i8* %buffer)
+
ret i32 1
}
diff --git a/tests/cases/legalizer_ta2.txt b/tests/cases/legalizer_ta2.txt
index ae9b4a47..66fb8c59 100644
--- a/tests/cases/legalizer_ta2.txt
+++ b/tests/cases/legalizer_ta2.txt
@@ -11,3 +11,6 @@ he
hello, w
cba
gfedgfed
+hellon worod
+hello, war`d
+hello, wor-d