aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-25 15:47:42 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-25 15:47:42 -0800
commitbfb9a540657debce1ba588e003b70c3259150f39 (patch)
treec56d33205d30356e42c8d761ec7e5dcb9c58410f
parent55ac19dc9b6cc6e806f3bae5843cca5ee17262b4 (diff)
refactor out paramX in mathops
-rw-r--r--src/analyzer.js68
-rw-r--r--src/intertyper.js23
-rw-r--r--src/jsifier.js2
-rw-r--r--src/parseTools.js230
4 files changed, 161 insertions, 162 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 593b4650..4dd95e7a 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -388,13 +388,13 @@ function analyzer(data, sidePass) {
case 'inttoptr': case 'ptrtoint': {
value = {
op: item.intertype,
- param1: item.params[0]
+ params: [item.params[0]] // XXX
};
// fall through
}
case 'mathop': {
var toAdd = [];
- var sourceBits = getBits(value.param1.type);
+ var sourceBits = getBits(value.params[0].type);
// All mathops can be parametrized by how many shifts we do, and how big the source is
var shifts = 0;
var targetBits = sourceBits;
@@ -406,11 +406,11 @@ function analyzer(data, sidePass) {
// fall through
}
case 'lshr': {
- shifts = parseInt(value.param2.ident);
+ shifts = parseInt(value.params[1].ident);
break;
}
case 'shl': {
- shifts = -parseInt(value.param2.ident);
+ shifts = -parseInt(value.params[1].ident);
break;
}
case 'sext': {
@@ -418,7 +418,7 @@ function analyzer(data, sidePass) {
// fall through
}
case 'trunc': case 'zext': case 'ptrtoint': {
- targetBits = getBits(value.param2.ident);
+ targetBits = getBits(value.params[1].ident);
break;
}
case 'inttoptr': {
@@ -429,31 +429,35 @@ function analyzer(data, sidePass) {
break;
}
case 'select': {
- sourceBits = targetBits = getBits(value.param2.type);
- var otherElementsA = getLegalVars(value.param2.ident, sourceBits);
- var otherElementsB = getLegalVars(value.param3.ident, sourceBits);
+ sourceBits = targetBits = getBits(value.params[1].type);
+ var otherElementsA = getLegalVars(value.params[1].ident, sourceBits);
+ var otherElementsB = getLegalVars(value.params[2].ident, sourceBits);
processor = function(result, j) {
return {
intertype: 'mathop',
op: 'select',
type: 'i' + otherElementsA[j].bits,
- param1: value.param1,
- param2: { intertype: 'value', ident: otherElementsA[j].ident, type: 'i' + otherElementsA[j].bits },
- param3: { intertype: 'value', ident: otherElementsB[j].ident, type: 'i' + otherElementsB[j].bits }
+ params: [
+ value.params[0],
+ { intertype: 'value', ident: otherElementsA[j].ident, type: 'i' + otherElementsA[j].bits },
+ { intertype: 'value', ident: otherElementsB[j].ident, type: 'i' + otherElementsB[j].bits }
+ ]
};
};
break;
}
case 'or': case 'and': case 'xor': {
- var otherElements = getLegalVars(value.param2.ident, sourceBits);
+ var otherElements = getLegalVars(value.params[1].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 }
- };
+ params: [
+ result,
+ { intertype: 'value', ident: otherElements[j].ident, type: 'i' + otherElements[j].bits }
+ ]
+ };
};
break;
}
@@ -469,16 +473,16 @@ function analyzer(data, sidePass) {
var sourceElements;
if (sourceBits <= 32) {
// The input is a legal type
- sourceElements = [{ ident: value.param1.ident, bits: sourceBits }];
+ sourceElements = [{ ident: value.params[0].ident, bits: sourceBits }];
} else {
- sourceElements = getLegalVars(value.param1.ident, sourceBits);
+ sourceElements = getLegalVars(value.params[0].ident, sourceBits);
}
if (!isNumber(shifts)) {
// We can't statically legalize this, do the operation at runtime TODO: optimize
assert(sourceBits == 64, 'TODO: handle nonconstant shifts on != 64 bits');
value.intertype = 'value';
value.ident = 'Runtime.bitshift64(' + sourceElements[0].ident + ', ' +
- sourceElements[1].ident + ',"' + value.op + '",' + value.param2.ident + '$0);' +
+ sourceElements[1].ident + ',"' + value.op + '",' + value.params[1].ident + '$0);' +
'var ' + value.assignTo + '$0 = ' + value.assignTo + '[0], ' + value.assignTo + '$1 = ' + value.assignTo + '[1];';
i++;
continue;
@@ -497,37 +501,43 @@ function analyzer(data, sidePass) {
var result = {
intertype: 'value',
ident: (j + whole >= 0 && j + whole < sourceElements.length) ? sourceElements[j + whole].ident : (signed ? signedFill : '0'),
- param1: (signed && j + whole > sourceElements.length) ? signedKeepAlive : null,
+ params: [(signed && j + whole > sourceElements.length) ? signedKeepAlive : null],
type: 'i32',
};
if (fraction != 0) {
var other = {
intertype: 'value',
ident: (j + sign + whole >= 0 && j + sign + whole < sourceElements.length) ? sourceElements[j + sign + whole].ident : (signed ? signedFill : '0'),
- param1: (signed && j + sign + whole > sourceElements.length) ? signedKeepAlive : null,
+ params: [(signed && j + sign + whole > sourceElements.length) ? signedKeepAlive : null],
type: 'i32',
};
other = {
intertype: 'mathop',
op: shiftOp,
type: 'i32',
- param1: other,
- param2: { intertype: 'value', ident: (32 - fraction).toString(), type: 'i32' }
+ params: [
+ other,
+ { intertype: 'value', ident: (32 - fraction).toString(), type: 'i32' }
+ ]
};
result = {
intertype: 'mathop',
// shifting in 1s from the top is a special case
op: (signed && shifts >= 0 && j + sign + whole >= sourceElements.length) ? 'ashr' : shiftOpReverse,
type: 'i32',
- param1: result,
- param2: { intertype: 'value', ident: fraction.toString(), type: 'i32' }
+ params: [
+ result,
+ { intertype: 'value', ident: fraction.toString(), type: 'i32' }
+ ]
};
result = {
intertype: 'mathop',
op: 'or',
type: 'i32',
- param1: result,
- param2: other
+ params: [
+ result,
+ other
+ ]
}
}
if (targetElements[j].bits < 32 && shifts < 0) {
@@ -536,8 +546,10 @@ function analyzer(data, sidePass) {
intertype: 'mathop',
op: 'and',
type: 'i32',
- param1: result,
- param2: { intertype: 'value', ident: (Math.pow(2, targetElements[j].bits)-1).toString(), type: 'i32' }
+ params: [
+ result,
+ { intertype: 'value', ident: (Math.pow(2, targetElements[j].bits)-1).toString(), type: 'i32' }
+ ]
}
}
if (processor) {
diff --git a/src/intertyper.js b/src/intertyper.js
index cfb12331..6d367b93 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -800,38 +800,39 @@ function intertyper(data, sidePass, baseLineNums) {
}
if (item.tokens[1].text == 'exact') item.tokens.splice(1, 1); // TODO: Implement trap values
var segments = splitTokenList(item.tokens.slice(1));
+ item.params = [];
for (var i = 1; i <= 4; i++) {
if (segments[i-1]) {
if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) {
segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike
}
- item['param'+i] = parseLLVMSegment(segments[i-1]);
+ item.params[i-1] = parseLLVMSegment(segments[i-1]);
}
}
if (item.op === 'select') {
- assert(item.param2.type === item.param3.type);
- item.type = item.param2.type;
+ assert(item.params[1].type === item.params[2].type);
+ item.type = item.params[1].type;
} else if (item.op === 'inttoptr' || item.op === 'ptrtoint') {
- item.type = item.param2.type;
+ item.type = item.params[1].type;
} else {
- item.type = item.param1.type;
+ item.type = item.params[0].type;
}
if (item.op != 'ptrtoint') {
- for (var i = 1; i <= 4; i++) {
- if (item['param'+i]) item['param'+i].type = item.type; // All params have the same type, normally
+ for (var i = 0; i < 4; i++) {
+ if (item.params[i]) item.params[i].type = item.type; // All params have the same type, normally
}
}
if (item.op in LLVM.EXTENDS) {
- item.type = item.param2.ident;
- item.param1.type = item.param2.type;
+ item.type = item.params[1].ident;
+ item.params[0].type = item.params[1].type;
// TODO: also remove 2nd param?
}
if (I64_MODE == 1) {
// Some specific corrections, since 'i64' is special
if (item.op in LLVM.SHIFTS) {
- item.param2.type = 'i32';
+ item.params[1].type = 'i32';
} else if (item.op == 'select') {
- item.param1.type = 'i1';
+ item.params[0].type = 'i1';
}
}
Types.needAnalysis[item.type] = 0;
diff --git a/src/jsifier.js b/src/jsifier.js
index e1d2921f..70a99020 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1049,7 +1049,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var temp = {
op: 'bitcast', variant: null, type: item.type,
assignTo: item.assignTo,
- param1: item.params[0]
+ params: [item.params[0]] // XXX
};
var ret = processMathop(temp);
if (!temp.assignTo) item.assignTo = null; // If the assign was stolen, propagate that
diff --git a/src/parseTools.js b/src/parseTools.js
index 56373535..ee7e5bdd 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1337,13 +1337,9 @@ function finalizeLLVMFunctionCall(item, noIndexizeFunctions) {
var temp = {
op: item.intertype,
variant: item.variant,
- type: item.type
+ type: item.type,
+ params: item.params.slice(0) // XXX slice?
};
- for (var i = 1; i <= 4; i++) {
- if (item.params[i-1]) {
- temp['param' + i] = item.params[i-1];
- }
- }
return processMathop(temp);
}
@@ -1557,48 +1553,45 @@ function processMathop(item) {
var variant = item.variant;
var type = item.type;
var paramTypes = ['', '', '', ''];
- for (var i = 1; i <= 3; i++) {
- if (item['param'+i]) {
- paramTypes[i-1] = item['param'+i].type || type;
- item['ident'+i] = finalizeLLVMParameter(item['param'+i]);
- if (!isNumber(item['ident'+i]) && !isNiceIdent(item['ident'+i])) {
- item['ident'+i] = '(' + item['ident'+i] + ')'; // we may have nested expressions. So enforce the order of operations we want
+ var idents = [];
+ for (var i = 0; i < 3; i++) {
+ if (item.params[i]) {
+ paramTypes[i] = item.params[i].type || type;
+ idents[i] = finalizeLLVMParameter(item.params[i]);
+ if (!isNumber(idents[i]) && !isNiceIdent(idents[i])) {
+ idents[i] = '(' + idents[i] + ')'; // we may have nested expressions. So enforce the order of operations we want
}
} else {
- item['ident'+i] = null; // just so it exists for purposes of reading ident2 etc. later on, and no exception is thrown
+ idents[i] = null; // just so it exists for purposes of reading idents[1] etc. later on, and no exception is thrown
}
}
- var ident1 = item.ident1;
- var ident2 = item.ident2;
- var ident3 = item.ident3;
- var originalIdent1 = ident1;
- var originalIdent2 = ident2;
+ var originalIdents = idents.slice(0);
if (isUnsignedOp(op, variant)) {
- ident1 = makeSignOp(ident1, paramTypes[0], 'un');
- ident2 = makeSignOp(ident2, paramTypes[1], 'un');
+ idents[0] = makeSignOp(idents[0], paramTypes[0], 'un');
+ idents[1] = makeSignOp(idents[1], paramTypes[0], 'un');
} else if (isSignedOp(op, variant)) {
- ident1 = makeSignOp(ident1, paramTypes[0], 're');
- ident2 = makeSignOp(ident2, paramTypes[1], 're');
+ idents[0] = makeSignOp(idents[0], paramTypes[0], 're');
+ idents[1] = makeSignOp(idents[1], paramTypes[0], 're');
}
var bits = null;
if (item.type[0] === 'i') {
bits = parseInt(item.type.substr(1));
}
- var bitsLeft = parseInt(((item.param2 && item.param2.ident) ? item.param2.ident : item.type).substr(1)); // remove i to leave the number of bits left after this operation
+ var bitsLeft = parseInt(((item.params[1] && item.params[1].ident) ? item.params[1].ident : item.type).substr(1)); // remove i to leave the number of bits left after this operation
function integerizeBignum(value) {
return makeInlineCalculation('VALUE-VALUE%1', value, 'tempBigIntI');
}
- if ((type == 'i64' || paramTypes[0] == 'i64' || paramTypes[1] == 'i64' || ident2 == '(i64)') && I64_MODE == 1) {
+ if ((type == 'i64' || paramTypes[0] == 'i64' || paramTypes[1] == 'i64' || idents[1] == '(i64)') && I64_MODE == 1) {
var warnI64_1 = function() {
warnOnce('Arithmetic on 64-bit integers in mode 1 is rounded and flaky, like mode 0!');
};
// In ops that can be either legalized or not, we need to differentiate how we access low and high parts
- var low1 = ident1 + (legalizedI64s ? '$0' : '[0]');
- var high1 = ident1 + (legalizedI64s ? '$1' : '[1]');
- var low2 = ident2 + (legalizedI64s ? '$0' : '[0]');
- var high2 = ident2 + (legalizedI64s ? '$1' : '[1]');
+ var low1 = idents[0] + (legalizedI64s ? '$0' : '[0]');
+ var high1 = idents[0] + (legalizedI64s ? '$1' : '[1]');
+ var low2 = idents[1] + (legalizedI64s ? '$0' : '[0]');
+ var high2 = idents[1] + (legalizedI64s ? '$1' : '[1]');
function finish(result) {
// If this is in legalization mode, steal the assign and assign into two vars
if (legalizedI64s) {
@@ -1613,56 +1606,56 @@ function processMathop(item) {
switch (op) {
// basic integer ops
case 'or': {
- return '[' + ident1 + '[0] | ' + ident2 + '[0], ' + ident1 + '[1] | ' + ident2 + '[1]]';
+ return '[' + idents[0] + '[0] | ' + idents[1] + '[0], ' + idents[0] + '[1] | ' + idents[1] + '[1]]';
}
case 'and': {
- return '[' + ident1 + '[0] & ' + ident2 + '[0], ' + ident1 + '[1] & ' + ident2 + '[1]]';
+ return '[' + idents[0] + '[0] & ' + idents[1] + '[0], ' + idents[0] + '[1] & ' + idents[1] + '[1]]';
}
case 'xor': {
- return '[' + ident1 + '[0] ^ ' + ident2 + '[0], ' + ident1 + '[1] ^ ' + ident2 + '[1]]';
+ return '[' + idents[0] + '[0] ^ ' + idents[1] + '[0], ' + idents[0] + '[1] ^ ' + idents[1] + '[1]]';
}
case 'shl':
case 'ashr':
case 'lshr': {
- if (!isNumber(ident2)) {
- return 'Runtime.bitshift64(' + ident1 + '[0], ' + ident1 + '[1],"' + op + '",' + stripCorrections(ident2) + '[0]|0)';
+ if (!isNumber(idents[1])) {
+ return 'Runtime.bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0)';
}
- bits = parseInt(ident2);
+ bits = parseInt(idents[1]);
var ander = Math.pow(2, bits)-1;
if (bits < 32) {
switch (op) {
case 'shl':
- return '[' + ident1 + '[0] << ' + ident2 + ', ' +
- '('+ident1 + '[1] << ' + ident2 + ') | ((' + ident1 + '[0]&(' + ander + '<<' + (32 - bits) + ')) >>> (32-' + ident2 + '))]';
+ return '[' + idents[0] + '[0] << ' + idents[1] + ', ' +
+ '('+idents[0] + '[1] << ' + idents[1] + ') | ((' + idents[0] + '[0]&(' + ander + '<<' + (32 - bits) + ')) >>> (32-' + idents[1] + '))]';
case 'ashr':
- return '[((('+ident1 + '[0] >>> ' + ident2 + ') | ((' + ident1 + '[1]&' + ander + ')<<' + (32 - bits) + ')) >> 0) >>> 0,' +
- '(' + ident1 + '[1] >> ' + ident2 + ') >>> 0]';
+ return '[((('+idents[0] + '[0] >>> ' + idents[1] + ') | ((' + idents[0] + '[1]&' + ander + ')<<' + (32 - bits) + ')) >> 0) >>> 0,' +
+ '(' + idents[0] + '[1] >> ' + idents[1] + ') >>> 0]';
case 'lshr':
- return '[(('+ident1 + '[0] >>> ' + ident2 + ') | ((' + ident1 + '[1]&' + ander + ')<<' + (32 - bits) + ')) >>> 0,' +
- ident1 + '[1] >>> ' + ident2 + ']';
+ return '[(('+idents[0] + '[0] >>> ' + idents[1] + ') | ((' + idents[0] + '[1]&' + ander + ')<<' + (32 - bits) + ')) >>> 0,' +
+ idents[0] + '[1] >>> ' + idents[1] + ']';
}
} else if (bits == 32) {
switch (op) {
case 'shl':
- return '[0, ' + ident1 + '[0]]';
+ return '[0, ' + idents[0] + '[0]]';
case 'ashr':
- return '[' + ident1 + '[1], (' + ident1 + '[1]|0) < 0 ? ' + ander + ' : 0]';
+ return '[' + idents[0] + '[1], (' + idents[0] + '[1]|0) < 0 ? ' + ander + ' : 0]';
case 'lshr':
- return '[' + ident1 + '[1], 0]';
+ return '[' + idents[0] + '[1], 0]';
}
} else { // bits > 32
switch (op) {
case 'shl':
- return '[0, ' + ident1 + '[0] << ' + (bits - 32) + ']';
+ return '[0, ' + idents[0] + '[0] << ' + (bits - 32) + ']';
case 'ashr':
- return '[(' + ident1 + '[1] >> ' + (bits - 32) + ') >>> 0, (' + ident1 + '[1]|0) < 0 ? ' + ander + ' : 0]';
+ return '[(' + idents[0] + '[1] >> ' + (bits - 32) + ') >>> 0, (' + idents[0] + '[1]|0) < 0 ? ' + ander + ' : 0]';
case 'lshr':
- return '[' + ident1 + '[1] >>> ' + (bits - 32) + ', 0]';
+ return '[' + idents[0] + '[1] >>> ' + (bits - 32) + ', 0]';
}
}
}
case 'uitofp': case 'sitofp': return low1 + ' + ' + high1 + '*4294967296';
- case 'fptoui': case 'fptosi': return finish(splitI64(ident1));
+ case 'fptoui': case 'fptosi': return finish(splitI64(idents[0]));
case 'icmp': {
switch (variant) {
case 'uge': return high1 + ' >= ' + high2 + ' && (' + high1 + ' > ' + high2 + ' || ' +
@@ -1686,39 +1679,39 @@ function processMathop(item) {
default: throw 'Unknown icmp variant: ' + variant;
}
}
- case 'zext': return makeI64(ident1, 0);
- case 'sext': return makeInlineCalculation(makeI64('VALUE', 'VALUE<0 ? 4294967295 : 0'), ident1, 'tempBigIntD');
+ case 'zext': return makeI64(idents[0], 0);
+ case 'sext': return makeInlineCalculation(makeI64('VALUE', 'VALUE<0 ? 4294967295 : 0'), idents[0], 'tempBigIntD');
case 'trunc': {
- return '((' + ident1 + '[0]) & ' + (Math.pow(2, bitsLeft)-1) + ')';
+ return '((' + idents[0] + '[0]) & ' + (Math.pow(2, bitsLeft)-1) + ')';
}
- case 'select': return ident1 + ' ? ' + makeCopyI64(ident2) + ' : ' + makeCopyI64(ident3);
- case 'ptrtoint': return makeI64(ident1, 0);
- case 'inttoptr': return '(' + ident1 + '[0])'; // just directly truncate the i64 to a 'pointer', which is an i32
+ case 'select': return idents[0] + ' ? ' + makeCopyI64(idents[1]) + ' : ' + makeCopyI64(idents[2]);
+ case 'ptrtoint': return makeI64(idents[0], 0);
+ case 'inttoptr': return '(' + idents[0] + '[0])'; // just directly truncate the i64 to a 'pointer', which is an i32
// Dangerous, rounded operations. TODO: Fully emulate
- case 'add': warnI64_1(); return finish(splitI64(mergeI64(ident1) + '+' + mergeI64(ident2)));
- case 'sub': warnI64_1(); return finish(splitI64(mergeI64(ident1) + '-' + mergeI64(ident2)));
- case 'sdiv': case 'udiv': warnI64_1(); return finish(splitI64(makeRounding(mergeI64(ident1) + '/' + mergeI64(ident2), bits, op[0] === 's')));
- case 'mul': warnI64_1(); return finish(splitI64(mergeI64(ident1) + '*' + mergeI64(ident2)));
- case 'urem': case 'srem': warnI64_1(); return finish(splitI64(mergeI64(ident1) + '%' + mergeI64(ident2)));
+ case 'add': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '+' + mergeI64(idents[1])));
+ case 'sub': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '-' + mergeI64(idents[1])));
+ case 'sdiv': case 'udiv': warnI64_1(); return finish(splitI64(makeRounding(mergeI64(idents[0]) + '/' + mergeI64(idents[1]), bits, op[0] === 's')));
+ case 'mul': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '*' + mergeI64(idents[1])));
+ case 'urem': case 'srem': warnI64_1(); return finish(splitI64(mergeI64(idents[0]) + '%' + mergeI64(idents[1])));
case 'bitcast': {
// Pointers are not 64-bit, so there is really only one possible type of bitcast here, int to float or vice versa
assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2');
- var inType = item.param1.type;
+ var inType = item.params[0].type;
var outType = item.type;
if (inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) {
if (legalizedI64s) {
- return '(tempDoubleI32[0]=' + ident1 + '$0, tempDoubleI32[1]=' + ident1 + '$1, tempDoubleF64[0])';
+ return '(tempDoubleI32[0]=' + idents[0] + '$0, tempDoubleI32[1]=' + idents[0] + '$1, tempDoubleF64[0])';
} else {
- return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', ident1, 'tempI64');
+ return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', idents[0], 'tempI64');
}
} else if (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES) {
if (legalizedI64s) {
- return 'tempDoubleF64[0]=' + ident1 + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']);
+ return 'tempDoubleF64[0]=' + idents[0] + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']);
} else {
- return '(tempDoubleF64[0]=' + ident1 + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ return '(tempDoubleF64[0]=' + idents[0] + ',[tempDoubleI32[0],tempDoubleI32[1]])';
}
} else {
- throw 'Invalid I64_MODE1 bitcast: ' + dump(item) + ' : ' + item.param1.type;
+ throw 'Invalid I64_MODE1 bitcast: ' + dump(item) + ' : ' + item.params[0].type;
}
}
default: throw 'Unsupported i64 mode 1 op: ' + item.op + ' : ' + dump(item);
@@ -1727,73 +1720,73 @@ function processMathop(item) {
switch (op) {
// basic integer ops
- case 'add': return handleOverflow(getFastValue(ident1, '+', ident2, item.type), bits);
- case 'sub': return handleOverflow(getFastValue(ident1, '-', ident2, item.type), bits);
- case 'sdiv': case 'udiv': return makeRounding(getFastValue(ident1, '/', ident2, item.type), bits, op[0] === 's');
- case 'mul': return handleOverflow(getFastValue(ident1, '*', ident2, item.type), bits);
- case 'urem': case 'srem': return getFastValue(ident1, '%', ident2, item.type);
+ case 'add': return handleOverflow(getFastValue(idents[0], '+', idents[1], item.type), bits);
+ case 'sub': return handleOverflow(getFastValue(idents[0], '-', idents[1], item.type), bits);
+ case 'sdiv': case 'udiv': return makeRounding(getFastValue(idents[0], '/', idents[1], item.type), bits, op[0] === 's');
+ case 'mul': return handleOverflow(getFastValue(idents[0], '*', idents[1], item.type), bits);
+ case 'urem': case 'srem': return getFastValue(idents[0], '%', idents[1], item.type);
case 'or': {
if (bits > 32) {
assert(bits === 64, 'Too many bits for or: ' + bits);
dprint('Warning: 64 bit OR - precision limit may be hit on llvm line ' + item.lineNum);
- return 'Runtime.or64(' + ident1 + ', ' + ident2 + ')';
+ return 'Runtime.or64(' + idents[0] + ', ' + idents[1] + ')';
}
- return ident1 + ' | ' + ident2;
+ return idents[0] + ' | ' + idents[1];
}
case 'and': {
if (bits > 32) {
assert(bits === 64, 'Too many bits for and: ' + bits);
dprint('Warning: 64 bit AND - precision limit may be hit on llvm line ' + item.lineNum);
- return 'Runtime.and64(' + ident1 + ', ' + ident2 + ')';
+ return 'Runtime.and64(' + idents[0] + ', ' + idents[1] + ')';
}
- return ident1 + ' & ' + ident2;
+ return idents[0] + ' & ' + idents[1];
}
case 'xor': {
if (bits > 32) {
assert(bits === 64, 'Too many bits for xor: ' + bits);
dprint('Warning: 64 bit XOR - precision limit may be hit on llvm line ' + item.lineNum);
- return 'Runtime.xor64(' + ident1 + ', ' + ident2 + ')';
+ return 'Runtime.xor64(' + idents[0] + ', ' + idents[1] + ')';
}
- return ident1 + ' ^ ' + ident2;
+ return idents[0] + ' ^ ' + idents[1];
}
case 'shl': {
- if (bits > 32) return ident1 + '*' + getFastValue(2, 'pow', ident2);
- return ident1 + ' << ' + ident2;
+ if (bits > 32) return idents[0] + '*' + getFastValue(2, 'pow', idents[1]);
+ return idents[0] + ' << ' + idents[1];
}
case 'ashr': {
- if (bits > 32) return integerizeBignum(ident1 + '/' + getFastValue(2, 'pow', ident2));
- if (bits === 32) return originalIdent1 + ' >> ' + ident2; // No need to reSign in this case
- return ident1 + ' >> ' + ident2;
+ if (bits > 32) return integerizeBignum(idents[0] + '/' + getFastValue(2, 'pow', idents[1]));
+ if (bits === 32) return originalIdents[0] + ' >> ' + idents[1]; // No need to reSign in this case
+ return idents[0] + ' >> ' + idents[1];
}
case 'lshr': {
- if (bits > 32) return integerizeBignum(ident1 + '/' + getFastValue(2, 'pow', ident2));
- if (bits === 32) return originalIdent1 + ' >>> ' + ident2; // No need to unSign in this case
- return ident1 + ' >>> ' + ident2;
+ if (bits > 32) return integerizeBignum(idents[0] + '/' + getFastValue(2, 'pow', idents[1]));
+ if (bits === 32) return originalIdents[0] + ' >>> ' + idents[1]; // No need to unSign in this case
+ return idents[0] + ' >>> ' + idents[1];
}
// basic float ops
- case 'fadd': return getFastValue(ident1, '+', ident2, item.type);
- case 'fsub': return getFastValue(ident1, '-', ident2, item.type);
- case 'fdiv': return getFastValue(ident1, '/', ident2, item.type);
- case 'fmul': return getFastValue(ident1, '*', ident2, item.type);
- case 'uitofp': case 'sitofp': return ident1;
- case 'fptoui': case 'fptosi': return makeRounding(ident1, bitsLeft, op === 'fptosi', true);
+ case 'fadd': return getFastValue(idents[0], '+', idents[1], item.type);
+ case 'fsub': return getFastValue(idents[0], '-', idents[1], item.type);
+ case 'fdiv': return getFastValue(idents[0], '/', idents[1], item.type);
+ case 'fmul': return getFastValue(idents[0], '*', idents[1], item.type);
+ case 'uitofp': case 'sitofp': return idents[0];
+ case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true);
// TODO: We sometimes generate false instead of 0, etc., in the *cmps. It seemed slightly faster before, but worth rechecking
// Note that with typed arrays, these become 0 when written. So that is a potential difference with non-typed array runs.
case 'icmp': {
switch (variant) {
- case 'uge': case 'sge': return ident1 + ' >= ' + ident2;
- case 'ule': case 'sle': return ident1 + ' <= ' + ident2;
- case 'ugt': case 'sgt': return ident1 + ' > ' + ident2;
- case 'ult': case 'slt': return ident1 + ' < ' + ident2;
+ case 'uge': case 'sge': return idents[0] + ' >= ' + idents[1];
+ case 'ule': case 'sle': return idents[0] + ' <= ' + idents[1];
+ case 'ugt': case 'sgt': return idents[0] + ' > ' + idents[1];
+ case 'ult': case 'slt': return idents[0] + ' < ' + idents[1];
// We use loose comparisons, which allows false == 0 to be true, etc. Ditto in fcmp
case 'ne': case 'eq': {
// We must sign them, so we do not compare -1 to 255 (could have unsigned them both too)
// since LLVM tells us if <=, >= etc. comparisons are signed, but not == and !=.
assert(paramTypes[0] == paramTypes[1]);
- ident1 = makeSignOp(ident1, paramTypes[0], 're');
- ident2 = makeSignOp(ident2, paramTypes[1], 're');
- return ident1 + (variant === 'eq' ? '==' : '!=') + ident2;
+ idents[0] = makeSignOp(idents[0], paramTypes[0], 're');
+ idents[1] = makeSignOp(idents[1], paramTypes[1], 're');
+ return idents[0] + (variant === 'eq' ? '==' : '!=') + idents[1];
}
default: throw 'Unknown icmp variant: ' + variant;
}
@@ -1802,23 +1795,23 @@ function processMathop(item) {
switch (variant) {
// TODO 'o' ones should be 'ordered (no NaN) and',
// 'u' ones should be 'unordered or'.
- case 'uge': case 'oge': return ident1 + ' >= ' + ident2;
- case 'ule': case 'ole': return ident1 + ' <= ' + ident2;
- case 'ugt': case 'ogt': return ident1 + ' > ' + ident2;
- case 'ult': case 'olt': return ident1 + ' < ' + ident2;
- case 'une': case 'one': return ident1 + ' != ' + ident2;
- case 'ueq': case 'oeq': return ident1 + ' == ' + ident2;
- case 'ord': return '!isNaN(' + ident1 + ') && !isNaN(' + ident2 + ')';
- case 'uno': return 'isNaN(' + ident1 + ') || isNaN(' + ident2 + ')';
+ case 'uge': case 'oge': return idents[0] + ' >= ' + idents[1];
+ case 'ule': case 'ole': return idents[0] + ' <= ' + idents[1];
+ case 'ugt': case 'ogt': return idents[0] + ' > ' + idents[1];
+ case 'ult': case 'olt': return idents[0] + ' < ' + idents[1];
+ case 'une': case 'one': return idents[0] + ' != ' + idents[1];
+ case 'ueq': case 'oeq': return idents[0] + ' == ' + idents[1];
+ case 'ord': return '!isNaN(' + idents[0] + ') && !isNaN(' + idents[1] + ')';
+ case 'uno': return 'isNaN(' + idents[0] + ') || isNaN(' + idents[1] + ')';
case 'true': return '1';
default: throw 'Unknown fcmp variant: ' + variant;
}
}
// Note that zext has sign checking, see above. We must guard against -33 in i8 turning into -33 in i32
// then unsigning that i32... which would give something huge.
- case 'zext': case 'fpext': case 'sext': return ident1;
- case 'fptrunc': return ident1;
- case 'select': return ident1 + ' ? ' + ident2 + ' : ' + ident3;
+ case 'zext': case 'fpext': case 'sext': return idents[0];
+ case 'fptrunc': return idents[0];
+ case 'select': return idents[0] + ' ? ' + idents[1] + ' : ' + idents[2];
case 'ptrtoint': case 'inttoptr': {
var ret = '';
if (QUANTUM_SIZE == 1) {
@@ -1826,9 +1819,9 @@ function processMathop(item) {
'The safest thing is to investigate every appearance, and modify the source code to avoid this. ' +
'Emscripten will print a list of the .ll lines, and also annotate the .js.');
dprint(' ' + op + ' on .ll line ' + item.lineNum);
- ident1 += ' /* Warning: ' + op + ', .ll line ' + item.lineNum + ' */';
+ idents[0] += ' /* Warning: ' + op + ', .ll line ' + item.lineNum + ' */';
}
- if (op == 'inttoptr' || bitsLeft >= 32) return ident1;
+ if (op == 'inttoptr' || bitsLeft >= 32) return idents[0];
// For ptrtoint and <32 bits, fall through into trunc since we need to truncate here
}
case 'trunc': {
@@ -1836,23 +1829,23 @@ function processMathop(item) {
// truncating can change the number, e.g. by truncating to an i1
// in order to get the first bit
assert(bitsLeft <= 32, 'Cannot truncate to more than 32 bits, since we use a native & op');
- return '((' + ident1 + ') & ' + (Math.pow(2, bitsLeft)-1) + ')';
+ return '((' + idents[0] + ') & ' + (Math.pow(2, bitsLeft)-1) + ')';
}
case 'bitcast': {
// Most bitcasts are no-ops for us. However, the exception is int to float and float to int
- var inType = item.param1.type;
+ var inType = item.params[0].type;
var outType = item.type;
if ((inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) ||
(inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES)) {
assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2');
assert(inType == 'i32' || inType == 'float', 'Can only bitcast ints <-> floats with 32 bits (try I64_MODE=1)');
if (inType in Runtime.INT_TYPES) {
- return '(tempDoubleI32[0] = ' + ident1 + ',tempDoubleF32[0])';
+ return '(tempDoubleI32[0] = ' + idents[0] + ',tempDoubleF32[0])';
} else {
- return '(tempDoubleF32[0] = ' + ident1 + ',tempDoubleI32[0])';
+ return '(tempDoubleF32[0] = ' + idents[0] + ',tempDoubleI32[0])';
}
}
- return ident1;
+ return idents[0];
}
default: throw 'Unknown mathcmp op: ' + item.op;
}
@@ -1870,9 +1863,6 @@ function walkInterdata(item, pre, post, obj) {
// TODO if (item.pointer && walkInterdata(item.pointer, pre, post, obj)) return true;
if (item.dependent && walkInterdata(item.dependent, pre, post, obj)) return true;
var i;
- for (i = 1; i <= 4; i++) {
- if (item['param'+i] && walkInterdata(item['param'+i], pre, post, obj)) return true;
- }
if (item.params) {
for (i = 0; i <= item.params.length; i++) {
if (walkInterdata(item.params[i], pre, post, obj)) return true;
@@ -1899,12 +1889,8 @@ function walkAndModifyInterdata(item, pre) {
if (item.value && (repl = walkAndModifyInterdata(item.value, pre))) item.value = repl;
if (item.pointer && (repl = walkAndModifyInterdata(item.pointer, pre))) item.pointer = repl;
if (item.dependent && (repl = walkAndModifyInterdata(item.dependent, pre))) item.dependent = repl;
- var i;
- for (i = 1; i <= 4; i++) {
- if (item['param'+i] && (repl = walkAndModifyInterdata(item['param'+i], pre))) item['param'+i] = repl;
- }
if (item.params) {
- for (i = 0; i <= item.params.length; i++) {
+ for (var i = 0; i <= item.params.length; i++) {
if (repl = walkAndModifyInterdata(item.params[i], pre)) item.params[i] = repl;
}
}