aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py2
-rw-r--r--src/analyzer.js10
-rw-r--r--src/parseTools.js17
-rw-r--r--src/preamble.js7
-rw-r--r--src/settings.js1
-rw-r--r--tests/cases/phi24_ta2.ll3
-rw-r--r--tools/find_bigvars.py24
7 files changed, 57 insertions, 7 deletions
diff --git a/emscripten.py b/emscripten.py
index 217fd6d5..1b1284c7 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -423,6 +423,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
math_envs = ['Math.min'] # TODO: move min to maths
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
+ if settings['TO_FLOAT32']: maths += ['Math.toFloat32']
+
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR']
diff --git a/src/analyzer.js b/src/analyzer.js
index 1a752305..931ce421 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -765,7 +765,15 @@ function analyzer(data, sidePass) {
}
break;
}
- case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem':
+ case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': {
+ if (sourceBits < 32) {
+ // when we add illegal types like i24, we must work on the singleton chunks
+ item.assignTo += '$0';
+ item.params[0].ident += '$0';
+ item.params[1].ident += '$0';
+ }
+ // fall through
+ }
case 'uitofp': case 'sitofp': case 'fptosi': case 'fptoui': {
// We cannot do these in parallel chunks of 32-bit operations. We will handle these in processMathop
i++;
diff --git a/src/parseTools.js b/src/parseTools.js
index b655d13e..f11c867a 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2020,6 +2020,13 @@ function makeIsNaN(value) {
return 'isNaN(' + value + ')';
}
+function makeFloat(value, type) {
+ if (TO_FLOAT32 && type == 'float') {
+ return 'Math.toFloat32(' + value + ')';
+ }
+ return value;
+}
+
// fptoui and fptosi are not in these, because we need to be careful about what we do there. We can't
// just sign/unsign the input first.
var UNSIGNED_OP = set('udiv', 'urem', 'uitofp', 'zext', 'lshr');
@@ -2275,11 +2282,11 @@ function processMathop(item) {
return idents[0] + ' >>> ' + idents[1];
}
// basic float ops
- 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 'frem': return getFastValue(idents[0], '%', idents[1], item.type);
+ case 'fadd': return makeFloat(getFastValue(idents[0], '+', idents[1], item.type), item.type);
+ case 'fsub': return makeFloat(getFastValue(idents[0], '-', idents[1], item.type), item.type);
+ case 'fdiv': return makeFloat(getFastValue(idents[0], '/', idents[1], item.type), item.type);
+ case 'fmul': return makeFloat(getFastValue(idents[0], '*', idents[1], item.type), item.type);
+ case 'frem': return makeFloat(getFastValue(idents[0], '%', idents[1], item.type), item.type);
case 'uitofp': case 'sitofp': return asmCoercion(idents[0], 'double', op[0]);
case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true);
diff --git a/src/preamble.js b/src/preamble.js
index 95bf2dc2..0f3f52c9 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -853,6 +853,13 @@ Math['imul'] = function(a, b) {
#endif
Math.imul = Math['imul'];
+#if TO_FLOAT32
+if (!Math['toFloat32']) Math['toFloat32'] = function(x) {
+ return x;
+};
+Math.toFloat32 = Math['toFloat32'];
+#endif
+
// A counter of dependencies for calling run(). If we need to
// do asynchronous work before running, increment this and
// decrement it. Incrementing must happen in a place like
diff --git a/src/settings.js b/src/settings.js
index 3515091d..3ecac040 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -108,6 +108,7 @@ var PRECISE_I64_MATH = 1; // If enabled, i64 addition etc. is emulated - which i
var PRECISE_I32_MUL = 1; // If enabled, i32 multiplication is done with full precision, which means it is
// correct even if the value exceeds the JS double-integer limit of ~52 bits (otherwise,
// rounding will occur above that range).
+var TO_FLOAT32 = 0; // Use Math.toFloat32
var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure
// compiler. This potentially lets closure optimize the code better.
diff --git a/tests/cases/phi24_ta2.ll b/tests/cases/phi24_ta2.ll
index b5b0664b..4894d5e6 100644
--- a/tests/cases/phi24_ta2.ll
+++ b/tests/cases/phi24_ta2.ll
@@ -549,7 +549,8 @@ safe_mod_func_uint32_t_u_u.exit.i.i: ; preds = %189, %.preheader..p
%p_5.sroa.0.0.extract.trunc2674116.i.i = phi i8 [ %p_5.sroa.0.0.extract.trunc2670.i.i, %189 ], [ -1, %.preheader..preheader.split_crit_edge.i.i ]
%p_5.sroa.1.sroa.0.0.load6982115.i.i = phi i24 [ %p_5.sroa.1.sroa.0.0.load6978.i.i, %189 ], [ -1, %.preheader..preheader.split_crit_edge.i.i ]
store i16 0, i16* @g_84, align 2
- %p_5.sroa.1.1.insert.ext36.i.i = trunc i24 %p_5.sroa.1.sroa.0.0.load6982115.i.i to i16
+ %adddd = add i24 %p_5.sroa.1.sroa.0.0.load6982115.i.i, 1 ; test i24 add
+ %p_5.sroa.1.1.insert.ext36.i.i = trunc i24 %adddd to i16
%p_5.sroa.1.1.insert.shift37.i.i = shl i16 %p_5.sroa.1.1.insert.ext36.i.i, 8
%p_5.sroa.0.0.insert.ext10.i.i = zext i8 %p_5.sroa.0.0.extract.trunc2674116.i.i to i16
%p_5.sroa.0.0.insert.insert12.i.i = or i16 %p_5.sroa.1.1.insert.shift37.i.i, %p_5.sroa.0.0.insert.ext10.i.i
diff --git a/tools/find_bigvars.py b/tools/find_bigvars.py
new file mode 100644
index 00000000..6bee5dd4
--- /dev/null
+++ b/tools/find_bigvars.py
@@ -0,0 +1,24 @@
+'''
+Simple tool to find functions with lots of vars.
+'''
+
+import os, sys, re
+
+filename = sys.argv[1]
+i = 0
+curr = None
+data = []
+size = 0
+for line in open(filename):
+ i += 1
+ if line.startswith('function '):
+ size = len(line.split(',')) # params
+ curr = line
+ elif line.strip().startswith('var '):
+ size += len(line.split(',')) + 1 # vars
+ elif line.startswith('}') and curr:
+ data.append([curr, size])
+ curr = None
+data.sort(lambda x, y: x[1] - y[1])
+print ''.join(['%6d : %s' % (x[1], x[0]) for x in data])
+