aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parseTools.js15
-rw-r--r--src/relooper/Relooper.cpp16
-rw-r--r--src/settings.js2
3 files changed, 27 insertions, 6 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index e226a4f8..e081d0de 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1045,9 +1045,14 @@ function asmCoercion(value, type, signedness) {
}
}
+var TWO_TWENTY = Math.pow(2, 20);
+
function asmMultiplyI32(a, b) {
// special-case: there is no integer multiply in asm, because there is no true integer
// multiply in JS. While we wait for Math.imul, do double multiply
+ if ((isNumber(a) && Math.abs(a) < TWO_TWENTY) || (isNumber(b) && Math.abs(b) < TWO_TWENTY)) {
+ return '(((' + a + ')*(' + b + '))&-1)'; // small enough to emit directly as a multiply
+ }
if (USE_MATH_IMUL) {
return 'Math.imul(' + a + ',' + b + ')';
}
@@ -1949,6 +1954,7 @@ function processMathop(item) {
if (item.type[0] === 'i') {
bits = parseInt(item.type.substr(1));
}
+ var bitsBefore = parseInt((item.params[0] ? item.params[0].type : item.type).substr(1)); // remove i to leave the number of bits left after this
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) {
@@ -2230,7 +2236,14 @@ function processMathop(item) {
}
// 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 idents[0];
+ case 'zext': {
+ if (EXPLICIT_ZEXT && bitsBefore == 1 && bitsLeft > 1) {
+ return '(' + originalIdents[0] + '?1:0)'; // explicit bool-to-int conversion, work around v8 issue 2513
+ break;
+ }
+ // otherwise, fall through
+ }
+ case 'fpext': case 'sext': return idents[0];
case 'fptrunc': return idents[0];
case 'select': return idents[0] + ' ? ' + asmEnsureFloat(idents[1], item.type) + ' : ' + asmEnsureFloat(idents[2], item.type);
case 'ptrtoint': case 'inttoptr': {
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index 6ea9e7f4..ae8577b1 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -253,11 +253,20 @@ int Shape::IdCounter = 0;
void MultipleShape::RenderLoopPrefix() {
if (NeedLoop) {
- PrintIndented("L%d: \n", Id);
+ if (Labeled) {
+ PrintIndented("L%d: do {\n", Id);
+ } else {
+ PrintIndented("do {\n");
+ }
+ Indenter::Indent();
}
}
void MultipleShape::RenderLoopPostfix() {
+ if (NeedLoop) {
+ Indenter::Unindent();
+ PrintIndented("} while(0);\n");
+ }
}
void MultipleShape::Render(bool InLoop) {
@@ -912,10 +921,7 @@ void Relooper::Calculate(Block *Entry) {
Branch *Details = iter->second;
if (Details->Type != Branch::Direct) {
assert(LoopStack.size() > 0);
- // If the ancestor is not at the top of the stack, we need a labelled break. We also
- // always need a labeled break for multiple blocks, which are always labeled.
- MultipleShape *Multiple;
- if (Details->Ancestor != LoopStack.top() || Shape::IsMultiple(Details->Ancestor)) {
+ if (Details->Ancestor != LoopStack.top()) {
LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor);
Labeled->Labeled = true;
Details->Labeled = true;
diff --git a/src/settings.js b/src/settings.js
index e43a717c..0234d0ca 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -327,6 +327,8 @@ var ASM_JS = 0; // If 1, generate code in asm.js format. XXX This is highly expe
// try this yet.
var USE_MATH_IMUL = 0; // If 1, use Math.imul when useful
+var EXPLICIT_ZEXT = 0; // If 1, generate an explicit conversion of zext i1 to i32, using ?:
+
var NECESSARY_BLOCKADDRS = []; // List of (function, block) for all block addresses that are taken.
// Compiler debugging options