diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-17 21:26:11 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-17 21:26:11 -0800 |
commit | ea0015403b3695d873a2c7eabc6fcdf0641b8e2e (patch) | |
tree | d0ab35da49e6ff1e47ceb730e86068dc7a555746 | |
parent | 65db7e5e8f3994a7d4ca1b4e01f87eef13c7c87b (diff) | |
download | binaryen-ea0015403b3695d873a2c7eabc6fcdf0641b8e2e.tar.gz binaryen-ea0015403b3695d873a2c7eabc6fcdf0641b8e2e.tar.bz2 binaryen-ea0015403b3695d873a2c7eabc6fcdf0641b8e2e.zip |
fround improvements
-rw-r--r-- | src/asm2wasm.h | 35 | ||||
-rw-r--r-- | test/unit.asm.js | 11 | ||||
-rw-r--r-- | test/unit.wast | 14 |
3 files changed, 58 insertions, 2 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 08f4e4141..3d430d712 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -334,10 +334,13 @@ private: std::map<unsigned, Ref> tempNums; - Literal getLiteral(Ref ast) { + Literal checkLiteral(Ref ast) { if (ast[0] == NUM) { return Literal((int32_t)ast[1]->getInteger()); } else if (ast[0] == UNARY_PREFIX) { + if (ast[1] == PLUS && ast[2][0] == NUM) { + return Literal((double)ast[2][1]->getNumber()); + } if (ast[1] == MINUS && ast[2][0] == NUM) { double num = -ast[2][1]->getNumber(); assert(isInteger32(num)); @@ -347,7 +350,13 @@ private: return Literal((double)-ast[2][2][1]->getNumber()); } } - abort(); + return Literal(); + } + + Literal getLiteral(Ref ast) { + Literal ret = checkLiteral(ast); + if (ret.type == none) abort(); + return ret; } Function* processFunction(Ref ast); @@ -880,6 +889,28 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->type = WasmType::i32; return ret; } + if (name == Math_fround) { + assert(ast[2]->size() == 1); + Literal lit = checkLiteral(ast[2][0]); + if (lit.type == i32) { + return allocator.alloc<Const>()->set(Literal((float)lit.geti32())); + } else if (lit.type == f64) { + return allocator.alloc<Const>()->set(Literal((float)lit.getf64())); + } + auto ret = allocator.alloc<Convert>(); + ret->value = process(ast[2][0]); + if (ret->value->type == f64) { + ret->op = DemoteFloat64; + } else if (ret->value->type == i32) { + ret->op = ConvertSInt32; + } else if (ret->value->type == f32) { + return ret->value; + } else { + abort_on("confusing fround target", ast[2][0]); + } + ret->type = WasmType::f32; + return ret; + } Call* ret; if (wasm.importsMap.find(name) != wasm.importsMap.end()) { Ref parent = astStackHelper.getParent(); diff --git a/test/unit.asm.js b/test/unit.asm.js index 77e2c5585..5695c3059 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -4,6 +4,7 @@ function () { var t = global.NaN, u = global.Infinity; var Int = 0; var Double = 0.0; + var Math_fround = global.Math.fround; function big_negative() { var temp = 0.0; @@ -64,6 +65,16 @@ function () { x = (4294967295 / 2)&-1; return x | 0; } + function fr(x) { + x = Math_fround(x); + var y = Math_fround(0), z = 0.0; + Math_fround(z); + Math_fround(y); + Math_fround(5); + Math_fround(0); + Math_fround(5.0); + Math_fround(0.0); + } function z() { } diff --git a/test/unit.wast b/test/unit.wast index 34dea557f..24692ba1c 100644 --- a/test/unit.wast +++ b/test/unit.wast @@ -233,6 +233,20 @@ (get_local $x) ) ) + (func $fr (param $x f32) + (local $y f32) + (local $z f64) + (block + (f32.demote/f64 + (get_local $z) + ) + (get_local $y) + (f32.const 5) + (f32.const 0) + (f32.const 5) + (f32.const 0) + ) + ) (func $z (nop) ) |