aboutsummaryrefslogtreecommitdiff
path: root/src/parseTools.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/parseTools.js')
-rw-r--r--src/parseTools.js48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index f1413c1c..b68365a1 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -926,14 +926,17 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
if (bytes > align) {
var ret = '(';
if (isIntImplemented(type)) {
- if (bytes <= 4) {
+ if (bytes == 4 && align == 2) {
+ // Special case that we can optimize
+ ret += makeGetValue(ptr, pos, 'i16', noNeedFirst, 2, ignore) + '+' +
+ '(' + makeGetValue(ptr, getFastValue(pos, '+', 2), 'i16', noNeedFirst, 2, ignore) + '<<16)';
+ } else if (bytes <= 4) {
+ ret = '';
for (var i = 0; i < bytes; i++) {
- ret += 'tempInt' + (i == 0 ? '=' : '|=((');
- ret += makeGetValue(ptr, getFastValue(pos, '+', i), 'i8', noNeedFirst, 1, ignore);
- if (i > 0) ret += ')<<' + (8*i) + ')';
- ret += ',';
+ ret += '(' + makeGetValue(ptr, getFastValue(pos, '+', i), 'i8', noNeedFirst, 1, ignore) + (i > 0 ? '<<' + (8*i) : '') + ')';
+ if (i < bytes-1) ret += '|';
}
- ret += makeSignOp('tempInt', type, unsigned ? 'un' : 're', true);
+ ret = '(' + makeSignOp(ret, type, unsigned ? 'un' : 're', true);
} else {
assert(bytes == 8);
ret += 'tempBigInt=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, true, ignore, align) + ',';
@@ -1018,10 +1021,15 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe,
if (bytes > align) {
var ret = '';
if (isIntImplemented(type)) {
- if (bytes <= 4) {
+ if (bytes == 4 && align == 2) {
+ // Special case that we can optimize
+ ret += 'tempBigInt=' + value + sep;
+ ret += makeSetValue(ptr, pos, 'tempBigInt&0xffff', 'i16', noNeedFirst, ignore, 2) + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', 2), 'tempBigInt>>16', 'i16', noNeedFirst, ignore, 2) + sep;
+ } else if (bytes <= 4) {
ret += 'tempBigInt=' + value + sep;
for (var i = 0; i < bytes; i++) {
- ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore) + sep;
+ ret += makeSetValue(ptr, getFastValue(pos, '+', i), 'tempBigInt&0xff', 'i8', noNeedFirst, ignore, 1) + sep;
if (i < bytes-1) ret += 'tempBigInt>>=8' + sep;
}
} else {
@@ -1661,14 +1669,22 @@ function processMathop(item) {
case 'fptoui': case 'fptosi': return splitI64(ident1);
case 'icmp': {
switch (variant) {
- case 'uge': case 'sge': return ident1 + '[1] >= ' + ident2 + '[1] && (' + ident1 + '[1] > ' + ident2 + '[1] || ' +
- ident1 + '[0] >= ' + ident2 + '[0])';
- case 'ule': case 'sle': return ident1 + '[1] <= ' + ident2 + '[1] && (' + ident1 + '[1] < ' + ident2 + '[1] || ' +
- ident1 + '[0] <= ' + ident2 + '[0])';
- case 'ugt': case 'sgt': return ident1 + '[1] > ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
- ident1 + '[0] > ' + ident2 + '[0])';
- case 'ult': case 'slt': return ident1 + '[1] < ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
- ident1 + '[0] < ' + ident2 + '[0])';
+ case 'uge': return ident1 + '[1] >= ' + ident2 + '[1] && (' + ident1 + '[1] > ' + ident2 + '[1] || ' +
+ ident1 + '[0] >= ' + ident2 + '[0])';
+ case 'sge': return '(' + ident1 + '[1]|0) >= (' + ident2 + '[1]|0) && ((' + ident1 + '[1]|0) > (' + ident2 + '[1]|0) || ' +
+ '(' + ident1 + '[0]|0) >= (' + ident2 + '[0]|0))';
+ case 'ule': return ident1 + '[1] <= ' + ident2 + '[1] && (' + ident1 + '[1] < ' + ident2 + '[1] || ' +
+ ident1 + '[0] <= ' + ident2 + '[0])';
+ case 'sle': return '(' + ident1 + '[1]|0) <= (' + ident2 + '[1]|0) && ((' + ident1 + '[1]|0) < (' + ident2 + '[1]|0) || ' +
+ '(' + ident1 + '[0]|0) <= (' + ident2 + '[0]|0))';
+ case 'ugt': return ident1 + '[1] > ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
+ ident1 + '[0] > ' + ident2 + '[0])';
+ case 'sgt': return '(' + ident1 + '[1]|0) > (' + ident2 + '[1]|0) || ((' + ident1 + '[1]|0) == (' + ident2 + '[1]|0) && ' +
+ '(' + ident1 + '[0]|0) > (' + ident2 + '[0]|0))';
+ case 'ult': return ident1 + '[1] < ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
+ ident1 + '[0] < ' + ident2 + '[0])';
+ case 'slt': return '(' + ident1 + '[1]|0) < (' + ident2 + '[1]|0) || ((' + ident1 + '[1]|0) == (' + ident2 + '[1]|0) && ' +
+ '(' + ident1 + '[0]|0) < (' + ident2 + '[0]|0))';
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 !=.