diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-11-10 11:08:48 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-11-10 11:08:48 -0800 |
commit | 74ad2855886778cf5957a460179b290b928ac994 (patch) | |
tree | 68cf67380e0f12a812e6de5b31b6868cf25fe539 /src | |
parent | 2e67d240b5255b24dc5423d7797ffe196527dab3 (diff) |
i64 fixes, first part of test_i64 passes
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 30 | ||||
-rw-r--r-- | src/library.js | 6 | ||||
-rw-r--r-- | src/parseTools.js | 68 | ||||
-rw-r--r-- | src/preamble.js | 4 |
4 files changed, 60 insertions, 48 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 64fe5e4a..b362009d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -841,23 +841,43 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { var argsTypes = []; var varargs = []; var varargsTypes = []; + var ignoreFunctionIndexizing = []; var useJSArgs = (shortident + '__jsargs') in LibraryManager.library; params.forEach(function(param, i) { var val = finalizeParam(param); if (!func || !func.hasVarArgs || i < func.numParams-1 || useJSArgs) { + if (param.type == 'i64' && I64_MODE == 1) { + val = makeI64Copy(val); // Must copy [low, high] i64s, so they don't end up modified in the caller + } args.push(val); argsTypes.push(param.type); } else { - varargs.push(val); - varargs = varargs.concat(zeros(getNativeFieldSize(param.type)-1)); - varargsTypes.push(param.type); - varargsTypes = varargsTypes.concat(zeros(getNativeFieldSize(param.type)-1)); + if (!(param.type == 'i64' && I64_MODE == 1)) { + varargs.push(val); + varargs = varargs.concat(zeros(getNativeFieldSize(param.type)-1)); + varargsTypes.push(param.type); + varargsTypes = varargsTypes.concat(zeros(getNativeFieldSize(param.type)-1)); + } else { + // i64 mode 1. Write one i32 with type i64, and one i32 with type i32 + varargs.push(val + '[0]'); + varargs = varargs.concat(zeros(getNativeFieldSize('i32')-1)); + ignoreFunctionIndexizing.push(varargs.length); // We will have a value there, but no type (the type is i64, but we write two i32s) + varargs.push(val + '[1]'); + varargs = varargs.concat(zeros(getNativeFieldSize('i32')-1)); + varargsTypes.push('i64'); + varargsTypes = varargsTypes.concat(zeros(getNativeFieldSize('i32')-1)); + varargsTypes.push('i32'); + varargsTypes = varargsTypes.concat(zeros(getNativeFieldSize('i32')-1)); + } } }); args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); - varargs = varargs.map(function(vararg, i) { return vararg === 0 ? 0 : indexizeFunctions(vararg, varargsTypes[i]) }); + varargs = varargs.map(function(vararg, i) { + if (ignoreFunctionIndexizing.indexOf(i) >= 0) return vararg; + return vararg === 0 ? 0 : indexizeFunctions(vararg, varargsTypes[i]) + }); if (func && func.hasVarArgs && !useJSArgs) { if (varargs.length === 0) { diff --git a/src/library.js b/src/library.js index cb6a2ea3..4bb74001 100644 --- a/src/library.js +++ b/src/library.js @@ -2205,6 +2205,12 @@ LibraryManager.library = { var ret; if (type === 'float' || type === 'double') { ret = {{{ makeGetValue('varargs', 'argIndex', 'double', undefined, undefined, true) }}}; +#if I64_MODE == 1 + } else if (type == 'i64') { + ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}, + {{{ makeGetValue('varargs', 'argIndex+4', 'i32', undefined, undefined, true) }}}]; + ret = ret[0] + ret[1]*Math.pow(2, 32); // XXX - loss of precision +#endif } else { ret = {{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}; } diff --git a/src/parseTools.js b/src/parseTools.js index 879c8537..b7ea28e1 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -526,6 +526,16 @@ function IEEEUnHex(stringy) { return (absolute * (neg ? -1 : 1)).toString(); } +// Makes a proper runtime value for a 64-bit value. Used in library. +function makeI64(low, high) { + if (I64_MODE == 1) { + return '[' + low + ',' + (high || '0') + ']'; + } else { + assert(!high); + return low; + } +} + function makeCopyI64(value) { assert(I64_MODE == 1); @@ -774,16 +784,6 @@ function checkSafeHeap() { return SAFE_HEAP === 1 || checkSpecificSafeHeap(); } -// Makes a proper runtime value for a 64-bit value. Used in library. -function makeI64(low, high) { - if (I64_MODE == 1) { - return '[' + low + ',' + (high || '0') + ']'; - } else { - assert(!high); - return low; - } -} - function getHeapOffset(offset, type) { if (USE_TYPED_ARRAYS !== 2) { return offset; @@ -1357,7 +1357,7 @@ function processMathop(item) { with(item) { return '(tempBigInt=(' + value + '), tempBigInt-tempBigInt%1)'; } - if (item.type == 'i64' && I64_MODE == 1) { + if ((paramTypes[0] == 'i64' || paramTypes[1] == 'i64') && I64_MODE == 1) { switch (op) { // basic integer ops case 'or': { @@ -1371,27 +1371,27 @@ function processMathop(item) { with(item) { } case 'shl': { return '[' + ident1 + '[0] << ' + ident2 + ', ' + - '('+ident1 + '[1] << ' + ident2 + ') | ((' + ident + '[0]&((Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + '))]'; + '('+ident1 + '[1] << ' + ident2 + ') | (' + ident1 + '[0]&(Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + '))]'; } case 'ashr': { - return '[('+ident1 + '[0] >> ' + ident2 + ') | ((' + ident + '[1]&((Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + '))]'; - + ident1 + '[1] >> ' + ident2 + ']'; + return '[('+ident1 + '[0] >> ' + ident2 + ') | (' + ident1 + '[1]&(Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + ')),' + + ident1 + '[1] >> ' + ident2 + ']'; } case 'lshr': { - return '[('+ident1 + '[0] >>> ' + ident2 + ') | ((' + ident + '[1]&((Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + '))]'; - + ident1 + '[1] >>> ' + ident2 + ']'; + return '[('+ident1 + '[0] >>> ' + ident2 + ') | (' + ident1 + '[1]&(Math.pow(2, ' + ident2 + ')-1)<<(32-' + ident2 + ') >> (32-' + ident2 + ')),' + + ident1 + '[1] >>> ' + ident2 + ']'; } - + case 'uitofp': case 'sitofp': return ident1 + '[0] + ' + ident1 + '[1]*4294967296'; case 'icmp': { switch (variant) { case 'uge': case 'sge': return ident1 + '[1] >= ' + ident2 + '[1] && (' + ident1 + '[1] > ' + ident2 + '[1] || ' + - '(' + ident1 + '[0] >= ' + ident2 + '[0]'); + ident1 + '[0] >= ' + ident2 + '[0])'; case 'ule': case 'sle': return ident1 + '[1] <= ' + ident2 + '[1] && (' + ident1 + '[1] < ' + ident2 + '[1] || ' + - '(' + ident1 + '[0] <= ' + ident2 + '[0]'); + ident1 + '[0] <= ' + ident2 + '[0])'; case 'ugt': case 'sgt': return ident1 + '[1] > ' + ident2 + '[1] || (' + ident1 + '[1] = ' + ident2 + '[1] && ' + - '(' + ident1 + '[0] > ' + ident2 + '[0]'); + ident1 + '[0] > ' + ident2 + '[0])'; case 'ult': case 'slt': return ident1 + '[1] < ' + ident2 + '[1] || (' + ident1 + '[1] = ' + ident2 + '[1] && ' + - '(' + ident1 + '[0] < ' + ident2 + '[0]'); + ident1 + '[0] < ' + ident2 + '[0])'; case 'ne': case 'eq': { // We must sign them, so we do not compare -1 to 255 (could have unsigned them both too) // since LLVM tells us if <=, >= etc. comparisons are signed, but not == and !=. @@ -1406,30 +1406,12 @@ function processMathop(item) { with(item) { default: throw 'Unknown icmp variant: ' + variant; } } - case 'zext': case 'sext': return makeCopyI64(ident1); + case 'zext': case 'sext': return makeI64(ident1, 0); case 'trunc': { - // Unlike extending, which we just 'do' (by doing nothing), - // truncating can change the number, e.g. by truncating to an i1 - // in order to get the first bit - assert(ident2[1] == 'i'); - assert(bitsLeft <= 32, 'Cannot truncate to more than 32 bits, since we use a native & op'); - return '((' + ident1 + ') & ' + (Math.pow(2, bitsLeft)-1) + ')'; - } - case 'select': return ident1 + ' ? ' + ident2 + ' : ' + ident3; - case 'ptrtoint': case 'inttoptr': { - var ret = ''; - if (QUANTUM_SIZE == 1) { - if (!Debugging.shownPtrtointWarning) { - dprint('WARNING: .ll contains ptrtoint and/or inttoptr. These may be dangerous in QUANTUM == 1.'); - dprint(' The safest thing is to investigate every appearance, and modify the source code to avoid this.'); - dprint(' Emscripten will print a list of the .ll lines, and also annotate the .js.'); - Debugging.shownPtrtointWarning = true; - } - dprint(' ' + op + ' on .ll line ' + item.lineNum); - ret = ' /* Warning: ' + op + ', .ll line ' + item.lineNum + ' */'; - } - return ident1 + ret; + return '((' + ident1 + '[0]) & ' + (Math.pow(2, bitsLeft)-1) + ')'; } + case 'select': return ident1 + ' ? ' + makeCopyI64(ident2) + ' : ' + makeCopyI64(ident3); + case 'ptrtoint': case 'inttoptr': throw 'Pointers cannot be 64-bit!'; default: throw 'Unsupported i64 mode 1 op: ' + item.op; } } diff --git a/src/preamble.js b/src/preamble.js index ec9e672e..51d100e1 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -474,6 +474,10 @@ function allocate(slab, types, allocator) { assert(type, 'Must know what type to store in allocate!'); #endif +#if I64_MODE == 1 + if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later +#endif + setValue(ret+i, curr, type); i += Runtime.getNativeTypeSize(type); } |