diff options
Diffstat (limited to 'src/library.js')
-rw-r--r-- | src/library.js | 129 |
1 files changed, 107 insertions, 22 deletions
diff --git a/src/library.js b/src/library.js index c8205d2b..1ba4f2fa 100644 --- a/src/library.js +++ b/src/library.js @@ -573,7 +573,7 @@ LibraryManager.library = { eof: false, ungotten: [] }; - assert(Math.max(_stdin, _stdout, _stderr) < 128); // make sure these are low, we flatten arrays with these + assert(Math.max(_stdin, _stdout, _stderr) < 1024); // make sure these are low, we flatten arrays with these {{{ makeSetValue(makeGlobalUse('_stdin'), 0, 1, 'void*') }}}; {{{ makeSetValue(makeGlobalUse('_stdout'), 0, 2, 'void*') }}}; {{{ makeSetValue(makeGlobalUse('_stderr'), 0, 3, 'void*') }}}; @@ -4913,16 +4913,20 @@ LibraryManager.library = { } return 8; } - return 'var ctlz_i8 = [' + range(256).map(function(x) { return ctlz(x) }).join(',') + '];'; + return 'var ctlz_i8 = allocate([' + range(256).map(function(x) { return ctlz(x) }).join(',') + '], "i8", ALLOC_STACK);'; }], + llvm_ctlz_i32__asm: true, + llvm_ctlz_i32__sig: 'ii', llvm_ctlz_i32: function(x) { - var ret = ctlz_i8[x >>> 24]; - if (ret < 8) return ret; - var ret = ctlz_i8[(x >> 16)&0xff]; - if (ret < 8) return ret + 8; - var ret = ctlz_i8[(x >> 8)&0xff]; - if (ret < 8) return ret + 16; - return ctlz_i8[x&0xff] + 24; + x = x|0; + var ret = 0; + ret = {{{ makeGetValueAsm('ctlz_i8', 'x >>> 24', 'i8') }}}; + if ((ret|0) < 8) return ret|0; + var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 16)&0xff', 'i8') }}}; + if ((ret|0) < 8) return (ret + 8)|0; + var ret = {{{ makeGetValueAsm('ctlz_i8', '(x >> 8)&0xff', 'i8') }}}; + if ((ret|0) < 8) return (ret + 16)|0; + return ({{{ makeGetValueAsm('ctlz_i8', 'x&0xff', 'i8') }}} + 24)|0; }, llvm_ctlz_i64__deps: ['llvm_ctlz_i32'], @@ -4945,16 +4949,20 @@ LibraryManager.library = { } return 8; } - return 'var cttz_i8 = [' + range(256).map(function(x) { return cttz(x) }).join(',') + '];'; + return 'var cttz_i8 = allocate([' + range(256).map(function(x) { return cttz(x) }).join(',') + '], "i8", ALLOC_STACK);'; }], + llvm_cttz_i32__asm: true, + llvm_cttz_i32__sig: 'ii', llvm_cttz_i32: function(x) { - var ret = cttz_i8[x & 0xff]; - if (ret < 8) return ret; - var ret = cttz_i8[(x >> 8)&0xff]; - if (ret < 8) return ret + 8; - var ret = cttz_i8[(x >> 16)&0xff]; - if (ret < 8) return ret + 16; - return cttz_i8[x >>> 24] + 24; + x = x|0; + var ret = 0; + ret = {{{ makeGetValueAsm('cttz_i8', 'x & 0xff', 'i8') }}}; + if ((ret|0) < 8) return ret|0; + var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 8)&0xff', 'i8') }}}; + if ((ret|0) < 8) return (ret + 8)|0; + var ret = {{{ makeGetValueAsm('cttz_i8', '(x >> 16)&0xff', 'i8') }}}; + if ((ret|0) < 8) return (ret + 16)|0; + return ({{{ makeGetValueAsm('cttz_i8', 'x >>> 24', 'i8') }}} + 24)|0; }, llvm_cttz_i64__deps: ['llvm_cttz_i32'], @@ -5296,9 +5304,11 @@ LibraryManager.library = { llvm_umul_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) { - i64Math.multiply(xl, xh, yl, yh); - {{{ makeStructuralReturn([makeGetTempDouble(0, 'i32'), makeGetTempDouble(1, 'i32'), '0']) }}}; - // XXX Need to hack support for second param in long.js +#if ASSERTIONS + Runtime.warnOnce('no overflow support in llvm_umul_with_overflow_i64'); +#endif + var low = ___muldi3(xl, xh, yl, yh); + {{{ makeStructuralReturn(['low', 'tempRet0', '0']) }}}; }, llvm_stacksave: function() { @@ -6207,13 +6217,74 @@ LibraryManager.library = { // related functionality so the slowdown is more limited. // ========================================================================== + saveSetjmp__asm: true, + saveSetjmp__sig: 'iii', + saveSetjmp: function(env, label, table) { + // Not particularly fast: slow table lookup of setjmpId to label. But setjmp + // prevents relooping anyhow, so slowness is to be expected. And typical case + // is 1 setjmp per invocation, or less. + env = env|0; + label = label|0; + table = table|0; + var i = 0; +#if ASSERTIONS + if ((label|0) == 0) abort(121); +#endif + setjmpId = (setjmpId+1)|0; + {{{ makeSetValueAsm('env', '0', 'setjmpId', 'i32') }}}; + while ((i|0) < {{{ MAX_SETJMPS }}}) { + if ({{{ makeGetValueAsm('table', 'i*4', 'i32') }}} == 0) { + {{{ makeSetValueAsm('table', 'i*4', 'setjmpId', 'i32') }}}; + {{{ makeSetValueAsm('table', 'i*4+4', 'label', 'i32') }}}; + // prepare next slot + {{{ makeSetValueAsm('table', 'i*4+8', '0', 'i32') }}}; + return 0; + } + i = (i+2)|0; + } + abort(987); // if you hit this, adjust MAX_SETJMPS + return 0; + }, + + testSetjmp__asm: true, + testSetjmp__sig: 'iii', + testSetjmp: function(id, table) { + id = id|0; + table = table|0; + var i = 0, curr = 0; + while ((i|0) < {{{ MAX_SETJMPS }}}) { + curr = {{{ makeGetValueAsm('table', 'i*4', 'i32') }}}; + if ((curr|0) == 0) break; + if ((curr|0) == (id|0)) { + return {{{ makeGetValueAsm('table', 'i*4+4', 'i32') }}}; + } + i = (i+2)|0; + } + return 0; + }, + +#if ASM_JS + setjmp__deps: ['saveSetjmp', 'testSetjmp'], +#endif setjmp__inline: function(env) { // Save the label +#if ASM_JS + return '_saveSetjmp(' + env + ', label, setjmpTable)'; +#else return '(tempInt = setjmpId++, mySetjmpIds[tempInt] = 1, setjmpLabels[tempInt] = label,' + makeSetValue(env, '0', 'tempInt', 'i32', undefined, undefined, undefined, undefined, ',') + ', 0)'; +#endif }, +#if ASM_JS + longjmp__deps: ['saveSetjmp', 'testSetjmp'], +#endif longjmp: function(env, value) { +#if ASM_JS + asm.setThrew(env, value || 1); + throw 'longjmp'; +#else throw { longjmp: true, id: {{{ makeGetValue('env', '0', 'i32') }}}, value: value || 1 }; +#endif }, // ========================================================================== @@ -7492,13 +7563,27 @@ LibraryManager.library = { var l = 0, h = 0, overflow = 0; l = (a + c)>>>0; h = (b + d)>>>0; - if ((l>>>0) < (a>>>0)) { // iff we overflowed + if ((h>>>0) < (b>>>0)) overflow = 1; + if ((l>>>0) < (a>>>0)) { h = (h+1)>>>0; - overflow = 1; + if ((h>>>0) == 0) overflow = 1; // two possibilities to overflow here } {{{ makeStructuralReturn(['l|0', 'h', 'overflow'], true) }}}; }, + i64Subtract__asm: true, + i64Subtract__sig: 'iiiii', + i64Subtract: function(a, b, c, d) { + a = a|0; b = b|0; c = c|0; d = d|0; + var l = 0, h = 0; + l = (a - c)>>>0; + h = (b - d)>>>0; + if ((l>>>0) > (a>>>0)) { // iff we overflowed + h = (h-1)>>>0; + } + {{{ makeStructuralReturn(['l|0', 'h'], true) }}}; + }, + bitshift64Shl__asm: true, bitshift64Shl__sig: 'iiii', bitshift64Shl: function(low, high, bits) { |