Title: [209476] trunk
Revision
209476
Author
keith_mil...@apple.com
Date
2016-12-07 13:43:58 -0800 (Wed, 07 Dec 2016)

Log Message

Add support for truncation operators
https://bugs.webkit.org/show_bug.cgi?id=165519

Reviewed by Geoffrey Garen.

JSTests:

* wasm/function-tests/i32-trunc-s-f32.js: Added.
* wasm/function-tests/i32-trunc-s-f64.js: Added.
* wasm/function-tests/i32-trunc-u-f32.js: Added.
* wasm/function-tests/i32-trunc-u-f64.js: Added.
* wasm/function-tests/i64-trunc-s-f32.js: Added.
* wasm/function-tests/i64-trunc-s-f64.js: Added.
* wasm/function-tests/i64-trunc-u-f32.js: Added.
* wasm/function-tests/i64-trunc-u-f64.js: Added.

Source/_javascript_Core:

This patch adds initial support for truncation operators. The current patch
does range based out of bounds checking, in the future we should use system
register flags on ARM and other tricks on X86 improve the performance of
these opcodes.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchTruncateDoubleToInt32):
(JSC::MacroAssemblerARM64::truncateDoubleToInt64):
(JSC::MacroAssemblerARM64::truncateDoubleToUint64):
(JSC::MacroAssemblerARM64::truncateFloatToInt32):
(JSC::MacroAssemblerARM64::truncateFloatToUint32):
(JSC::MacroAssemblerARM64::truncateFloatToInt64):
(JSC::MacroAssemblerARM64::truncateFloatToUint64):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::truncateFloatToInt32):
(JSC::MacroAssemblerX86Common::truncateDoubleToUint32): Deleted.
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::truncateDoubleToUint32):
(JSC::MacroAssemblerX86_64::truncateDoubleToInt64):
(JSC::MacroAssemblerX86_64::truncateDoubleToUint64):
(JSC::MacroAssemblerX86_64::truncateFloatToUint32):
(JSC::MacroAssemblerX86_64::truncateFloatToInt64):
(JSC::MacroAssemblerX86_64::truncateFloatToUint64):
* assembler/X86Assembler.h:
(JSC::X86Assembler::cvttss2si_rr):
(JSC::X86Assembler::cvttss2siq_rr):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF64>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF32>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF64>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF32>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF64>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF64>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF32>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF32>):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (209475 => 209476)


--- trunk/JSTests/ChangeLog	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/JSTests/ChangeLog	2016-12-07 21:43:58 UTC (rev 209476)
@@ -1,3 +1,19 @@
+2016-12-06  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for truncation operators
+        https://bugs.webkit.org/show_bug.cgi?id=165519
+
+        Reviewed by Geoffrey Garen.
+
+        * wasm/function-tests/i32-trunc-s-f32.js: Added.
+        * wasm/function-tests/i32-trunc-s-f64.js: Added.
+        * wasm/function-tests/i32-trunc-u-f32.js: Added.
+        * wasm/function-tests/i32-trunc-u-f64.js: Added.
+        * wasm/function-tests/i64-trunc-s-f32.js: Added.
+        * wasm/function-tests/i64-trunc-s-f64.js: Added.
+        * wasm/function-tests/i64-trunc-u-f32.js: Added.
+        * wasm/function-tests/i64-trunc-u-f64.js: Added.
+
 2016-12-06  Mark Lam  <mark....@apple.com>
 
         Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.

Added: trunk/JSTests/wasm/function-tests/i32-trunc-s-f32.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i32-trunc-s-f32.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i32-trunc-s-f32.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,31 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f32"], ret: "i32" }, [])
+    .GetLocal(0)
+    .I32TruncSF32()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i32", value: "0" }, [{ type: "f32", value: "0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "0x1p-149" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0x1p-149" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "1.0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "0x1.19999ap+0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "1.5" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f32", value: "-1.0" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f32", value: "-0x1.19999ap+0" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f32", value: "-1.5" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f32", value: "-1.9" }]],
+                         [{ type: "i32", value: "-2" }, [{ type: "f32", value: "-2.0" }]],
+                         [{ type: "i32", value: "2147483520" }, [{ type: "f32", value: "2147483520.0" }]],
+                         [{ type: "i32", value: "-2147483648" }, [{ type: "f32", value: "-2147483648.0" }]],
+                        ],
+
+                       );

