aboutsummaryrefslogtreecommitdiff
path: root/src/parseTools.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/parseTools.js')
-rw-r--r--src/parseTools.js264
1 files changed, 194 insertions, 70 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index b2093da3..1ef09f49 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -128,16 +128,48 @@ function isStructType(type) {
return type[0] == '%';
}
+function isStructuralType(type) {
+ return /^{ ?[^}]* ?}$/.test(type); // { i32, i8 } etc. - anonymous struct types
+}
+
+function getStructuralTypeParts(type) { // split { i32, i8 } etc. into parts
+ return type.replace(/[ {}]/g, '').split(',');
+}
+
+function getStructureTypeParts(type) {
+ if (isStructuralType(type)) {
+ return type.replace(/[ {}]/g, '').split(',');
+ } else {
+ var typeData = Types.types[type];
+ assert(typeData, type);
+ return typeData.fields;
+ }
+}
+
+function getStructuralTypePartBits(part) {
+ return Math.ceil((getBits(part) || 32)/32)*32; // simple 32-bit alignment. || 32 is for pointers
+}
+
function isIntImplemented(type) {
return type[0] == 'i' || isPointerType(type);
}
-// Note: works for iX types, not pointers (even though they are implemented as ints)
+// Note: works for iX types and structure types, not pointers (even though they are implemented as ints)
function getBits(type) {
- if (!type || type[0] != 'i') return 0;
- var left = type.substr(1);
- if (!isNumber(left)) return 0;
- return parseInt(left);
+ if (!type) return 0;
+ if (type[0] == 'i') {
+ var left = type.substr(1);
+ if (!isNumber(left)) return 0;
+ return parseInt(left);
+ }
+ if (isStructuralType(type)) {
+ return sum(getStructuralTypeParts(type).map(getStructuralTypePartBits));
+ }
+ if (isStructType(type)) {
+ var typeData = Types.types[type];
+ return typeData.flatSize*8;
+ }
+ return 0;
}
function isIllegalType(type) {
@@ -163,11 +195,13 @@ function isFunctionDef(token, out) {
var subtext = segment[0].text;
fail = fail || segment.length > 1 || !(isType(subtext) || subtext == '...');
});
- if (out) out.numArgs = segments.length;
+ if (out) {
+ out.segments = segments;
+ out.numArgs = segments.length;
+ }
return !fail;
}
-
function isPossiblyFunctionType(type) {
// A quick but unreliable way to see if something is a function type. Yes is just 'maybe', no is definite.
var len = type.length;
@@ -189,6 +223,7 @@ function isFunctionType(type, out) {
if (pointingLevels(type) !== 1) return false;
var text = removeAllPointing(parts.slice(1).join(' '));
if (!text) return false;
+ if (out) out.returnType = parts[0];
return isType(parts[0]) && isFunctionDef({ text: text, item: tokenize(text.substr(1, text.length-2), true) }, out);
}
@@ -310,7 +345,9 @@ function parseParamTokens(params) {
if (segment.length == 1) {
if (segment[0].text == '...') {
ret.push({
- intertype: 'varargs'
+ intertype: 'varargs',
+ type: 'i8*',
+ ident: 'varrp' // the conventional name we have for this
});
} else {
// Clang sometimes has a parameter with just a type,
@@ -360,25 +397,31 @@ var UNINDEXABLE_GLOBALS = set(
'_llvm_global_ctors' // special-cased
);
-function noticePtr(ptr) {
- if (!NAMED_GLOBALS && !LibraryManager.loaded) UNINDEXABLE_GLOBALS[ptr] = 1; // we cannot index globals referred to in the library, since they are used there by name
-}
-
function isIndexableGlobal(ident) {
if (!(ident in Variables.globals)) return false;
if (ident in UNINDEXABLE_GLOBALS) return false;
var data = Variables.globals[ident];
- return !data.alias && !data.external;
+ // in asm.js, externals are just globals
+ return !data.alias && (ASM_JS || !data.external);
}
function makeGlobalDef(ident) {
if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return '';
- return 'var ' + ident + ';'; // TODO: add option for namespacing or offsetting to allow reducing the number of globals
+ return 'var ' + ident + ';';
}
function makeGlobalUse(ident) {
- if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return '(' + getFastValue('GLOBAL_BASE', '+', Variables.indexedGlobals[ident]) + ')';
- return ident; // TODO: add option for namespacing or offsetting to allow reducing the number of globals
+ if (!NAMED_GLOBALS && isIndexableGlobal(ident)) {
+ var index = Variables.indexedGlobals[ident];
+ if (index === undefined) {
+ // we are accessing this before we index globals, likely from the library. mark as unindexable
+ UNINDEXABLE_GLOBALS[ident] = 1;
+ return ident;
+ }
+ // We know and assert on TOTAL_STACK being equal to GLOBAL_BASE
+ return (TOTAL_STACK + index).toString();
+ }
+ return ident;
}
function sortGlobals(globals) {
@@ -922,6 +965,12 @@ function checkSafeHeap() {
return SAFE_HEAP === 1 || checkSpecificSafeHeap();
}
+if (ASM_JS) {
+ var hexMemoryMask = '0x' + (TOTAL_MEMORY-1).toString(16);
+ var decMemoryMask = (TOTAL_MEMORY-1).toString();
+ var memoryMask = hexMemoryMask.length <= decMemoryMask.length ? hexMemoryMask : decMemoryMask;
+}
+
function getHeapOffset(offset, type) {
if (USE_TYPED_ARRAYS !== 2) {
return offset;
@@ -930,17 +979,44 @@ function getHeapOffset(offset, type) {
type = 'i32'; // XXX we emulate 64-bit values as 32
}
var shifts = Math.log(Runtime.getNativeTypeSize(type))/Math.LN2;
+ offset = '(' + offset + ')';
+ if (ASM_JS && phase == 'funcs') offset = '(' + offset + '&' + memoryMask + ')';
if (shifts != 0) {
- return '((' + offset + ')>>' + (shifts) + ')';
+ return '(' + offset + '>>' + shifts + ')';
} else {
- return '(' + offset + ')';
+ return offset;
}
}
}
+function makeVarDef(js) {
+ if (!ASM_JS) js = 'var ' + js;
+ return js;
+}
+
+function asmInitializer(type, impl) {
+ if (isIntImplemented(type)) {// || (impl && impl == 'VAR_EMULATED')) {
+ return '0';
+ } else {
+ return '+0';
+ }
+}
+
+function asmCoercion(value, type) {
+ if (!ASM_JS) return value;
+ if (isIntImplemented(type)) {
+ return '((' + value + ')|0)';
+ } else {
+ return '(+(' + value + '))';
+ }
+}
+
+function makeGetTempDouble(i) {
+ return makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32')*i, 'i32');
+}
+
// See makeSetValue
function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSafe) {
- noticePtr(ptr);
if (UNALIGNED_MEMORY) align = 1;
if (isStructType(type)) {
var typeData = Types.types[type];
@@ -952,9 +1028,9 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
}
if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') {
- return '(tempDoubleI32[0]=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, unsigned, ignore, align) + ',' +
- 'tempDoubleI32[1]=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, unsigned, ignore, align) + ',' +
- 'tempDoubleF64[0])';
+ return '(HEAP32[tempDoublePtr>>2]=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, unsigned, ignore, align) + ',' +
+ 'HEAP32[tempDoublePtr+4>>2]=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, unsigned, ignore, align) + ',' +
+ 'HEAPF64[tempDoublePtr>>3])';
}
if (USE_TYPED_ARRAYS == 2 && align) {
@@ -977,9 +1053,9 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
}
} else {
if (type == 'float') {
- ret += 'copyTempFloat(' + getFastValue(ptr, '+', pos) + '),tempDoubleF32[0]';
+ ret += 'copyTempFloat(' + getFastValue(ptr, '+', pos) + '),HEAPF32[tempDoublePtr>>2]';
} else {
- ret += 'copyTempDouble(' + getFastValue(ptr, '+', pos) + '),tempDoubleF64[0]';
+ ret += 'copyTempDouble(' + getFastValue(ptr, '+', pos) + '),HEAP64[tempDoublePtr>>3]';
}
}
ret += ')';
@@ -993,14 +1069,24 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
if (type[0] === '#') type = type.substr(1);
return 'SAFE_HEAP_LOAD(' + offset + ', ' + type + ', ' + (!!unsigned+0) + ', ' + ((!checkSafeHeap() || ignore)|0) + ')';
} else {
- return makeGetSlabs(ptr, type, false, unsigned)[0] + '[' + getHeapOffset(offset, type) + ']';
+ var ret = makeGetSlabs(ptr, type, false, unsigned)[0] + '[' + getHeapOffset(offset, type) + ']';
+ if (ASM_JS && phase == 'funcs') {
+ ret = asmCoercion(ret, type);
+ }
+ return ret;
}
}
function indexizeFunctions(value, type) {
assert((type && type !== '?') || (typeof value === 'string' && value.substr(0, 6) === 'CHECK_'), 'No type given for function indexizing');
assert(value !== type, 'Type set to value');
- if (type && isFunctionType(type) && value[0] === '_') { // checking for _ differentiates from $ (local vars)
+ var out = {};
+ if (type && isFunctionType(type, out) && value[0] === '_') { // checking for _ differentiates from $ (local vars)
+ // add signature to library functions that we now know need indexing
+ if (!(value in Functions.implementedFunctions) && !(value in Functions.unimplementedFunctions)) {
+ Functions.unimplementedFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : []);
+ }
+
if (BUILD_AS_SHARED_LIB) {
return '(FUNCTION_TABLE_OFFSET + ' + Functions.getIndex(value) + ')';
} else {
@@ -1021,7 +1107,6 @@ function indexizeFunctions(value, type) {
//! which means we should write to all slabs, ignore type differences if any on reads, etc.
//! @param noNeedFirst Whether to ignore the offset in the pointer itself.
function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, sep, forcedAlign) {
- noticePtr(ptr);
if (UNALIGNED_MEMORY && !forcedAlign) align = 1;
sep = sep || ';';
if (isStructType(type)) {
@@ -1039,9 +1124,9 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe,
}
if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') {
- return '(tempDoubleF64[0]=' + value + ',' +
- makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' +
- makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')';
+ return '(HEAPF64[tempDoublePtr>>3]=' + value + ',' +
+ makeSetValue(ptr, pos, 'HEAP32[tempDoublePtr>>2]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' +
+ makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'HEAP32[tempDoublePtr+4>>2]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')';
} else if (USE_TYPED_ARRAYS == 2 && type == 'i64') {
return '(tempI64 = [' + splitI64(value) + '],' +
makeSetValue(ptr, pos, 'tempI64[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' +
@@ -1093,7 +1178,6 @@ var SEEK_OPTIMAL_ALIGN_MIN = 20;
var UNROLL_LOOP_MAX = 8;
function makeSetValues(ptr, pos, value, type, num, align) {
- noticePtr(ptr);
function unroll(type, num, jump, value$) {
jump = jump || 1;
value$ = value$ || value;
@@ -1125,7 +1209,7 @@ function makeSetValues(ptr, pos, value, type, num, align) {
[4, 2, 1].forEach(function(possibleAlign) {
if (num == 0) return;
if (align >= possibleAlign) {
- if (num <= UNROLL_LOOP_MAX*possibleAlign) {
+ if (num <= UNROLL_LOOP_MAX*possibleAlign || ASM_JS) { // XXX test asm performance
ret.push(unroll('i' + (possibleAlign*8), Math.floor(num/possibleAlign), possibleAlign, values[possibleAlign]));
} else {
ret.push('for (var $$dest = ' + getFastValue(ptr, '+', pos) + (possibleAlign > 1 ? '>>' + log2(possibleAlign) : '') + ', ' +
@@ -1143,8 +1227,6 @@ function makeSetValues(ptr, pos, value, type, num, align) {
var TYPED_ARRAY_SET_MIN = Infinity; // .set() as memcpy seems to just slow us down
function makeCopyValues(dest, src, num, type, modifier, align, sep) {
- noticePtr(dest);
- noticePtr(src);
sep = sep || ';';
function unroll(type, num, jump) {
jump = jump || 1;
@@ -1179,7 +1261,7 @@ function makeCopyValues(dest, src, num, type, modifier, align, sep) {
if (num == 0) return;
if (align >= possibleAlign) {
// If we can unroll the loop, do so. Also do so if we must unroll it (we do not create real loops when inlined)
- if (num <= UNROLL_LOOP_MAX*possibleAlign || sep == ',') {
+ if (num <= UNROLL_LOOP_MAX*possibleAlign || sep == ',' || ASM_JS) { // XXX test asm performance
ret.push(unroll('i' + (possibleAlign*8), Math.floor(num/possibleAlign), possibleAlign));
} else {
assert(sep == ';');
@@ -1509,8 +1591,35 @@ function handleOverflow(text, bits) {
}
}
-function makeLLVMStruct(values) { // TODO: Use this everywhere
- return '{ ' + values.map(function(value, i) { return 'f' + i + ': ' + value }).join(', ') + ' }'
+function makeLLVMStruct(values) {
+ if (USE_TYPED_ARRAYS == 2) {
+ return 'DEPRECATED' + (new Error().stack) + 'XXX';
+ } else {
+ return '{ ' + values.map(function(value, i) { return 'f' + i + ': ' + value }).join(', ') + ' }'
+ }
+}
+
+function makeStructuralReturn(values) {
+ if (USE_TYPED_ARRAYS == 2) {
+ var i = 0;
+ return 'return (' + values.slice(1).map(function(value) {
+ return ASM_JS ? 'asm.setTempRet' + (i++) + '(' + value + ')'
+ : 'tempRet' + (i++) + ' = ' + value;
+ }).concat([values[0]]).join(',') + ')';
+ } else {
+ var i = 0;
+ return 'return { ' + values.map(function(value) {
+ return 'f' + (i++) + ': ' + value;
+ }).join(', ') + ' }';
+ }
+}
+
+function makeStructuralAccess(ident, i) {
+ if (USE_TYPED_ARRAYS == 2) {
+ return ident + '$' + i;
+ } else {
+ return ident + '.f' + i;
+ }
}
// From parseLLVMSegment
@@ -1619,30 +1728,36 @@ function makeSignOp(value, type, op, force, ignore) {
function makeRounding(value, bits, signed, floatConversion) {
// TODO: handle roundings of i64s
assert(bits);
- // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that.
- if (bits <= 32 && signed) return '((' + value + ')&-1)'; // This is fast and even correct, for all cases. Note that it is the same
- // as |0, but &-1 hints to the js optimizer that this is a rounding correction
- // Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure
- // the value is non-negative
- if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')';
- // We are left with >32 bits signed, or a float conversion. Check and correct inline
- // Note that if converting a float, we may have the wrong sign at this point! But, we have
- // been rounded properly regardless, and we will be sign-corrected later when actually used, if
- // necessary.
- return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
-/* refactored version - needs perf testing TODO
- if (bits <= 32) {
- if (signed) {
- return '((' + value + ')&-1)'; // &-1 (instead of |0) hints to the js optimizer that this is a rounding correction
- } else {
- return '((' + value + ')>>>0)';
+ if (!ASM_JS) {
+ // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that.
+ if (bits <= 32 && signed) return '((' + value + ')&-1)'; // This is fast and even correct, for all cases. Note that it is the same
+ // as |0, but &-1 hints to the js optimizer that this is a rounding correction
+ // Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure
+ // the value is non-negative
+ if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')';
+ // We are left with >32 bits signed, or a float conversion. Check and correct inline
+ // Note that if converting a float, we may have the wrong sign at this point! But, we have
+ // been rounded properly regardless, and we will be sign-corrected later when actually used, if
+ // necessary.
+ return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
+ } else {
+ // asm.js mode, cleaner refactoring of this function as well. TODO: use in non-asm case, most of this
+ if (floatConversion && bits <= 32) {
+ return '(~~(' + value + '))'; // explicit float-to-int conversion
+ }
+
+ if (bits <= 32) {
+ if (signed) {
+ return '((' + value + ')&-1)'; // &-1 (instead of |0) hints to the js optimizer that this is a rounding correction
+ } else {
+ return '((' + value + ')>>>0)';
+ }
}
+ // Math.floor is reasonably fast if we don't care about corrections (and even correct if unsigned)
+ if (!correctRoundings() || !signed) return 'Math.floor(' + value + ')';
+ // We are left with >32 bits
+ return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
}
- // Math.floor is reasonably fast if we don't care about corrections (and even correct if unsigned)
- if (!correctRoundings() || !signed) return 'Math.floor(' + value + ')';
- // We are left with >32 bits
- return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR');
-*/
}
// fptoui and fptosi are not in these, because we need to be careful about what we do there. We can't
@@ -1716,8 +1831,8 @@ function processMathop(item) {
}
function i64PreciseOp(type, lastArg) {
Types.preciseI64MathUsed = true;
- return finish(['(i64Math.' + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 +
- (lastArg ? ',' + lastArg : '') + '),i64Math.result[0])', 'i64Math.result[1]']);
+ return finish(['(i64Math' + (ASM_JS ? '_' : '.') + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 +
+ (lastArg ? ',' + lastArg : '') + '),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')', makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32'), 'i32')]);
}
switch (op) {
// basic integer ops
@@ -1734,7 +1849,8 @@ function processMathop(item) {
case 'ashr':
case 'lshr': {
if (!isNumber(idents[1])) {
- return 'Runtime.bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0)';
+ return '(Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0),' +
+ '[' + makeGetTempDouble(0) + ',' + makeGetTempDouble(1) + '])';
}
bits = parseInt(idents[1]);
var ander = Math.pow(2, bits)-1;
@@ -1851,15 +1967,15 @@ function processMathop(item) {
var outType = item.type;
if (inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) {
if (legalizedI64s) {
- return '(tempDoubleI32[0]=' + idents[0] + '$0, tempDoubleI32[1]=' + idents[0] + '$1, tempDoubleF64[0])';
+ return '(HEAP32[tempDoublePtr>>2]=' + idents[0] + '$0, HEAP32[tempDoublePtr+4>>2]=' + idents[0] + '$1, HEAPF64[tempDoublePtr>>3])';
} else {
- return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', idents[0], 'tempI64');
+ return makeInlineCalculation('HEAP32[tempDoublePtr>>2]=VALUE[0],HEAP32[tempDoublePtr+4>>2]=VALUE[1],HEAPF64[tempDoublePtr>>>3]', idents[0], 'tempI64');
}
} else if (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES) {
if (legalizedI64s) {
- return 'tempDoubleF64[0]=' + idents[0] + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']);
+ return 'HEAPF64[tempDoublePtr>>3]=' + idents[0] + '; ' + finish(['HEAP32[tempDoublePtr>>2]','HEAP32[tempDoublePtr+4>>2]']);
} else {
- return '(tempDoubleF64[0]=' + idents[0] + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ return '(HEAPF64[tempDoublePtr>>3]=' + idents[0] + ',[HEAP32[tempDoublePtr>>2],HEAP32[tempDoublePtr+4>>2]])';
}
} else {
throw 'Invalid USE_TYPED_ARRAYS == 2 bitcast: ' + dump(item) + ' : ' + item.params[0].type;
@@ -1877,8 +1993,16 @@ function processMathop(item) {
case 'mul': {
if (bits == 32 && PRECISE_I32_MUL) {
Types.preciseI64MathUsed = true;
- return '(i64Math.multiply(' + idents[0] + ',0,' + idents[1] + ',0),i64Math.result[0])';
+ return '(i64Math' + (ASM_JS ? '_' : '.') + 'multiply(' + idents[0] + ',0,' + idents[1] + ',0),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')';
} else {
+ if (ASM_JS) {
+ // special-case: there is no integer multiply in asm, because there is no true integer
+ // multiply in JS. While we wait for Math.imul, do double multiply
+ if (USE_MATH_IMUL) {
+ return 'Math.imul(' + idents[0] + ',' + idents[1] + ')';
+ }
+ return '(~~(+' + idents[0] + ' * +' + idents[1] + '))';
+ }
return handleOverflow(getFastValue(idents[0], '*', idents[1], item.type), bits);
}
}
@@ -1927,7 +2051,7 @@ function processMathop(item) {
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 'uitofp': case 'sitofp': return idents[0];
+ case 'uitofp': case 'sitofp': return asmCoercion(idents[0], 'double');
case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true);
// TODO: We sometimes generate false instead of 0, etc., in the *cmps. It seemed slightly faster before, but worth rechecking
@@ -1998,9 +2122,9 @@ function processMathop(item) {
(inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES)) {
assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2');
if (inType in Runtime.INT_TYPES) {
- return '(tempDoubleI32[0] = ' + idents[0] + ',tempDoubleF32[0])';
+ return '(HEAP32[tempDoublePtr>>2] = ' + idents[0] + ',HEAPF32[tempDoublePtr>>2])';
} else {
- return '(tempDoubleF32[0] = ' + idents[0] + ',tempDoubleI32[0])';
+ return '(HEAPF32[tempDoublePtr>>2] = ' + idents[0] + ',HEAP32[tempDoublePtr>>2])';
}
}
return idents[0];