aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js8
-rw-r--r--src/parseTools.js12
-rwxr-xr-xtests/runner.py42
3 files changed, 58 insertions, 4 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 21ffa7e9..b3701112 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1046,10 +1046,14 @@ function JSify(data, functionsOnly, givenFunctions) {
makeFuncLineActor('mathop', processMathop);
makeFuncLineActor('bitcast', function(item) {
- return processMathop({
+ var temp = {
op: 'bitcast', variant: null, type: item.type,
+ assignTo: item.assignTo,
param1: item.params[0]
- });
+ };
+ var ret = processMathop(temp);
+ if (!temp.assignTo) item.assignTo = null; // If the assign was stolen, propagate that
+ return ret;
});
function makeFunctionCall(ident, params, funcData, type) {
diff --git a/src/parseTools.js b/src/parseTools.js
index 5a92335e..d3cb7795 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1699,9 +1699,17 @@ function processMathop(item) {
var inType = item.param1.type;
var outType = item.type;
if (inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) {
- return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', ident1, 'tempI64');
+ if (legalizedI64s) {
+ return '(tempDoubleI32[0]=' + ident1 + '$0, tempDoubleI32[1]=' + ident1 + '$1, tempDoubleF64[0])';
+ } else {
+ return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', ident1, 'tempI64');
+ }
} else if (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES) {
- return '(tempDoubleF64[0]=' + ident1 + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ if (legalizedI64s) {
+ return 'tempDoubleF64[0]=' + ident1 + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']);
+ } else {
+ return '(tempDoubleF64[0]=' + ident1 + ',[tempDoubleI32[0],tempDoubleI32[1]])';
+ }
} else {
throw 'Invalid I64_MODE1 bitcast: ' + dump(item) + ' : ' + item.param1.type;
}
diff --git a/tests/runner.py b/tests/runner.py
index 217a34bf..4db17431 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -702,6 +702,48 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
self.do_run(src, '*1,1,0,0,1,0*\n')
+ def test_i64_double(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2')
+ src = r'''
+ #include <stdio.h>
+
+ typedef long long int64;
+ #define JSDOUBLE_HI32_SIGNBIT 0x80000000
+
+ bool JSDOUBLE_IS_NEGZERO(double d)
+ {
+ union {
+ struct {
+ unsigned int lo, hi;
+ } s;
+ double d;
+ } x;
+ if (d != 0)
+ return false;
+ x.d = d;
+ return (x.s.hi & JSDOUBLE_HI32_SIGNBIT) != 0;
+ }
+
+ bool JSINT64_IS_NEGZERO(int64 l)
+ {
+ union {
+ int64 i;
+ double d;
+ } x;
+ if (l != 0)
+ return false;
+ x.i = l;
+ return x.d == -0;
+ }
+
+ int main(int argc, char * argv[]) {
+ printf("*%d,%d,%d,%d*\n", JSDOUBLE_IS_NEGZERO(0), JSDOUBLE_IS_NEGZERO(-0), JSDOUBLE_IS_NEGZERO(-1), JSDOUBLE_IS_NEGZERO(+1));
+ printf("*%d,%d,%d,%d*\n", JSINT64_IS_NEGZERO(0), JSINT64_IS_NEGZERO(-0), JSINT64_IS_NEGZERO(-1), JSINT64_IS_NEGZERO(+1));
+ return 0;
+ }
+ '''
+ self.do_run(src, '*0,0,0,0*\n*1,1,0,0*\n') # same as gcc
+
def test_unaligned(self):
if Settings.QUANTUM_SIZE == 1: return self.skip('No meaning to unaligned addresses in q1')