Added: trunk/JSTests/wasm/function-tests/i32-trunc-s-f64.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i32-trunc-s-f64.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i32-trunc-s-f64.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,31 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f64"], ret: "i32" }, [])
+    .GetLocal(0)
+    .I32TruncSF64()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i32", value: "0" }, [{ type: "f64", value: "0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "0x0.0000000000001p-1022" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0x0.0000000000001p-1022" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "1.0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "0x1.199999999999ap+0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "1.5" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f64", value: "-1.0" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f64", value: "-0x1.199999999999ap+0" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f64", value: "-1.5" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f64", value: "-1.9" }]],
+                         [{ type: "i32", value: "-2" }, [{ type: "f64", value: "-2.0" }]],
+                         [{ type: "i32", value: "2147483647" }, [{ type: "f64", value: "2147483647.0" }]],
+                         [{ type: "i32", value: "-2147483648" }, [{ type: "f64", value: "-2147483648.0" }]],
+                        ],
+
+                       );

Added: trunk/JSTests/wasm/function-tests/i32-trunc-u-f32.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i32-trunc-u-f32.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i32-trunc-u-f32.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,29 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f32"], ret: "i32" }, [])
+    .GetLocal(0)
+    .I32TruncUF32()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i32", value: "0" }, [{ type: "f32", value: "0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "0x1p-149" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0x1p-149" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "1.0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "0x1.19999ap+0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "1.5" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f32", value: "1.9" }]],
+                         [{ type: "i32", value: "2" }, [{ type: "f32", value: "2.0" }]],
+                         [{ type: "i32", value: "-2147483648" }, [{ type: "f32", value: "2147483648" }]],
+                         [{ type: "i32", value: "-256" }, [{ type: "f32", value: "4294967040.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0x1.ccccccp-1" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f32", value: "-0x1.fffffep-1" }]],
+                        ],
+                       );

Added: trunk/JSTests/wasm/function-tests/i32-trunc-u-f64.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i32-trunc-u-f64.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i32-trunc-u-f64.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,30 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f64"], ret: "i32" }, [])
+    .GetLocal(0)
+    .I32TruncUF64()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i32", value: "0" }, [{ type: "f64", value: "0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "0x0.0000000000001p-1022" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0x0.0000000000001p-1022" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "1.0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "0x1.199999999999ap+0" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "1.5" }]],
+                         [{ type: "i32", value: "1" }, [{ type: "f64", value: "1.9" }]],
+                         [{ type: "i32", value: "2" }, [{ type: "f64", value: "2.0" }]],
+                         [{ type: "i32", value: "-2147483648" }, [{ type: "f64", value: "2147483648" }]],
+                         [{ type: "i32", value: "-1" }, [{ type: "f64", value: "4294967295.0" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0x1.ccccccccccccdp-1" }]],
+                         [{ type: "i32", value: "0" }, [{ type: "f64", value: "-0x1.fffffffffffffp-1" }]],
+                         [{ type: "i32", value: "100000000" }, [{ type: "f64", value: "1e8" }]],
+                        ],
+                       );

Added: trunk/JSTests/wasm/function-tests/i64-trunc-s-f32.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i64-trunc-s-f32.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i64-trunc-s-f32.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,33 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f32"], ret: "i64" }, [])
+    .GetLocal(0)
+    .I64TruncSF32()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i64", value: "0" }, [{ type: "f32", value: "0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "0x1p-149" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0x1p-149" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "1.0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "0x1.19999ap+0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "1.5" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f32", value: "-1.0" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f32", value: "-0x1.19999ap+0" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f32", value: "-1.5" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f32", value: "-1.9" }]],
+                         [{ type: "i64", value: "-2" }, [{ type: "f32", value: "-2.0" }]],
+                         [{ type: "i64", value: "4294967296" }, [{ type: "f32", value: "4294967296" }]],
+                         [{ type: "i64", value: "-4294967296" }, [{ type: "f32", value: "-4294967296" }]],
+                         [{ type: "i64", value: "9223371487098961920" }, [{ type: "f32", value: "9223371487098961920.0" }]],
+                         [{ type: "i64", value: "-9223372036854775808" }, [{ type: "f32", value: "-9223372036854775808.0" }]],
+                        ],
+
+                       );

