diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/analyzer.js | 2 | ||||
-rw-r--r-- | src/intertyper.js | 10 | ||||
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rw-r--r-- | src/library.js | 10 | ||||
-rw-r--r-- | src/library_gl.js | 4 | ||||
-rw-r--r-- | src/library_sdl.js | 42 | ||||
-rw-r--r-- | src/parseTools.js | 70 | ||||
-rw-r--r-- | system/include/emscripten/vector.h | 10 | ||||
-rw-r--r-- | tests/cases/caall.ll | 2 | ||||
-rw-r--r-- | tests/test_core.py | 18 | ||||
-rw-r--r-- | tests/test_sanity.py | 6 | ||||
-rw-r--r-- | tools/shared.py | 2 |
13 files changed, 109 insertions, 70 deletions
@@ -105,4 +105,5 @@ a license to everyone to use it as detailed in LICENSE.) * Remi Papillie <remi.papillie@gmail.com> * Fraser Adams <fraser.adams@blueyonder.co.uk> * Michael Tirado <icetooth333@gmail.com> +* Ben Noordhuis <info@bnoordhuis.nl> diff --git a/src/analyzer.js b/src/analyzer.js index 2b74a83f..253c5505 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -418,7 +418,7 @@ function analyzer(data, sidePass) { toAdd.push({ intertype: 'value', assignTo: element.ident, - type: element.bits, + type: 'i' + element.bits, ident: 'tempRet' + (j - 1) }); assert(j<10); // TODO: dynamically create more than 10 tempRet-s diff --git a/src/intertyper.js b/src/intertyper.js index d3640889..fceeb38d 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -682,7 +682,7 @@ function intertyper(lines, sidePass, baseLineNums) { } if (item.assignTo) item.ident = 'return ' + item.ident; item.ident = '(function(' + params + ') { ' + item.ident + ' })(' + args + ');'; - return { forward: null, ret: item, item: item }; + return { ret: item, item: item }; } if (item.ident.substr(-2) == '()') { // See comment in isStructType() @@ -705,13 +705,12 @@ function intertyper(lines, sidePass, baseLineNums) { if (item.indent == 2) { // standalone call - not in assign item.standalone = true; - return { forward: null, ret: item, item: item }; + return { ret: item, item: item }; } - return { forward: item, ret: null, item: item }; + return { ret: null, item: item }; } function callHandler(item) { var result = makeCall.call(this, item, 'call'); - if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); return result.ret; } function invokeHandler(item) { @@ -721,10 +720,9 @@ function intertyper(lines, sidePass, baseLineNums) { finalResults.push({ intertype: 'branch', label: result.item.toLabel, - lineNum: (result.forward ? item.parentLineNum : item.lineNum) + 0.5 + lineNum: item.lineNum + 0.5 }); } - if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); return result.ret; } function atomicHandler(item) { diff --git a/src/jsifier.js b/src/jsifier.js index adcb38ee..0da48a8c 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1491,7 +1491,7 @@ function JSify(data, functionsOnly, givenFunctions) { } params.forEach(function(param, i) { - var val = finalizeParam(param); + var val = finalizeLLVMParameter(param); if (!hasVarArgs || useJSArgs || i < normalArgs) { args.push(val); argsTypes.push(param.type); diff --git a/src/library.js b/src/library.js index 6eab2587..e3cdc7c3 100644 --- a/src/library.js +++ b/src/library.js @@ -8578,7 +8578,7 @@ LibraryManager.library = { }, emscripten_run_script_string: function(ptr) { - var s = eval(Pointer_stringify(ptr)); + var s = eval(Pointer_stringify(ptr)) + ''; var me = _emscripten_run_script_string; if (!me.bufferSize || me.bufferSize < s.length+1) { if (me.bufferSize) _free(me.buffer); @@ -8621,6 +8621,14 @@ LibraryManager.library = { }, //============================ + // emscripten vector ops + //============================ + + emscripten_float32x4_signmask__inline: function(x) { + return x + '.signMask()'; + }, + + //============================ // i64 math //============================ diff --git a/src/library_gl.js b/src/library_gl.js index 6f145e91..76501111 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -3227,7 +3227,9 @@ var LibraryGL = { #if ASSERTIONS if (!useCurrProgram) { - assert(GL.immediate.TexEnvJIT.getTexUnitType(i) != 0, "GL_TEXTURE" + i + " coords are supplied, but that texture unit is disabled in the fixed-function pipeline."); + if (GL.immediate.TexEnvJIT.getTexUnitType(i) == 0) { + Runtime.warnOnce("GL_TEXTURE" + i + " coords are supplied, but that texture unit is disabled in the fixed-function pipeline."); + } } #endif diff --git a/src/library_sdl.js b/src/library_sdl.js index e652dfc8..04a66351 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -153,24 +153,30 @@ var LibrarySDL = { 120: 27, 121: 28, 122: 29, // Z - 44: 54, // comma - 46: 55, // period - 47: 56, // slash - 49: 30, // 1 - 50: 31, - 51: 32, - 52: 33, - 53: 34, - 54: 35, - 55: 36, - 56: 37, - 57: 38, // 9 - 48: 39, // 0 - 13: 40, // return - 9: 43, // tab - 27: 41, // escape - 32: 44, // space - 92: 49, // backslash + 49: 30, // 1 + 50: 31, + 51: 32, + 52: 33, + 53: 34, + 54: 35, + 55: 36, + 56: 37, + 57: 38, // 9 + 48: 39, // 0 + 13: 40, // return + 27: 41, // escape + 8: 42, // backspace + 9: 43, // tab + 32: 44, // space + 61: 46, // equals + 91: 47, // left bracket + 93: 48, // right bracket + 92: 49, // backslash + 59: 51, // ; + 96: 52, // apostrophe + 44: 54, // comma + 46: 55, // period + 47: 56, // slash 305: 224, // ctrl 308: 226, // alt }, diff --git a/src/parseTools.js b/src/parseTools.js index 16f4058c..db95d71f 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -157,6 +157,10 @@ function isStructType(type) { return type[0] == '%'; } +function isVectorType(type) { + return type[type.length-1] === '>'; +} + function isStructuralType(type) { return /^{ ?[^}]* ?}$/.test(type); // { i32, i8 } etc. - anonymous struct types } @@ -215,8 +219,22 @@ function isIdenticallyImplemented(type1, type2) { } function isIllegalType(type) { - var bits = getBits(type); - return bits > 0 && (bits >= 64 || !isPowerOfTwo(bits)); + switch (type) { + case 'i1': + case 'i8': + case 'i16': + case 'i32': + case 'float': + case 'double': + case 'rawJS': + case '<2 x float>': + case '<4 x float>': + case '<2 x i32>': + case '<4 x i32>': + case 'void': return false; + } + if (!type || type[type.length-1] === '*') return false; + return true; } function isVoidType(type) { @@ -287,6 +305,9 @@ function getReturnType(type) { if (pointingLevels(type) > 1) return '*'; // the type of a call can be either the return value, or the entire function. ** or more means it is a return value var lastOpen = type.lastIndexOf('('); if (lastOpen > 0) { + // handle things like void (i32)* (i32, void (i32)*)* + var closeStar = type.indexOf(')*'); + if (closeStar > 0 && closeStar < type.length-2) lastOpen = closeStar+3; return type.substr(0, lastOpen-1); } return type; @@ -466,26 +487,13 @@ function parseParamTokens(params) { Types.needAnalysis[ret[ret.length-1].type] = 0; anonymousIndex ++; } - } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { - ret.push(parseLLVMFunctionCall(segment)); - } else if (segment[1].text === 'blockaddress') { - ret.push(parseBlockAddress(segment)); - } else if (segment[1].type && segment[1].type == '{') { - ret.push(parseLLVMSegment(segment)); } else { if (segment[2] && segment[2].text == 'to') { // part of bitcast params segment = segment.slice(0, 2); } - while (segment.length > 2) { - segment[0].text += segment[1].text; - segment.splice(1, 1); // TODO: merge tokens nicely - } - ret.push({ - intertype: 'value', - type: segment[0].text, - ident: toNiceIdent(parseNumerical(segment[1].text, segment[0].text)) - }); - Types.needAnalysis[removeAllPointing(ret[ret.length-1].type)] = 0; + var parsed = parseLLVMSegment(segment); + if (parsed.intertype === 'value' && !isIllegalType(parsed.type)) parsed.ident = parseNumerical(parsed.ident, parsed.type); + ret.push(parsed); } ret[ret.length-1].byVal = byVal; } @@ -559,25 +567,6 @@ function sortGlobals(globals) { }); } -function finalizeParam(param) { - if (param.intertype in PARSABLE_LLVM_FUNCTIONS) { - return finalizeLLVMFunctionCall(param); - } else if (param.intertype === 'blockaddress') { - return finalizeBlockAddress(param); - } else if (param.intertype === 'jsvalue') { - return param.ident; - } else { - if (param.type == 'i64' && USE_TYPED_ARRAYS == 2) { - return parseI64Constant(param.ident); - } - var ret = toNiceIdent(param.ident); - if (ret in Variables.globals) { - ret = makeGlobalUse(ret); - } - return ret; - } -} - // Segment ==> Parameter function parseLLVMSegment(segment) { var type; @@ -2001,6 +1990,8 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) { } else if (param.ident == 'zeroinitializer') { if (isStructType(param.type)) { return makeLLVMStruct(zeros(Types.types[param.type].fields.length)); + } else if (isVectorType(param.type)) { + return ensureVector(0, getVectorBaseType(param.type)); } else { return '0'; } @@ -2023,7 +2014,7 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) { } else if (param.intertype == 'mathop') { return processMathop(param); } else if (param.intertype === 'vector') { - return 'float32x4(' + param.idents.join(',') + ')'; + return getVectorBaseType(param.type) + '32x4(' + param.idents.join(',') + ')'; } else { throw 'invalid llvm parameter: ' + param.intertype; } @@ -2383,6 +2374,9 @@ function processMathop(item) { return 'SIMD.uint32x4BitsToFloat32x4(' + idents[0] + ')'; } } + case 'and': return 'SIMD.and(' + idents[0] + ',' + idents[1] + ')'; + case 'or': return 'SIMD.or(' + idents[0] + ',' + idents[1] + ')'; + case 'xor': return 'SIMD.xor(' + idents[0] + ',' + idents[1] + ')'; default: throw 'vector op todo: ' + dump(item); } } diff --git a/system/include/emscripten/vector.h b/system/include/emscripten/vector.h index ea148f0d..938f2369 100644 --- a/system/include/emscripten/vector.h +++ b/system/include/emscripten/vector.h @@ -4,3 +4,13 @@ typedef float float32x4 __attribute__((__vector_size__(16))); typedef unsigned int uint32x4 __attribute__((__vector_size__(16))); +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int emscripten_float32x4_signmask(float32x4 x); + +#ifdef __cplusplus +} +#endif + diff --git a/tests/cases/caall.ll b/tests/cases/caall.ll index 313116e6..5b8f7f29 100644 --- a/tests/cases/caall.ll +++ b/tests/cases/caall.ll @@ -18,7 +18,7 @@ entry: define (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 %x) { entry: %ret = inttoptr i32 0 to (i32*)** - ret %ret + ret (i32*)** %ret } ; [#uses=1] diff --git a/tests/test_core.py b/tests/test_core.py index 89dd725f..0cd619b0 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -8657,9 +8657,15 @@ _mm_set_ps(const float __Z, const float __Y, const float __X, const float __W) return (float32x4){ __W, __X, __Y, __Z }; } +static __inline__ float32x4 __attribute__((__always_inline__)) +_mm_setzero_ps(void) +{ + return (float32x4){ 0.0, 0.0, 0.0, 0.0 }; +} + int main(int argc, char **argv) { float data[8]; - for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc); + for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc); // confuse optimizer { float32x4 *a = (float32x4*)&data[0]; float32x4 *b = (float32x4*)&data[4]; @@ -8671,6 +8677,8 @@ int main(int argc, char **argv) { printf("2floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); d = c*d; printf("3floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + c = _mm_setzero_ps(); + printf("zeros %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3]); } { uint32x4 *a = (uint32x4*)&data[0]; @@ -8682,12 +8690,18 @@ int main(int argc, char **argv) { e = c+d; f = c-d; printf("5uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]); + e = c&d; + f = c|d; + e = ~c&d; + f = c^d; + printf("5uintops! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]); } { float32x4 c, d, e, f; c = _mm_set_ps(9.0, 4.0, 0, -9.0); d = _mm_set_ps(10.0, 14.0, -12, -2.0); printf("6floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + printf("7calcs: %d\n", emscripten_float32x4_signmask(c)); // TODO: just not just compilation but output as well } return 0; @@ -8697,8 +8711,10 @@ int main(int argc, char **argv) { self.do_run(src, '''1floats! 6, 12, 20, 30 42, 56, 72, 90 2floats! 48, 68, 92, 120 42, 56, 72, 90 3floats! 48, 68, 92, 120 2016, 3808, 6624, 10800 +zeros 0, 0, 0, 0 4uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736 5uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056 +5uintops! 36175872, 35651584, 34603008, 33816576 48758784, 52428800, 53477376, 54788096 6floats! -9, 0, 4, 9 -2, -12, 14, 10 ''') diff --git a/tests/test_sanity.py b/tests/test_sanity.py index a0fff252..a405c3a3 100644 --- a/tests/test_sanity.py +++ b/tests/test_sanity.py @@ -217,7 +217,11 @@ class sanity(RunnerCore): try: os.environ['EM_IGNORE_SANITY'] = '1' - for version, succeed in [('v0.7.9', False), ('v0.8.0', True), ('v0.8.1', True), ('cheez', False)]: + for version, succeed in [('v0.7.9', False), + ('v0.8.0', True), + ('v0.8.1', True), + ('v0.10.21-pre', True), + ('cheez', False)]: f = open(path_from_root('tests', 'fake', 'nodejs'), 'w') f.write('#!/bin/sh\n') f.write('''if [ $1 = "--version" ]; then diff --git a/tools/shared.py b/tools/shared.py index 108a48a4..f6c0cc95 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -284,7 +284,7 @@ def check_node_version(): try: node = listify(NODE_JS) actual = Popen(node + ['--version'], stdout=PIPE).communicate()[0].strip() - version = tuple(map(int, actual.replace('v', '').split('.'))) + version = tuple(map(int, actual.replace('v', '').replace('-pre', '').split('.'))) if version >= EXPECTED_NODE_VERSION: return True logging.warning('node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION))))) |