From c61d62972b79ba6036dd31360dd22e0b9dc7f6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Cabrera?= Date: Fri, 9 Feb 2024 18:08:05 -0500 Subject: [PATCH] winch: Add saturating conversion instructions This commit adds support for the saturating conversions instructions. --- build.rs | 1 - tests/misc_testsuite/winch/conversions.wast | 497 -------------------- winch/codegen/src/isa/aarch64/masm.rs | 4 +- winch/codegen/src/isa/x64/asm.rs | 6 +- winch/codegen/src/isa/x64/masm.rs | 6 +- winch/codegen/src/masm.rs | 29 +- winch/codegen/src/visitor.rs | 115 ++++- 7 files changed, 146 insertions(+), 512 deletions(-) delete mode 100644 tests/misc_testsuite/winch/conversions.wast diff --git a/build.rs b/build.rs index ee3cd87508b6..06ff566f5075 100644 --- a/build.rs +++ b/build.rs @@ -214,7 +214,6 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool { if testsuite == "spec_testsuite" { let denylist = [ "br_table", - "conversions", "global", "table_fill", "table_get", diff --git a/tests/misc_testsuite/winch/conversions.wast b/tests/misc_testsuite/winch/conversions.wast deleted file mode 100644 index c6422d2e1b50..000000000000 --- a/tests/misc_testsuite/winch/conversions.wast +++ /dev/null @@ -1,497 +0,0 @@ -(module - (func (export "i64.extend_i32_s") (param $x i32) (result i64) (i64.extend_i32_s (local.get $x))) - (func (export "i64.extend_i32_u") (param $x i32) (result i64) (i64.extend_i32_u (local.get $x))) - (func (export "i32.wrap_i64") (param $x i64) (result i32) (i32.wrap_i64 (local.get $x))) - (func (export "i32.trunc_f32_s") (param $x f32) (result i32) (i32.trunc_f32_s (local.get $x))) - (func (export "i32.trunc_f32_u") (param $x f32) (result i32) (i32.trunc_f32_u (local.get $x))) - (func (export "i32.trunc_f64_s") (param $x f64) (result i32) (i32.trunc_f64_s (local.get $x))) - (func (export "i32.trunc_f64_u") (param $x f64) (result i32) (i32.trunc_f64_u (local.get $x))) - (func (export "i64.trunc_f32_s") (param $x f32) (result i64) (i64.trunc_f32_s (local.get $x))) - (func (export "i64.trunc_f32_u") (param $x f32) (result i64) (i64.trunc_f32_u (local.get $x))) - (func (export "i64.trunc_f64_s") (param $x f64) (result i64) (i64.trunc_f64_s (local.get $x))) - (func (export "i64.trunc_f64_u") (param $x f64) (result i64) (i64.trunc_f64_u (local.get $x))) - (func (export "f32.convert_i32_s") (param $x i32) (result f32) (f32.convert_i32_s (local.get $x))) - (func (export "f32.convert_i64_s") (param $x i64) (result f32) (f32.convert_i64_s (local.get $x))) - (func (export "f64.convert_i32_s") (param $x i32) (result f64) (f64.convert_i32_s (local.get $x))) - (func (export "f64.convert_i64_s") (param $x i64) (result f64) (f64.convert_i64_s (local.get $x))) - (func (export "f32.convert_i32_u") (param $x i32) (result f32) (f32.convert_i32_u (local.get $x))) - (func (export "f32.convert_i64_u") (param $x i64) (result f32) (f32.convert_i64_u (local.get $x))) - (func (export "f64.convert_i32_u") (param $x i32) (result f64) (f64.convert_i32_u (local.get $x))) - (func (export "f64.convert_i64_u") (param $x i64) (result f64) (f64.convert_i64_u (local.get $x))) - (func (export "f64.promote_f32") (param $x f32) (result f64) (f64.promote_f32 (local.get $x))) - (func (export "f32.demote_f64") (param $x f64) (result f32) (f32.demote_f64 (local.get $x))) - (func (export "f32.reinterpret_i32") (param $x i32) (result f32) (f32.reinterpret_i32 (local.get $x))) - (func (export "f64.reinterpret_i64") (param $x i64) (result f64) (f64.reinterpret_i64 (local.get $x))) - (func (export "i32.reinterpret_f32") (param $x f32) (result i32) (i32.reinterpret_f32 (local.get $x))) - (func (export "i64.reinterpret_f64") (param $x f64) (result i64) (i64.reinterpret_f64 (local.get $x))) -) - -(assert_return (invoke "i64.extend_i32_s" (i32.const 0)) (i64.const 0)) -(assert_return (invoke "i64.extend_i32_s" (i32.const 10000)) (i64.const 10000)) -(assert_return (invoke "i64.extend_i32_s" (i32.const -10000)) (i64.const -10000)) -(assert_return (invoke "i64.extend_i32_s" (i32.const -1)) (i64.const -1)) -(assert_return (invoke "i64.extend_i32_s" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff)) -(assert_return (invoke "i64.extend_i32_s" (i32.const 0x80000000)) (i64.const 0xffffffff80000000)) - -(assert_return (invoke "i64.extend_i32_u" (i32.const 0)) (i64.const 0)) -(assert_return (invoke "i64.extend_i32_u" (i32.const 10000)) (i64.const 10000)) -(assert_return (invoke "i64.extend_i32_u" (i32.const -10000)) (i64.const 0x00000000ffffd8f0)) -(assert_return (invoke "i64.extend_i32_u" (i32.const -1)) (i64.const 0xffffffff)) -(assert_return (invoke "i64.extend_i32_u" (i32.const 0x7fffffff)) (i64.const 0x000000007fffffff)) -(assert_return (invoke "i64.extend_i32_u" (i32.const 0x80000000)) (i64.const 0x0000000080000000)) - -(assert_return (invoke "i32.wrap_i64" (i64.const -1)) (i32.const -1)) -(assert_return (invoke "i32.wrap_i64" (i64.const -100000)) (i32.const -100000)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0x80000000)) (i32.const 0x80000000)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0xffffffff7fffffff)) (i32.const 0x7fffffff)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0xffffffff00000000)) (i32.const 0x00000000)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0xfffffffeffffffff)) (i32.const 0xffffffff)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0xffffffff00000001)) (i32.const 0x00000001)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0)) (i32.const 0)) -(assert_return (invoke "i32.wrap_i64" (i64.const 1311768467463790320)) (i32.const 0x9abcdef0)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0x00000000ffffffff)) (i32.const 0xffffffff)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0x0000000100000000)) (i32.const 0x00000000)) -(assert_return (invoke "i32.wrap_i64" (i64.const 0x0000000100000001)) (i32.const 0x00000001)) - -(assert_return (invoke "i32.trunc_f32_s" (f32.const 0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const 1.0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const 0x1.19999ap+0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const 1.5)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.0)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -0x1.19999ap+0)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.5)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -1.9)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -2.0)) (i32.const -2)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const 2147483520.0)) (i32.const 2147483520)) -(assert_return (invoke "i32.trunc_f32_s" (f32.const -2147483648.0)) (i32.const -2147483648)) -(assert_trap (invoke "i32.trunc_f32_s" (f32.const 2147483648.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const -2147483904.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const -inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const nan:0x200000)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_s" (f32.const -nan:0x200000)) "invalid conversion to integer") - -(assert_return (invoke "i32.trunc_f32_u" (f32.const 0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const -0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 0x1.19999ap+0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.5)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 1.9)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 2.0)) (i32.const 2)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000 -(assert_return (invoke "i32.trunc_f32_u" (f32.const 4294967040.0)) (i32.const -256)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1.ccccccp-1)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f32_u" (f32.const -0x1.fffffep-1)) (i32.const 0)) -(assert_trap (invoke "i32.trunc_f32_u" (f32.const 4294967296.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const -1.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const -inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const nan:0x200000)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f32_u" (f32.const -nan:0x200000)) "invalid conversion to integer") - -(assert_return (invoke "i32.trunc_f64_s" (f64.const 0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 1.0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 0x1.199999999999ap+0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 1.5)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.0)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -0x1.199999999999ap+0)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.5)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -1.9)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -2.0)) (i32.const -2)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.0)) (i32.const 2147483647)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.0)) (i32.const -2147483648)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.9)) (i32.const -2147483648)) -(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.9)) (i32.const 2147483647)) -(assert_trap (invoke "i32.trunc_f64_s" (f64.const 2147483648.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const -2147483649.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const -inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const nan:0x4000000000000)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan:0x4000000000000)) "invalid conversion to integer") - -(assert_return (invoke "i32.trunc_f64_u" (f64.const 0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.0)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 0x1.199999999999ap+0)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.5)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 1.9)) (i32.const 1)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 2.0)) (i32.const 2)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000 -(assert_return (invoke "i32.trunc_f64_u" (f64.const 4294967295.0)) (i32.const -1)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x1.ccccccccccccdp-1)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const -0x1.fffffffffffffp-1)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 1e8)) (i32.const 100000000)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.9)) (i32.const 0)) -(assert_return (invoke "i32.trunc_f64_u" (f64.const 4294967295.9)) (i32.const 4294967295)) -(assert_trap (invoke "i32.trunc_f64_u" (f64.const 4294967296.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const -1.0)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const 1e16)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const 1e30)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const 9223372036854775808)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const -inf)) "integer overflow") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const nan:0x4000000000000)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i32.trunc_f64_u" (f64.const -nan:0x4000000000000)) "invalid conversion to integer") - -(assert_return (invoke "i64.trunc_f32_s" (f32.const 0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const 0x1p-149)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -0x1p-149)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const 1.0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const 0x1.19999ap+0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const 1.5)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.0)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -0x1.19999ap+0)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.5)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -1.9)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -2.0)) (i64.const -2)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000 -(assert_return (invoke "i64.trunc_f32_s" (f32.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000 -(assert_return (invoke "i64.trunc_f32_s" (f32.const 9223371487098961920.0)) (i64.const 9223371487098961920)) -(assert_return (invoke "i64.trunc_f32_s" (f32.const -9223372036854775808.0)) (i64.const -9223372036854775808)) -(assert_trap (invoke "i64.trunc_f32_s" (f32.const 9223372036854775808.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const -9223373136366403584.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const -inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const nan:0x200000)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_s" (f32.const -nan:0x200000)) "invalid conversion to integer") - -(assert_return (invoke "i64.trunc_f32_u" (f32.const 0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const -0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 0x1p-149)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1p-149)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 1.0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 0x1.19999ap+0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 1.5)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 4294967296)) (i64.const 4294967296)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const 18446742974197923840.0)) (i64.const -1099511627776)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1.ccccccp-1)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f32_u" (f32.const -0x1.fffffep-1)) (i64.const 0)) -(assert_trap (invoke "i64.trunc_f32_u" (f32.const 18446744073709551616.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const -1.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const -inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const nan:0x200000)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f32_u" (f32.const -nan:0x200000)) "invalid conversion to integer") - -(assert_return (invoke "i64.trunc_f64_s" (f64.const 0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const 0x0.0000000000001p-1022)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -0x0.0000000000001p-1022)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const 1.0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const 0x1.199999999999ap+0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const 1.5)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.0)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -0x1.199999999999ap+0)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.5)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -1.9)) (i64.const -1)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -2.0)) (i64.const -2)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000 -(assert_return (invoke "i64.trunc_f64_s" (f64.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000 -(assert_return (invoke "i64.trunc_f64_s" (f64.const 9223372036854774784.0)) (i64.const 9223372036854774784)) -(assert_return (invoke "i64.trunc_f64_s" (f64.const -9223372036854775808.0)) (i64.const -9223372036854775808)) -(assert_trap (invoke "i64.trunc_f64_s" (f64.const 9223372036854775808.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const -9223372036854777856.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const -inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const nan:0x4000000000000)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_s" (f64.const -nan:0x4000000000000)) "invalid conversion to integer") - -(assert_return (invoke "i64.trunc_f64_u" (f64.const 0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const -0.0)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 0x0.0000000000001p-1022)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x0.0000000000001p-1022)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 1.0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 0x1.199999999999ap+0)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 1.5)) (i64.const 1)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 4294967295)) (i64.const 0xffffffff)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 4294967296)) (i64.const 0x100000000)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 18446744073709549568.0)) (i64.const -2048)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x1.ccccccccccccdp-1)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const -0x1.fffffffffffffp-1)) (i64.const 0)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 1e8)) (i64.const 100000000)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 1e16)) (i64.const 10000000000000000)) -(assert_return (invoke "i64.trunc_f64_u" (f64.const 9223372036854775808)) (i64.const -9223372036854775808)) -(assert_trap (invoke "i64.trunc_f64_u" (f64.const 18446744073709551616.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const -1.0)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const -inf)) "integer overflow") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const nan:0x4000000000000)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const -nan)) "invalid conversion to integer") -(assert_trap (invoke "i64.trunc_f64_u" (f64.const -nan:0x4000000000000)) "invalid conversion to integer") - -(assert_return (invoke "f32.convert_i32_s" (i32.const 1)) (f32.const 1.0)) -(assert_return (invoke "f32.convert_i32_s" (i32.const -1)) (f32.const -1.0)) -(assert_return (invoke "f32.convert_i32_s" (i32.const 0)) (f32.const 0.0)) -(assert_return (invoke "f32.convert_i32_s" (i32.const 2147483647)) (f32.const 2147483648)) -(assert_return (invoke "f32.convert_i32_s" (i32.const -2147483648)) (f32.const -2147483648)) -(assert_return (invoke "f32.convert_i32_s" (i32.const 1234567890)) (f32.const 0x1.26580cp+30)) - -(assert_return (invoke "f32.convert_i64_s" (i64.const 1)) (f32.const 1.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const -1)) (f32.const -1.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 9223372036854775807)) (f32.const 9223372036854775807)) -(assert_return (invoke "f32.convert_i64_s" (i64.const -9223372036854775808)) (f32.const -9223372036854775808)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 314159265358979)) (f32.const 0x1.1db9e8p+48)) ;; PI -;; Test rounding directions. -(assert_return (invoke "f32.convert_i64_s" (i64.const 16777217)) (f32.const 16777216.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const -16777217)) (f32.const -16777216.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 16777219)) (f32.const 16777220.0)) -(assert_return (invoke "f32.convert_i64_s" (i64.const -16777219)) (f32.const -16777220.0)) - -(assert_return (invoke "f32.convert_i64_s" (i64.const 0x7fffff4000000001)) (f32.const 0x1.fffffep+62)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 0x8000004000000001)) (f32.const -0x1.fffffep+62)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53)) -(assert_return (invoke "f32.convert_i64_s" (i64.const 0xffdfffffdfffffff)) (f32.const -0x1.000002p+53)) - -(assert_return (invoke "f64.convert_i32_s" (i32.const 1)) (f64.const 1.0)) -(assert_return (invoke "f64.convert_i32_s" (i32.const -1)) (f64.const -1.0)) -(assert_return (invoke "f64.convert_i32_s" (i32.const 0)) (f64.const 0.0)) -(assert_return (invoke "f64.convert_i32_s" (i32.const 2147483647)) (f64.const 2147483647)) -(assert_return (invoke "f64.convert_i32_s" (i32.const -2147483648)) (f64.const -2147483648)) -(assert_return (invoke "f64.convert_i32_s" (i32.const 987654321)) (f64.const 987654321)) - -(assert_return (invoke "f64.convert_i64_s" (i64.const 1)) (f64.const 1.0)) -(assert_return (invoke "f64.convert_i64_s" (i64.const -1)) (f64.const -1.0)) -(assert_return (invoke "f64.convert_i64_s" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "f64.convert_i64_s" (i64.const 9223372036854775807)) (f64.const 9223372036854775807)) -(assert_return (invoke "f64.convert_i64_s" (i64.const -9223372036854775808)) (f64.const -9223372036854775808)) -(assert_return (invoke "f64.convert_i64_s" (i64.const 4669201609102990)) (f64.const 4669201609102990)) ;; Feigenbaum -;; Test rounding directions. -(assert_return (invoke "f64.convert_i64_s" (i64.const 9007199254740993)) (f64.const 9007199254740992)) -(assert_return (invoke "f64.convert_i64_s" (i64.const -9007199254740993)) (f64.const -9007199254740992)) -(assert_return (invoke "f64.convert_i64_s" (i64.const 9007199254740995)) (f64.const 9007199254740996)) -(assert_return (invoke "f64.convert_i64_s" (i64.const -9007199254740995)) (f64.const -9007199254740996)) - -(assert_return (invoke "f32.convert_i32_u" (i32.const 1)) (f32.const 1.0)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0)) (f32.const 0.0)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 2147483647)) (f32.const 2147483648)) -(assert_return (invoke "f32.convert_i32_u" (i32.const -2147483648)) (f32.const 2147483648)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0x12345678)) (f32.const 0x1.234568p+28)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0xffffffff)) (f32.const 4294967296.0)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000080)) (f32.const 0x1.000000p+31)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000081)) (f32.const 0x1.000002p+31)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0x80000082)) (f32.const 0x1.000002p+31)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe80)) (f32.const 0x1.fffffcp+31)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe81)) (f32.const 0x1.fffffep+31)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 0xfffffe82)) (f32.const 0x1.fffffep+31)) -;; Test rounding directions. -(assert_return (invoke "f32.convert_i32_u" (i32.const 16777217)) (f32.const 16777216.0)) -(assert_return (invoke "f32.convert_i32_u" (i32.const 16777219)) (f32.const 16777220.0)) - -(assert_return (invoke "f32.convert_i64_u" (i64.const 1)) (f32.const 1.0)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 9223372036854775807)) (f32.const 9223372036854775807)) -(assert_return (invoke "f32.convert_i64_u" (i64.const -9223372036854775808)) (f32.const 9223372036854775808)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 0xffffffffffffffff)) (f32.const 18446744073709551616.0)) -;; Test rounding directions. -(assert_return (invoke "f32.convert_i64_u" (i64.const 16777217)) (f32.const 16777216.0)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 16777219)) (f32.const 16777220.0)) - -(assert_return (invoke "f32.convert_i64_u" (i64.const 0x0020000020000001)) (f32.const 0x1.000002p+53)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 0x7fffffbfffffffff)) (f32.const 0x1.fffffep+62)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 0x8000008000000001)) (f32.const 0x1.000002p+63)) -(assert_return (invoke "f32.convert_i64_u" (i64.const 0xfffffe8000000001)) (f32.const 0x1.fffffep+63)) - -(assert_return (invoke "f64.convert_i32_u" (i32.const 1)) (f64.const 1.0)) -(assert_return (invoke "f64.convert_i32_u" (i32.const 0)) (f64.const 0.0)) -(assert_return (invoke "f64.convert_i32_u" (i32.const 2147483647)) (f64.const 2147483647)) -(assert_return (invoke "f64.convert_i32_u" (i32.const -2147483648)) (f64.const 2147483648)) -(assert_return (invoke "f64.convert_i32_u" (i32.const 0xffffffff)) (f64.const 4294967295.0)) - -(assert_return (invoke "f64.convert_i64_u" (i64.const 1)) (f64.const 1.0)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 9223372036854775807)) (f64.const 9223372036854775807)) -(assert_return (invoke "f64.convert_i64_u" (i64.const -9223372036854775808)) (f64.const 9223372036854775808)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0xffffffffffffffff)) (f64.const 18446744073709551616.0)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000400)) (f64.const 0x1.0000000000000p+63)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000401)) (f64.const 0x1.0000000000001p+63)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0x8000000000000402)) (f64.const 0x1.0000000000001p+63)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff400)) (f64.const 0x1.ffffffffffffep+63)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff401)) (f64.const 0x1.fffffffffffffp+63)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 0xfffffffffffff402)) (f64.const 0x1.fffffffffffffp+63)) -;; Test rounding directions. -(assert_return (invoke "f64.convert_i64_u" (i64.const 9007199254740993)) (f64.const 9007199254740992)) -(assert_return (invoke "f64.convert_i64_u" (i64.const 9007199254740995)) (f64.const 9007199254740996)) - -(assert_return (invoke "f64.promote_f32" (f32.const 0.0)) (f64.const 0.0)) -(assert_return (invoke "f64.promote_f32" (f32.const -0.0)) (f64.const -0.0)) -(assert_return (invoke "f64.promote_f32" (f32.const 0x1p-149)) (f64.const 0x1p-149)) -(assert_return (invoke "f64.promote_f32" (f32.const -0x1p-149)) (f64.const -0x1p-149)) -(assert_return (invoke "f64.promote_f32" (f32.const 1.0)) (f64.const 1.0)) -(assert_return (invoke "f64.promote_f32" (f32.const -1.0)) (f64.const -1.0)) -(assert_return (invoke "f64.promote_f32" (f32.const -0x1.fffffep+127)) (f64.const -0x1.fffffep+127)) -(assert_return (invoke "f64.promote_f32" (f32.const 0x1.fffffep+127)) (f64.const 0x1.fffffep+127)) -;; Generated randomly by picking a random int and reinterpret it to float. -(assert_return (invoke "f64.promote_f32" (f32.const 0x1p-119)) (f64.const 0x1p-119)) -;; Generated randomly by picking a random float. -(assert_return (invoke "f64.promote_f32" (f32.const 0x1.8f867ep+125)) (f64.const 6.6382536710104395e+37)) -(assert_return (invoke "f64.promote_f32" (f32.const inf)) (f64.const inf)) -(assert_return (invoke "f64.promote_f32" (f32.const -inf)) (f64.const -inf)) -(assert_return (invoke "f64.promote_f32" (f32.const nan)) (f64.const nan:canonical)) -(assert_return (invoke "f64.promote_f32" (f32.const nan:0x200000)) (f64.const nan:arithmetic)) -(assert_return (invoke "f64.promote_f32" (f32.const -nan)) (f64.const nan:canonical)) -(assert_return (invoke "f64.promote_f32" (f32.const -nan:0x200000)) (f64.const nan:arithmetic)) - -(assert_return (invoke "f32.demote_f64" (f64.const 0.0)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0.0)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x0.0000000000001p-1022)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 1.0)) (f32.const 1.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -1.0)) (f32.const -1.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffe0000000p-127)) (f32.const 0x1p-126)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffe0000000p-127)) (f32.const -0x1p-126)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffdfffffffp-127)) (f32.const 0x1.fffffcp-127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffdfffffffp-127)) (f32.const -0x1.fffffcp-127)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-149)) (f32.const -0x1p-149)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000000p+127)) (f32.const 0x1.fffffcp+127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000000p+127)) (f32.const -0x1.fffffcp+127)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000001p+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000001p+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffefffffffp+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffefffffffp+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.ffffffp+127)) (f32.const inf)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.ffffffp+127)) (f32.const -inf)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-119)) (f32.const 0x1p-119)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.8f867ep+125)) (f32.const 0x1.8f867ep+125)) -(assert_return (invoke "f32.demote_f64" (f64.const inf)) (f32.const inf)) -(assert_return (invoke "f32.demote_f64" (f64.const -inf)) (f32.const -inf)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p+0)) (f32.const 1.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffffffffffp-1)) (f32.const 1.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+0)) (f32.const 0x1.000000p+0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+0)) (f32.const 0x1.000002p+0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+0)) (f32.const 0x1.000002p+0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+0)) (f32.const 0x1.000004p+0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000050000000p+0)) (f32.const 0x1.000004p+0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+24)) (f32.const 0x1.0p+24)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+24)) (f32.const 0x1.000002p+24)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+24)) (f32.const 0x1.000002p+24)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+24)) (f32.const 0x1.000004p+24)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.4eae4f7024c7p+108)) (f32.const 0x1.4eae5p+108)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.a12e71e358685p-113)) (f32.const 0x1.a12e72p-113)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.cb98354d521ffp-127)) (f32.const 0x1.cb9834p-127)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.6972b30cfb562p+1)) (f32.const -0x1.6972b4p+1)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.bedbe4819d4c4p+112)) (f32.const -0x1.bedbe4p+112)) -(assert_return (invoke "f32.demote_f64" (f64.const nan)) (f32.const nan:canonical)) -(assert_return (invoke "f32.demote_f64" (f64.const nan:0x4000000000000)) (f32.const nan:arithmetic)) -(assert_return (invoke "f32.demote_f64" (f64.const -nan)) (f32.const nan:canonical)) -(assert_return (invoke "f32.demote_f64" (f64.const -nan:0x4000000000000)) (f32.const nan:arithmetic)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-1022)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-1022)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0p-150)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.0p-150)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p-150)) (f32.const 0x1p-149)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1.0000000000001p-150)) (f32.const -0x1p-149)) - -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0)) (f32.const 0.0)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0x80000000)) (f32.const -0.0)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 1)) (f32.const 0x1p-149)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const -1)) (f32.const -nan:0x7fffff)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 123456789)) (f32.const 0x1.b79a2ap-113)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const -2147483647)) (f32.const -0x1p-149)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0x7f800000)) (f32.const inf)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0xff800000)) (f32.const -inf)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0x7fc00000)) (f32.const nan)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0xffc00000)) (f32.const -nan)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0x7fa00000)) (f32.const nan:0x200000)) -(assert_return (invoke "f32.reinterpret_i32" (i32.const 0xffa00000)) (f32.const -nan:0x200000)) - -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 1)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const -1)) (f64.const -nan:0xfffffffffffff)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0x8000000000000000)) (f64.const -0.0)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 1234567890)) (f64.const 0x0.00000499602d2p-1022)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const -9223372036854775807)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0x7ff0000000000000)) (f64.const inf)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0xfff0000000000000)) (f64.const -inf)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0x7ff8000000000000)) (f64.const nan)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0xfff8000000000000)) (f64.const -nan)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0x7ff4000000000000)) (f64.const nan:0x4000000000000)) -(assert_return (invoke "f64.reinterpret_i64" (i64.const 0xfff4000000000000)) (f64.const -nan:0x4000000000000)) - -(assert_return (invoke "i32.reinterpret_f32" (f32.const 0.0)) (i32.const 0)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -0.0)) (i32.const 0x80000000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -nan:0x7fffff)) (i32.const -1)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -0x1p-149)) (i32.const 0x80000001)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const 1.0)) (i32.const 1065353216)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const 3.1415926)) (i32.const 1078530010)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const 0x1.fffffep+127)) (i32.const 2139095039)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -0x1.fffffep+127)) (i32.const -8388609)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const inf)) (i32.const 0x7f800000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -inf)) (i32.const 0xff800000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const nan)) (i32.const 0x7fc00000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -nan)) (i32.const 0xffc00000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const nan:0x200000)) (i32.const 0x7fa00000)) -(assert_return (invoke "i32.reinterpret_f32" (f32.const -nan:0x200000)) (i32.const 0xffa00000)) - -(assert_return (invoke "i64.reinterpret_f64" (f64.const 0.0)) (i64.const 0)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -0.0)) (i64.const 0x8000000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const 0x0.0000000000001p-1022)) (i64.const 1)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -nan:0xfffffffffffff)) (i64.const -1)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -0x0.0000000000001p-1022)) (i64.const 0x8000000000000001)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const 1.0)) (i64.const 4607182418800017408)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const 3.14159265358979)) (i64.const 4614256656552045841)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const 0x1.fffffffffffffp+1023)) (i64.const 9218868437227405311)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -0x1.fffffffffffffp+1023)) (i64.const -4503599627370497)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const inf)) (i64.const 0x7ff0000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -inf)) (i64.const 0xfff0000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const nan)) (i64.const 0x7ff8000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -nan)) (i64.const 0xfff8000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const nan:0x4000000000000)) (i64.const 0x7ff4000000000000)) -(assert_return (invoke "i64.reinterpret_f64" (f64.const -nan:0x4000000000000)) (i64.const 0xfff4000000000000)) - -;; Type check - -(assert_invalid (module (func (result i32) (i32.wrap_i64 (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.trunc_f32_s (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.trunc_f32_u (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.trunc_f64_s (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.reinterpret_f32 (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.extend_i32_s (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.extend_i32_u (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.trunc_f32_s (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.trunc_f32_u (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.trunc_f64_s (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.trunc_f64_u (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.reinterpret_f64 (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.convert_i32_s (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.convert_i32_u (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.convert_i64_s (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.convert_i64_u (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.demote_f64 (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.reinterpret_i32 (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.convert_i32_s (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.convert_i32_u (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.convert_i64_s (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.convert_i64_u (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.promote_f32 (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.reinterpret_i64 (i32.const 0)))) "type mismatch") diff --git a/winch/codegen/src/isa/aarch64/masm.rs b/winch/codegen/src/isa/aarch64/masm.rs index 596d39940940..c10f8f1006a4 100644 --- a/winch/codegen/src/isa/aarch64/masm.rs +++ b/winch/codegen/src/isa/aarch64/masm.rs @@ -6,7 +6,7 @@ use crate::{ masm::{ CalleeKind, DivKind, ExtendKind, FloatCmpKind, Imm as I, IntCmpKind, MacroAssembler as Masm, OperandSize, RegImm, RemKind, RoundingMode, SPOffset, ShiftKind, - StackSlot, TrapCode, + StackSlot, TrapCode, TruncKind, }, }; use cranelift_codegen::{settings, Final, MachBufferFinalized, MachLabel}; @@ -379,6 +379,7 @@ impl Masm for MacroAssembler { _dst: Reg, _src_size: OperandSize, _dst_size: OperandSize, + _kind: TruncKind, ) { todo!() } @@ -390,6 +391,7 @@ impl Masm for MacroAssembler { _tmp_fpr: Reg, _src_size: OperandSize, _dst_size: OperandSize, + _kind: TruncKind, ) { todo!() } diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs index 89f1a5b82e22..2859cb110426 100644 --- a/winch/codegen/src/isa/x64/asm.rs +++ b/winch/codegen/src/isa/x64/asm.rs @@ -615,11 +615,12 @@ impl Assembler { tmp_xmm: Reg, src_size: OperandSize, dst_size: OperandSize, + saturating: bool, ) { self.emit(Inst::CvtFloatToSintSeq { dst_size: dst_size.into(), src_size: src_size.into(), - is_saturating: false, + is_saturating: saturating, src: src.into(), dst: dst.into(), tmp_gpr: tmp_gpr.into(), @@ -637,11 +638,12 @@ impl Assembler { tmp_xmm2: Reg, src_size: OperandSize, dst_size: OperandSize, + saturating: bool, ) { self.emit(Inst::CvtFloatToUintSeq { dst_size: dst_size.into(), src_size: src_size.into(), - is_saturating: false, + is_saturating: saturating, src: src.into(), dst: dst.into(), tmp_gpr: tmp_gpr.into(), diff --git a/winch/codegen/src/isa/x64/masm.rs b/winch/codegen/src/isa/x64/masm.rs index eddd4739609f..433dfb651045 100644 --- a/winch/codegen/src/isa/x64/masm.rs +++ b/winch/codegen/src/isa/x64/masm.rs @@ -7,7 +7,7 @@ use super::{ use crate::masm::{ DivKind, ExtendKind, FloatCmpKind, Imm as I, IntCmpKind, MacroAssembler as Masm, OperandSize, - RegImm, RemKind, RoundingMode, ShiftKind, TrapCode, TRUSTED_FLAGS, UNTRUSTED_FLAGS, + RegImm, RemKind, RoundingMode, ShiftKind, TrapCode, TruncKind, TRUSTED_FLAGS, UNTRUSTED_FLAGS, }; use crate::{ abi::ABI, @@ -1021,6 +1021,7 @@ impl Masm for MacroAssembler { dst: Reg, src_size: OperandSize, dst_size: OperandSize, + kind: TruncKind, ) { self.asm.cvt_float_to_sint_seq( src, @@ -1029,6 +1030,7 @@ impl Masm for MacroAssembler { regs::scratch_xmm(), src_size, dst_size, + kind.is_checked(), ); } @@ -1039,6 +1041,7 @@ impl Masm for MacroAssembler { tmp_fpr: Reg, src_size: OperandSize, dst_size: OperandSize, + kind: TruncKind, ) { self.asm.cvt_float_to_uint_seq( src, @@ -1048,6 +1051,7 @@ impl Masm for MacroAssembler { tmp_fpr, src_size, dst_size, + kind.is_checked(), ); } diff --git a/winch/codegen/src/masm.rs b/winch/codegen/src/masm.rs index 54b1792c5425..b3dd603f0c7f 100644 --- a/winch/codegen/src/masm.rs +++ b/winch/codegen/src/masm.rs @@ -39,6 +39,25 @@ pub(crate) enum MemMoveDirection { LowToHigh, } +/// Classifies how to treat float-to-int conversions. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub(crate) enum TruncKind { + /// Saturating conversion. If the source value is greater than the maximum + /// value of the destination type, the result is clamped to the + /// destination maximum value. + Checked, + /// An exception is raised if the source value is greater than the maximum + /// value of the destination type. + Unchecked, +} + +impl TruncKind { + /// Returns true if the truncation kind is checked. + pub(crate) fn is_checked(&self) -> bool { + *self == TruncKind::Checked + } +} + /// Representation of the stack pointer offset. #[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Default)] pub struct SPOffset(u32); @@ -676,7 +695,14 @@ pub(crate) trait MacroAssembler { /// Emits one or more instructions to perform a signed truncation of a /// float into an integer. - fn signed_truncate(&mut self, src: Reg, dst: Reg, src_size: OperandSize, dst_size: OperandSize); + fn signed_truncate( + &mut self, + src: Reg, + dst: Reg, + src_size: OperandSize, + dst_size: OperandSize, + kind: TruncKind, + ); /// Emits one or more instructions to perform an unsigned truncation of a /// float into an integer. @@ -687,6 +713,7 @@ pub(crate) trait MacroAssembler { tmp_fpr: Reg, src_size: OperandSize, dst_size: OperandSize, + kind: TruncKind, ); /// Emits one or more instructions to perform a signed convert of an diff --git a/winch/codegen/src/visitor.rs b/winch/codegen/src/visitor.rs index c2bbf9cd0d61..d52b2a49e7db 100644 --- a/winch/codegen/src/visitor.rs +++ b/winch/codegen/src/visitor.rs @@ -8,7 +8,7 @@ use crate::abi::{RetArea, ABI}; use crate::codegen::{control_index, Callee, CodeGen, ControlStackFrame, FnCall}; use crate::masm::{ DivKind, ExtendKind, FloatCmpKind, IntCmpKind, MacroAssembler, MemMoveDirection, OperandSize, - RegImm, RemKind, RoundingMode, SPOffset, ShiftKind, + RegImm, RemKind, RoundingMode, SPOffset, ShiftKind, TruncKind, }; use crate::stack::{TypedReg, Val}; use cranelift_codegen::ir::TrapCode; @@ -231,6 +231,15 @@ macro_rules! def_unsupported { (emit F32Store $($rest:tt)*) => {}; (emit F64Load $($rest:tt)*) => {}; (emit F64Store $($rest:tt)*) => {}; + (emit I32TruncSatF32S $($rest:tt)*) => {}; + (emit I32TruncSatF32U $($rest:tt)*) => {}; + (emit I32TruncSatF64S $($rest:tt)*) => {}; + (emit I32TruncSatF64U $($rest:tt)*) => {}; + (emit I64TruncSatF32S $($rest:tt)*) => {}; + (emit I64TruncSatF32U $($rest:tt)*) => {}; + (emit I64TruncSatF64S $($rest:tt)*) => {}; + (emit I64TruncSatF64U $($rest:tt)*) => {}; + (emit $unsupported:tt $($rest:tt)*) => {$($rest)*}; } @@ -1162,7 +1171,7 @@ where self.context .convert_op(self.masm, WasmValType::I32, |masm, dst, src, dst_size| { - masm.signed_truncate(src, dst, S32, dst_size); + masm.signed_truncate(src, dst, S32, dst_size, TruncKind::Unchecked); }); } @@ -1174,7 +1183,7 @@ where WasmValType::I32, RegClass::Float, |masm, dst, src, tmp_fpr, dst_size| { - masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size); + masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size, TruncKind::Unchecked); }, ); } @@ -1184,7 +1193,7 @@ where self.context .convert_op(self.masm, WasmValType::I32, |masm, dst, src, dst_size| { - masm.signed_truncate(src, dst, S64, dst_size); + masm.signed_truncate(src, dst, S64, dst_size, TruncKind::Unchecked); }); } @@ -1196,7 +1205,7 @@ where WasmValType::I32, RegClass::Float, |masm, dst, src, tmp_fpr, dst_size| { - masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size); + masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size, TruncKind::Unchecked); }, ); } @@ -1206,7 +1215,7 @@ where self.context .convert_op(self.masm, WasmValType::I64, |masm, dst, src, dst_size| { - masm.signed_truncate(src, dst, S32, dst_size); + masm.signed_truncate(src, dst, S32, dst_size, TruncKind::Unchecked); }); } @@ -1218,7 +1227,7 @@ where WasmValType::I64, RegClass::Float, |masm, dst, src, tmp_fpr, dst_size| { - masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size); + masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size, TruncKind::Unchecked); }, ); } @@ -1228,7 +1237,7 @@ where self.context .convert_op(self.masm, WasmValType::I64, |masm, dst, src, dst_size| { - masm.signed_truncate(src, dst, S64, dst_size); + masm.signed_truncate(src, dst, S64, dst_size, TruncKind::Unchecked); }); } @@ -1240,7 +1249,7 @@ where WasmValType::I64, RegClass::Float, |masm, dst, src, tmp_fpr, dst_size| { - masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size); + masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size, TruncKind::Unchecked); }, ); } @@ -1944,6 +1953,94 @@ where self.emit_wasm_store(&memarg, OperandSize::S64) } + fn visit_i32_trunc_sat_f32_s(&mut self) { + use OperandSize::*; + + self.context + .convert_op(self.masm, WasmValType::I32, |masm, dst, src, dst_size| { + masm.signed_truncate(src, dst, S32, dst_size, TruncKind::Checked); + }); + } + + fn visit_i32_trunc_sat_f32_u(&mut self) { + use OperandSize::*; + + self.context.convert_op_with_tmp_reg( + self.masm, + WasmValType::I32, + RegClass::Float, + |masm, dst, src, tmp_fpr, dst_size| { + masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size, TruncKind::Checked); + }, + ); + } + + fn visit_i32_trunc_sat_f64_s(&mut self) { + use OperandSize::*; + + self.context + .convert_op(self.masm, WasmValType::I32, |masm, dst, src, dst_size| { + masm.signed_truncate(src, dst, S64, dst_size, TruncKind::Checked); + }); + } + + fn visit_i32_trunc_sat_f64_u(&mut self) { + use OperandSize::*; + + self.context.convert_op_with_tmp_reg( + self.masm, + WasmValType::I32, + RegClass::Float, + |masm, dst, src, tmp_fpr, dst_size| { + masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size, TruncKind::Checked); + }, + ); + } + + fn visit_i64_trunc_sat_f32_s(&mut self) { + use OperandSize::*; + + self.context + .convert_op(self.masm, WasmValType::I64, |masm, dst, src, dst_size| { + masm.signed_truncate(src, dst, S32, dst_size, TruncKind::Checked); + }); + } + + fn visit_i64_trunc_sat_f32_u(&mut self) { + use OperandSize::*; + + self.context.convert_op_with_tmp_reg( + self.masm, + WasmValType::I64, + RegClass::Float, + |masm, dst, src, tmp_fpr, dst_size| { + masm.unsigned_truncate(src, dst, tmp_fpr, S32, dst_size, TruncKind::Checked); + }, + ); + } + + fn visit_i64_trunc_sat_f64_s(&mut self) { + use OperandSize::*; + + self.context + .convert_op(self.masm, WasmValType::I64, |masm, dst, src, dst_size| { + masm.signed_truncate(src, dst, S64, dst_size, TruncKind::Checked); + }); + } + + fn visit_i64_trunc_sat_f64_u(&mut self) { + use OperandSize::*; + + self.context.convert_op_with_tmp_reg( + self.masm, + WasmValType::I64, + RegClass::Float, + |masm, dst, src, tmp_fpr, dst_size| { + masm.unsigned_truncate(src, dst, tmp_fpr, S64, dst_size, TruncKind::Checked); + }, + ); + } + wasmparser::for_each_operator!(def_unsupported); }