Added: trunk/JSTests/wasm/function-tests/i64-trunc-s-f64.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i64-trunc-s-f64.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i64-trunc-s-f64.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,33 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f64"], ret: "i64" }, [])
+    .GetLocal(0)
+    .I64TruncSF64()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i64", value: "0" }, [{ type: "f64", value: "0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "0x0.0000000000001p-1022" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0x0.0000000000001p-1022" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "1.0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "0x1.199999999999ap+0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "1.5" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f64", value: "-1.0" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f64", value: "-0x1.199999999999ap+0" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f64", value: "-1.5" }]],
+                         [{ type: "i64", value: "-1" }, [{ type: "f64", value: "-1.9" }]],
+                         [{ type: "i64", value: "-2" }, [{ type: "f64", value: "-2.0" }]],
+                         [{ type: "i64", value: "4294967296" }, [{ type: "f64", value: "4294967296" }]],
+                         [{ type: "i64", value: "-4294967296" }, [{ type: "f64", value: "-4294967296" }]],
+                         [{ type: "i64", value: "9223372036854774784" }, [{ type: "f64", value: "9223372036854774784.0" }]],
+                         [{ type: "i64", value: "-9223372036854775808" }, [{ type: "f64", value: "-9223372036854775808.0" }]],
+                        ],
+
+                       );

