diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-10-29 18:38:52 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-10-29 18:52:24 -0700 |
commit | 0154b1effe2cde0ad81a1adcbe83b7c9d018dbbd (patch) | |
tree | 1dee9c9ad2edc3d860dc4deebb0696376a70b1ce /src | |
parent | 2e50e7ca8ae5f6e18894c74fe4d33c90e404c6bc (diff) |
add test for precise float32 support, allow 3 modes of precise float32 support, and rename option to PRECISE_F32 to be consistent with other precision options
Diffstat (limited to 'src')
-rw-r--r-- | src/parseTools.js | 14 | ||||
-rw-r--r-- | src/preamble.js | 7 | ||||
-rw-r--r-- | src/settings.js | 8 |
3 files changed, 20 insertions, 9 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 79a88373..4dbabbb0 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1187,7 +1187,7 @@ function ensureDot(value) { function asmEnsureFloat(value, type) { // ensures that a float type has either 5.5 (clearly a float) or +5 (float due to asm coercion) if (!ASM_JS) return value; if (!isNumber(value)) return value; - if (FROUND && type === 'float') { + if (PRECISE_F32 && type === 'float') { // normally ok to just emit Math_fround(0), but if the constant is large we may need a .0 (if it can't fit in an int) if (value == 0) return 'Math_fround(0)'; value = ensureDot(value); @@ -1207,7 +1207,7 @@ function asmEnsureFloat(value, type) { // ensures that a float type has either 5 function asmInitializer(type) { if (type in Runtime.FLOAT_TYPES) { - if (FROUND && type === 'float') return 'Math_fround(0)'; + if (PRECISE_F32 && type === 'float') return 'Math_fround(0)'; return RUNNING_JS_OPTS ? '+0' : '.0'; } else { return '0'; @@ -1229,7 +1229,7 @@ function asmCoercion(value, type, signedness) { value = '(' + value + ')|0'; } } - if (FROUND && type === 'float') { + if (PRECISE_F32 && type === 'float') { return 'Math_fround(' + value + ')'; } else { return '(+(' + value + '))'; @@ -2153,7 +2153,7 @@ function makeIsNaN(value, type) { } function makeFloat(value, type) { - if (FROUND && type == 'float') { + if (PRECISE_F32 && type == 'float') { return 'Math_fround(' + value + ')'; } return value; @@ -2502,11 +2502,11 @@ function processMathop(item) { } case 'sext': return idents[0]; case 'fpext': { - if (FROUND) return '+(' + idents[0] + ')'; + if (PRECISE_F32) return '+(' + idents[0] + ')'; return idents[0]; } case 'fptrunc': { - if (FROUND) return 'Math_fround(' + idents[0] + ')'; + if (PRECISE_F32) return 'Math_fround(' + idents[0] + ')'; return idents[0]; } case 'select': return idents[0] + '?' + asmEnsureFloat(idents[1], item.type) + ':' + asmEnsureFloat(idents[2], item.type); @@ -2706,7 +2706,7 @@ function ensureValidFFIType(type) { // FFI return values must arrive as doubles, and we can force them to floats afterwards function asmFFICoercion(value, type) { value = asmCoercion(value, ensureValidFFIType(type)); - if (FROUND && type === 'float') value = asmCoercion(value, 'float'); + if (PRECISE_F32 && type === 'float') value = asmCoercion(value, 'float'); return value; } diff --git a/src/preamble.js b/src/preamble.js index f00e59e0..8ab6d604 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -1074,8 +1074,13 @@ Math['imul'] = function(a, b) { #endif Math.imul = Math['imul']; -#if FROUND +#if PRECISE_F32 +#if PRECISE_F32 == 1 +var froundBuffer = new Float32Array(1); +if (!Math['fround']) Math['fround'] = function(x) { froundBuffer[0] = x; return froundBuffer[0] }; +#else // 2 if (!Math['fround']) Math['fround'] = function(x) { return x }; +#endif Math.fround = Math['fround']; #endif diff --git a/src/settings.js b/src/settings.js index 3ea513cb..de9ab46c 100644 --- a/src/settings.js +++ b/src/settings.js @@ -115,7 +115,13 @@ 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 FROUND = 0; // Use Math.fround (polyfilling when necessary) +var PRECISE_F32 = 0; // 0: Use JS numbers for floating-point values. These are 64-bit and do not model C++ + // floats exactly, which are 32-bit. + // 1: Model C++ floats precisely, using Math.fround, polyfilling when necessary. This + // can be slow if the polyfill is used on heavy float32 computation. + // 2: Model C++ floats precisely using Math.fround if available in the JS engine, otherwise + // use an empty polyfill. This will have less of a speed penalty than using the full + // polyfill in cases where engine support is not present. var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure // compiler. This potentially lets closure optimize the code better. |