OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
10 | 10 #include "src/utils.h" |
11 #include "src/wasm/wasm-macro-gen.h" | 11 #include "src/wasm/wasm-macro-gen.h" |
12 | 12 |
13 #include "test/cctest/cctest.h" | 13 #include "test/cctest/cctest.h" |
14 #include "test/cctest/compiler/value-helper.h" | 14 #include "test/cctest/compiler/value-helper.h" |
15 #include "test/cctest/wasm/test-signatures.h" | 15 #include "test/cctest/wasm/test-signatures.h" |
16 #include "test/cctest/wasm/wasm-run-utils.h" | 16 #include "test/cctest/wasm/wasm-run-utils.h" |
17 | 17 |
18 using namespace v8::base; | 18 using namespace v8::base; |
19 using namespace v8::internal; | 19 using namespace v8::internal; |
20 using namespace v8::internal::compiler; | 20 using namespace v8::internal::compiler; |
(...skipping 2518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2539 | 2539 |
2540 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), r.Call(*i)); } | 2540 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), r.Call(*i)); } |
2541 } | 2541 } |
2542 | 2542 |
2543 WASM_EXEC_TEST(F32Min) { | 2543 WASM_EXEC_TEST(F32Min) { |
2544 WasmRunner<float> r(execution_mode, MachineType::Float32(), | 2544 WasmRunner<float> r(execution_mode, MachineType::Float32(), |
2545 MachineType::Float32()); | 2545 MachineType::Float32()); |
2546 BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2546 BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2547 | 2547 |
2548 FOR_FLOAT32_INPUTS(i) { | 2548 FOR_FLOAT32_INPUTS(i) { |
2549 FOR_FLOAT32_INPUTS(j) { | 2549 FOR_FLOAT32_INPUTS(j) { CHECK_DOUBLE_EQ(JSMin(*i, *j), r.Call(*i, *j)); } |
2550 float expected; | |
2551 if (*i < *j) { | |
2552 expected = *i; | |
2553 } else if (*j < *i) { | |
2554 expected = *j; | |
2555 } else if (*i != *i) { | |
2556 // If *i or *j is NaN, then the result is NaN. | |
2557 expected = *i; | |
2558 } else { | |
2559 expected = *j; | |
2560 } | |
2561 | |
2562 CHECK_FLOAT_EQ(expected, r.Call(*i, *j)); | |
2563 } | |
2564 } | 2550 } |
2565 } | 2551 } |
2566 | 2552 |
2567 WASM_EXEC_TEST(F64Min) { | 2553 WASM_EXEC_TEST(F64Min) { |
2568 WasmRunner<double> r(execution_mode, MachineType::Float64(), | 2554 WasmRunner<double> r(execution_mode, MachineType::Float64(), |
2569 MachineType::Float64()); | 2555 MachineType::Float64()); |
2570 BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2556 BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2571 | 2557 |
2572 FOR_FLOAT64_INPUTS(i) { | 2558 FOR_FLOAT64_INPUTS(i) { |
2573 FOR_FLOAT64_INPUTS(j) { | 2559 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(JSMin(*i, *j), r.Call(*i, *j)); } |
2574 double result = r.Call(*i, *j); | |
2575 if (std::isnan(*i) || std::isnan(*j)) { | |
2576 // If one of the inputs is nan, the result should be nan. | |
2577 CHECK(std::isnan(result)); | |
2578 } else if ((*i == 0.0) && (*j == 0.0) && | |
2579 (copysign(1.0, *i) != copysign(1.0, *j))) { | |
2580 // If one input is +0.0 and the other input is -0.0, the result should | |
2581 // be -0.0. | |
2582 CHECK_EQ(bit_cast<uint64_t>(-0.0), bit_cast<uint64_t>(result)); | |
2583 } else { | |
2584 double expected = *i < *j ? *i : *j; | |
2585 CHECK_DOUBLE_EQ(expected, result); | |
2586 } | |
2587 } | |
2588 } | 2560 } |
2589 } | 2561 } |
2590 | 2562 |
2591 WASM_EXEC_TEST(F32Max) { | 2563 WASM_EXEC_TEST(F32Max) { |
2592 WasmRunner<float> r(execution_mode, MachineType::Float32(), | 2564 WasmRunner<float> r(execution_mode, MachineType::Float32(), |
2593 MachineType::Float32()); | 2565 MachineType::Float32()); |
2594 BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2566 BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2595 | 2567 |
2596 FOR_FLOAT32_INPUTS(i) { | 2568 FOR_FLOAT32_INPUTS(i) { |
2597 FOR_FLOAT32_INPUTS(j) { | 2569 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(JSMax(*i, *j), r.Call(*i, *j)); } |
2598 float expected; | |
2599 if (*i > *j) { | |
2600 expected = *i; | |
2601 } else if (*j > *i) { | |
2602 expected = *j; | |
2603 } else if (*i != *i) { | |
2604 // If *i or *j is NaN, then the result is NaN. | |
2605 expected = *i; | |
2606 } else { | |
2607 expected = *j; | |
2608 } | |
2609 | |
2610 CHECK_FLOAT_EQ(expected, r.Call(*i, *j)); | |
2611 } | |
2612 } | 2570 } |
2613 } | 2571 } |
2614 | 2572 |
2615 WASM_EXEC_TEST(F64Max) { | 2573 WASM_EXEC_TEST(F64Max) { |
2616 WasmRunner<double> r(execution_mode, MachineType::Float64(), | 2574 WasmRunner<double> r(execution_mode, MachineType::Float64(), |
2617 MachineType::Float64()); | 2575 MachineType::Float64()); |
2618 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2576 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2619 | 2577 |
2620 FOR_FLOAT64_INPUTS(i) { | 2578 FOR_FLOAT64_INPUTS(i) { |
2621 FOR_FLOAT64_INPUTS(j) { | 2579 FOR_FLOAT64_INPUTS(j) { |
2622 double result = r.Call(*i, *j); | 2580 double result = r.Call(*i, *j); |
2623 if (std::isnan(*i) || std::isnan(*j)) { | 2581 CHECK_DOUBLE_EQ(JSMax(*i, *j), result); |
2624 // If one of the inputs is nan, the result should be nan. | |
2625 CHECK(std::isnan(result)); | |
2626 } else if ((*i == 0.0) && (*j == 0.0) && | |
2627 (copysign(1.0, *i) != copysign(1.0, *j))) { | |
2628 // If one input is +0.0 and the other input is -0.0, the result should | |
2629 // be -0.0. | |
2630 CHECK_EQ(bit_cast<uint64_t>(0.0), bit_cast<uint64_t>(result)); | |
2631 } else { | |
2632 double expected = *i > *j ? *i : *j; | |
2633 CHECK_DOUBLE_EQ(expected, result); | |
2634 } | |
2635 } | 2582 } |
2636 } | 2583 } |
2637 } | 2584 } |
2638 | 2585 |
2639 WASM_EXEC_TEST(I32SConvertF32) { | 2586 WASM_EXEC_TEST(I32SConvertF32) { |
2640 WasmRunner<int32_t> r(execution_mode, MachineType::Float32()); | 2587 WasmRunner<int32_t> r(execution_mode, MachineType::Float32()); |
2641 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0))); | 2588 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0))); |
2642 | 2589 |
2643 // The upper bound is (INT32_MAX + 1), which is the lowest float-representable | 2590 // The upper bound is (INT32_MAX + 1), which is the lowest float-representable |
2644 // number above INT32_MAX which cannot be represented as int32. | 2591 // number above INT32_MAX which cannot be represented as int32. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2769 MachineType::Int32()); | 2716 MachineType::Int32()); |
2770 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_ZERO); | 2717 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_ZERO); |
2771 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 2718 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
2772 CHECK_EQ(0, r.Call(133, 100)); | 2719 CHECK_EQ(0, r.Call(133, 100)); |
2773 CHECK_EQ(0, r.Call(kMin, -1)); | 2720 CHECK_EQ(0, r.Call(kMin, -1)); |
2774 CHECK_EQ(0, r.Call(0, 1)); | 2721 CHECK_EQ(0, r.Call(0, 1)); |
2775 CHECK_TRAP(r.Call(100, 0)); | 2722 CHECK_TRAP(r.Call(100, 0)); |
2776 CHECK_TRAP(r.Call(-1001, 0)); | 2723 CHECK_TRAP(r.Call(-1001, 0)); |
2777 CHECK_TRAP(r.Call(kMin, 0)); | 2724 CHECK_TRAP(r.Call(kMin, 0)); |
2778 } | 2725 } |
OLD | NEW |