Added: trunk/JSTests/wasm/function-tests/i64-trunc-u-f32.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i64-trunc-u-f32.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i64-trunc-u-f32.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,27 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f32"], ret: "i64" }, [])
+    .GetLocal(0)
+    .I64TruncUF32()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i64", value: "0" }, [{ type: "f32", value: "0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "0x1p-149" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0x1p-149" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "1.0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "0x1.19999ap+0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f32", value: "1.5" }]],
+                         [{ type: "i64", value: "4294967296" }, [{ type: "f32", value: "4294967296" }]],
+                         [{ type: "i64", value: "-1099511627776" }, [{ type: "f32", value: "18446742974197923840.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0x1.ccccccp-1" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f32", value: "-0x1.fffffep-1" }]],[{ type: "i64", value: "0" }, [{ type: "f32", value: "0.0" }]],
+                        ],
+                       );

Added: trunk/JSTests/wasm/function-tests/i64-trunc-u-f64.js (0 => 209476)


--- trunk/JSTests/wasm/function-tests/i64-trunc-u-f64.js	                        (rev 0)
+++ trunk/JSTests/wasm/function-tests/i64-trunc-u-f64.js	2016-12-07 21:43:58 UTC (rev 209476)
@@ -0,0 +1,32 @@
+import Builder from '../Builder.js'
+
+const b = new Builder();
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: ["f64"], ret: "i64" }, [])
+    .GetLocal(0)
+    .I64TruncUF64()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1,
+                        [[{ type: "i64", value: "0" }, [{ type: "f64", value: "0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "0x0.0000000000001p-1022" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0x0.0000000000001p-1022" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "1.0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "0x1.199999999999ap+0" }]],
+                         [{ type: "i64", value: "1" }, [{ type: "f64", value: "1.5" }]],
+                         [{ type: "i64", value: "0xffffffff" }, [{ type: "f64", value: "4294967295" }]],
+                         [{ type: "i64", value: "0x100000000" }, [{ type: "f64", value: "4294967296" }]],
+                         [{ type: "i64", value: "-2048" }, [{ type: "f64", value: "18446744073709549568.0" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0x1.ccccccccccccdp-1" }]],
+                         [{ type: "i64", value: "0" }, [{ type: "f64", value: "-0x1.fffffffffffffp-1" }]],
+                         [{ type: "i64", value: "100000000" }, [{ type: "f64", value: "1e8" }]],
+                         [{ type: "i64", value: "10000000000000000" }, [{ type: "f64", value: "1e16" }]],
+                         [{ type: "i64", value: "-9223372036854775808" }, [{ type: "f64", value: "9223372036854775808" }]],
+                        ],
+
+                       );

Modified: trunk/Source/_javascript_Core/ChangeLog (209475 => 209476)


--- trunk/Source/_javascript_Core/ChangeLog	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-12-07 21:43:58 UTC (rev 209476)
@@ -1,3 +1,48 @@
+2016-12-06  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for truncation operators
+        https://bugs.webkit.org/show_bug.cgi?id=165519
+
+        Reviewed by Geoffrey Garen.
+
+        This patch adds initial support for truncation operators. The current patch
+        does range based out of bounds checking, in the future we should use system
+        register flags on ARM and other tricks on X86 improve the performance of
+        these opcodes.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::branchTruncateDoubleToInt32):
+        (JSC::MacroAssemblerARM64::truncateDoubleToInt64):
+        (JSC::MacroAssemblerARM64::truncateDoubleToUint64):
+        (JSC::MacroAssemblerARM64::truncateFloatToInt32):
+        (JSC::MacroAssemblerARM64::truncateFloatToUint32):
+        (JSC::MacroAssemblerARM64::truncateFloatToInt64):
+        (JSC::MacroAssemblerARM64::truncateFloatToUint64):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::truncateFloatToInt32):
+        (JSC::MacroAssemblerX86Common::truncateDoubleToUint32): Deleted.
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::truncateDoubleToUint32):
+        (JSC::MacroAssemblerX86_64::truncateDoubleToInt64):
+        (JSC::MacroAssemblerX86_64::truncateDoubleToUint64):
+        (JSC::MacroAssemblerX86_64::truncateFloatToUint32):
+        (JSC::MacroAssemblerX86_64::truncateFloatToInt64):
+        (JSC::MacroAssemblerX86_64::truncateFloatToUint64):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::cvttss2si_rr):
+        (JSC::X86Assembler::cvttss2siq_rr):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF64>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF32>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF64>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF32>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF64>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF64>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF32>):
+        (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF32>):
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser<Context>::parseExpression):
+
 2016-12-07  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: Remove unused and mostly untested Page domain commands and events

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (209475 => 209476)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2016-12-07 21:43:58 UTC (rev 209476)
@@ -1655,7 +1655,7 @@
         // Truncate to a 64-bit integer in dataTempRegister, copy the low 32-bit to dest.
         m_assembler.fcvtzs<64, 64>(getCachedDataTempRegisterIDAndInvalidate(), src);
         zeroExtend32ToPtr(dataTempRegister, dest);
-        // Check thlow 32-bits sign extend to be equal to the full value.
+        // Check the low 32-bits sign extend to be equal to the full value.
         m_assembler.cmp<64>(dataTempRegister, dataTempRegister, ARM64Assembler::SXTW, 0);
         return Jump(makeBranch(branchType == BranchIfTruncateSuccessful ? Equal : NotEqual));
     }
@@ -2041,7 +2041,46 @@
         m_assembler.fcvtzu<32, 64>(dest, src);
     }
 
+    void truncateDoubleToInt64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzs<64, 64>(dest, src);
+    }
 
+    void truncateDoubleToUint64(FPRegisterID src, RegisterID dest, FPRegisterID, FPRegisterID)
+    {
+        truncateDoubleToUint64(src, dest);
+    }
+
+    void truncateDoubleToUint64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzu<64, 64>(dest, src);
+    }
+
+    void truncateFloatToInt32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzs<32, 32>(dest, src);
+    }
+
+    void truncateFloatToUint32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzu<32, 32>(dest, src);
+    }
+
+    void truncateFloatToInt64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzs<64, 32>(dest, src);
+    }
+
+    void truncateFloatToUint64(FPRegisterID src, RegisterID dest, FPRegisterID, FPRegisterID)
+    {
+        truncateFloatToUint64(src, dest);
+    }
+
+    void truncateFloatToUint64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.fcvtzu<64, 32>(dest, src);
+    }
+
     // Stack manipulation operations:
     //
     // The ABI is assumed to provide a stack abstraction to memory,

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (209475 => 209476)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2016-12-07 21:43:58 UTC (rev 209476)
@@ -1678,15 +1678,13 @@
         ASSERT(isSSE2Present());
         m_assembler.cvttsd2si_rr(src, dest);
     }
-    
-#if CPU(X86_64)
-    void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
+
+    void truncateFloatToInt32(FPRegisterID src, RegisterID dest)
     {
         ASSERT(isSSE2Present());
-        m_assembler.cvttsd2siq_rr(src, dest);
+        m_assembler.cvttss2si_rr(src, dest);
     }
-#endif
-    
+
     // Convert 'src' to an integer, and places the resulting 'dest'.
     // If the result is not representable as a 32 bit value, branch.
     // May also branch for some values that are representable in 32 bits

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (209475 => 209476)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2016-12-07 21:43:58 UTC (rev 209476)
@@ -1295,6 +1295,72 @@
         return MacroAssemblerX86Common::branchTest8(cond, Address(scratchRegister()), mask8);
     }
 
+    void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.cvttsd2siq_rr(src, dest);
+    }
+
+    void truncateDoubleToInt64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.cvttsd2siq_rr(src, dest);
+    }
+
+    // int64Min should contain exactly 0x43E0000000000000 == static_cast<double>(int64_t::min()). scratch may
+    // be the same FPR as src.
+    void truncateDoubleToUint64(FPRegisterID src, RegisterID dest, FPRegisterID scratch, FPRegisterID int64Min)
+    {
+        ASSERT(scratch != int64Min);
+
+        // Since X86 does not have a floating point to unsigned integer instruction, we need to use the signed
+        // integer conversion instruction. If the src is less than int64_t::min() then the results of the two
+        // instructions are the same. Otherwise, we need to: subtract int64_t::min(); truncate double to
+        // uint64_t; then add back int64_t::min() in the destination gpr.
+
+        Jump large = branchDouble(DoubleGreaterThanOrEqual, src, int64Min);
+        m_assembler.cvttsd2siq_rr(src, dest);
+        Jump done = jump();
+        large.link(this);
+        moveDouble(src, scratch);
+        m_assembler.subsd_rr(int64Min, scratch);
+        m_assembler.movq_i64r(0x8000000000000000, scratchRegister());
+        m_assembler.cvttsd2siq_rr(scratch, dest);
+        m_assembler.orq_rr(scratchRegister(), dest);
+        done.link(this);
+    }
+
+    void truncateFloatToUint32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.cvttss2siq_rr(src, dest);
+    }
+
+    void truncateFloatToInt64(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.cvttss2siq_rr(src, dest);
+    }
+
+    // int64Min should contain exactly 0x5f000000 == static_cast<float>(int64_t::min()). scratch may be the
+    // same FPR as src.
+    void truncateFloatToUint64(FPRegisterID src, RegisterID dest, FPRegisterID scratch, FPRegisterID int64Min)
+    {
+        ASSERT(scratch != int64Min);
+
+        // Since X86 does not have a floating point to unsigned integer instruction, we need to use the signed
+        // integer conversion instruction. If the src is less than int64_t::min() then the results of the two
+        // instructions are the same. Otherwise, we need to: subtract int64_t::min(); truncate double to
+        // uint64_t; then add back int64_t::min() in the destination gpr.
+
+        Jump large = branchFloat(DoubleGreaterThanOrEqual, src, int64Min);
+        m_assembler.cvttss2siq_rr(src, dest);
+        Jump done = jump();
+        large.link(this);
+        moveDouble(src, scratch);
+        m_assembler.subss_rr(int64Min, scratch);
+        m_assembler.movq_i64r(0x8000000000000000, scratchRegister());
+        m_assembler.cvttss2siq_rr(scratch, dest);
+        m_assembler.orq_rr(scratchRegister(), dest);
+        done.link(this);
+    }
+
     void convertInt64ToDouble(RegisterID src, FPRegisterID dest)
     {
         m_assembler.cvtsi2sdq_rr(src, dest);

Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (209475 => 209476)


--- trunk/Source/_javascript_Core/assembler/X86Assembler.h	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h	2016-12-07 21:43:58 UTC (rev 209476)
@@ -267,6 +267,7 @@
         OP2_MOVAPS_VpdWpd   = 0x28,
         OP2_CVTSI2SD_VsdEd  = 0x2A,
         OP2_CVTTSD2SI_GdWsd = 0x2C,
+        OP2_CVTTSS2SI_GdWsd = 0x2C,
         OP2_UCOMISD_VsdWsd  = 0x2E,
         OP2_3BYTE_ESCAPE_3A = 0x3A,
         OP2_CMOVCC          = 0x40,
@@ -2293,6 +2294,20 @@
         m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
     }
 
+    void cvttss2si_rr(XMMRegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_CVTTSS2SI_GdWsd, dst, (RegisterID)src);
+    }
+
+#if CPU(X86_64)
+    void cvttss2siq_rr(XMMRegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp64(OP2_CVTTSS2SI_GdWsd, dst, (RegisterID)src);
+    }
+#endif
+
     void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_F2);

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (209475 => 209476)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2016-12-07 21:43:58 UTC (rev 209476)
@@ -905,6 +905,229 @@
     return true;
 }
 
+template<>
+bool B3IRGenerator::addOp<OpType::I32TruncSF64>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), -static_cast<double>(std::numeric_limits<int32_t>::min()));
+    Value* min = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), static_cast<double>(std::numeric_limits<int32_t>::min()));
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterEqual, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int32, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateDoubleToInt32(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I32TruncSF32>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), -static_cast<float>(std::numeric_limits<int32_t>::min()));
+    Value* min = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), static_cast<float>(std::numeric_limits<int32_t>::min()));
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterEqual, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int32, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateFloatToInt32(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+
+template<>
+bool B3IRGenerator::addOp<OpType::I32TruncUF64>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), static_cast<double>(std::numeric_limits<int32_t>::min()) * -2.0);
+    Value* min = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), -1.0);
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterThan, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int32, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateDoubleToUint32(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I32TruncUF32>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), static_cast<float>(std::numeric_limits<int32_t>::min()) * -2.0);
+    Value* min = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), -1.0);
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterThan, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int32, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateFloatToUint32(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I64TruncSF64>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), -static_cast<double>(std::numeric_limits<int64_t>::min()));
+    Value* min = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), static_cast<double>(std::numeric_limits<int64_t>::min()));
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterEqual, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int64, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateDoubleToInt64(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I64TruncUF64>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), static_cast<double>(std::numeric_limits<int64_t>::min()) * -2.0);
+    Value* min = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), -1.0);
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterThan, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+
+    Value* constant;
+    if (isX86()) {
+        // Since x86 doesn't have an instruction to convert floating points to unsigned integers, we at least try to do the smart thing if
+        // the numbers are would be positive anyway as a signed integer. Since we cannot materialize constants into fprs we have b3 do it
+        // so we can pool them if needed.
+        constant = m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), static_cast<double>(std::numeric_limits<uint64_t>::max() - std::numeric_limits<int64_t>::max()));
+    }
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int64, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    if (isX86()) {
+        patchpoint->append(constant, ValueRep::SomeRegister);
+        patchpoint->numFPScratchRegisters = 1;
+    }
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        AllowMacroScratchRegisterUsage allowScratch(jit);
+        FPRReg scratch = InvalidFPRReg;
+        FPRReg constant = InvalidFPRReg;
+        if (isX86()) {
+            scratch = params.fpScratch(0);
+            constant = params[2].fpr();
+        }
+        jit.truncateDoubleToUint64(params[1].fpr(), params[0].gpr(), scratch, constant);
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I64TruncSF32>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), -static_cast<float>(std::numeric_limits<int64_t>::min()));
+    Value* min = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), static_cast<float>(std::numeric_limits<int64_t>::min()));
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterEqual, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int64, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        jit.truncateFloatToInt64(params[1].fpr(), params[0].gpr());
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
+template<>
+bool B3IRGenerator::addOp<OpType::I64TruncUF32>(ExpressionType arg, ExpressionType& result)
+{
+    Value* max = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), static_cast<float>(std::numeric_limits<int64_t>::min()) * -2.0);
+    Value* min = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), -1.0);
+    Value* outOfBounds = m_currentBlock->appendNew<Value>(m_proc, BitAnd, Origin(),
+        m_currentBlock->appendNew<Value>(m_proc, LessThan, Origin(), arg, max),
+        m_currentBlock->appendNew<Value>(m_proc, GreaterThan, Origin(), arg, min));
+    outOfBounds = m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), outOfBounds, zeroForType(I32));
+    CheckValue* trap = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), outOfBounds);
+    trap->setGenerator([] (CCallHelpers& jit, const StackmapGenerationParams&) {
+        jit.breakpoint();
+    });
+
+    Value* constant;
+    if (isX86()) {
+        // Since x86 doesn't have an instruction to convert floating points to unsigned integers, we at least try to do the smart thing if
+        // the numbers are would be positive anyway as a signed integer. Since we cannot materialize constants into fprs we have b3 do it
+        // so we can pool them if needed.
+        constant = m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), static_cast<float>(std::numeric_limits<uint64_t>::max() - std::numeric_limits<int64_t>::max()));
+    }
+    PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int64, Origin());
+    patchpoint->append(arg, ValueRep::SomeRegister);
+    if (isX86()) {
+        patchpoint->append(constant, ValueRep::SomeRegister);
+        patchpoint->numFPScratchRegisters = 1;
+    }
+    patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+        AllowMacroScratchRegisterUsage allowScratch(jit);
+        FPRReg scratch = InvalidFPRReg;
+        FPRReg constant = InvalidFPRReg;
+        if (isX86()) {
+            scratch = params.fpScratch(0);
+            constant = params[2].fpr();
+        }
+        jit.truncateFloatToUint64(params[1].fpr(), params[0].gpr(), scratch, constant);
+    });
+    patchpoint->effects = Effects::none();
+    result = patchpoint;
+    return true;
+}
+
 } } // namespace JSC::Wasm
 
 #include "WasmB3IRGeneratorInlines.h"

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (209475 => 209476)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2016-12-07 21:33:37 UTC (rev 209475)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2016-12-07 21:43:58 UTC (rev 209476)
@@ -221,6 +221,14 @@
     case OpType::I64Ctz: return unaryCase<OpType::I64Ctz>();
     case OpType::I32Popcnt: return unaryCase<OpType::I32Popcnt>();
     case OpType::I64Popcnt: return unaryCase<OpType::I64Popcnt>();
+    case OpType::I32TruncSF32: return unaryCase<OpType::I32TruncSF32>();
+    case OpType::I32TruncUF32: return unaryCase<OpType::I32TruncUF32>();
+    case OpType::I32TruncSF64: return unaryCase<OpType::I32TruncSF64>();
+    case OpType::I32TruncUF64: return unaryCase<OpType::I32TruncUF64>();
+    case OpType::I64TruncSF32: return unaryCase<OpType::I64TruncSF32>();
+    case OpType::I64TruncUF32: return unaryCase<OpType::I64TruncUF32>();
+    case OpType::I64TruncSF64: return unaryCase<OpType::I64TruncSF64>();
+    case OpType::I64TruncUF64: return unaryCase<OpType::I64TruncUF64>();
 #define CREATE_CASE(name, id, b3op, inc) case OpType::name: return unaryCase<OpType::name>();
     FOR_EACH_WASM_SIMPLE_UNARY_OP(CREATE_CASE)
 #undef CREATE_CASE
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to