OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 <functional> | 5 #include <functional> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "test/cctest/cctest.h" | 8 #include "test/cctest/cctest.h" |
9 #include "test/cctest/compiler/codegen-tester.h" | 9 #include "test/cctest/compiler/codegen-tester.h" |
10 #include "test/cctest/compiler/value-helper.h" | 10 #include "test/cctest/compiler/value-helper.h" |
(...skipping 3873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3884 | 3884 |
3885 | 3885 |
3886 static bool sadd_overflow(int32_t x, int32_t y, int32_t* val) { | 3886 static bool sadd_overflow(int32_t x, int32_t y, int32_t* val) { |
3887 int32_t v = | 3887 int32_t v = |
3888 static_cast<int32_t>(static_cast<uint32_t>(x) + static_cast<uint32_t>(y)); | 3888 static_cast<int32_t>(static_cast<uint32_t>(x) + static_cast<uint32_t>(y)); |
3889 *val = v; | 3889 *val = v; |
3890 return (((v ^ x) & (v ^ y)) >> 31) & 1; | 3890 return (((v ^ x) & (v ^ y)) >> 31) & 1; |
3891 } | 3891 } |
3892 | 3892 |
3893 | 3893 |
| 3894 static bool ssub_overflow(int32_t x, int32_t y, int32_t* val) { |
| 3895 int32_t v = |
| 3896 static_cast<int32_t>(static_cast<uint32_t>(x) - static_cast<uint32_t>(y)); |
| 3897 *val = v; |
| 3898 return (((v ^ x) & (v ^ ~y)) >> 31) & 1; |
| 3899 } |
| 3900 |
| 3901 |
3894 TEST(RunInt32AddWithOverflowP) { | 3902 TEST(RunInt32AddWithOverflowP) { |
3895 int32_t actual_val = -1; | 3903 int32_t actual_val = -1; |
3896 RawMachineAssemblerTester<int32_t> m; | 3904 RawMachineAssemblerTester<int32_t> m; |
3897 Int32BinopTester bt(&m); | 3905 Int32BinopTester bt(&m); |
3898 Node* val, *ovf; | 3906 Node* val, *ovf; |
3899 m.Int32AddWithOverflow(bt.param0, bt.param1, &val, &ovf); | 3907 m.Int32AddWithOverflow(bt.param0, bt.param1, &val, &ovf); |
3900 m.StoreToPointer(&actual_val, kMachineWord32, val); | 3908 m.StoreToPointer(&actual_val, kMachineWord32, val); |
3901 bt.AddReturn(ovf); | 3909 bt.AddReturn(ovf); |
3902 FOR_INT32_INPUTS(i) { | 3910 FOR_INT32_INPUTS(i) { |
3903 FOR_INT32_INPUTS(j) { | 3911 FOR_INT32_INPUTS(j) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3965 bt.AddReturn(val); | 3973 bt.AddReturn(val); |
3966 FOR_UINT32_INPUTS(i) { | 3974 FOR_UINT32_INPUTS(i) { |
3967 FOR_UINT32_INPUTS(j) { | 3975 FOR_UINT32_INPUTS(j) { |
3968 int32_t expected; | 3976 int32_t expected; |
3969 if (sadd_overflow(*i, *j, &expected)) expected = ~expected; | 3977 if (sadd_overflow(*i, *j, &expected)) expected = ~expected; |
3970 CHECK_EQ(expected, bt.call(*i, *j)); | 3978 CHECK_EQ(expected, bt.call(*i, *j)); |
3971 } | 3979 } |
3972 } | 3980 } |
3973 } | 3981 } |
3974 | 3982 |
| 3983 |
| 3984 TEST(RunInt32SubWithOverflowP) { |
| 3985 int32_t actual_val = -1; |
| 3986 RawMachineAssemblerTester<int32_t> m; |
| 3987 Int32BinopTester bt(&m); |
| 3988 Node* val, *ovf; |
| 3989 m.Int32SubWithOverflow(bt.param0, bt.param1, &val, &ovf); |
| 3990 m.StoreToPointer(&actual_val, kMachineWord32, val); |
| 3991 bt.AddReturn(ovf); |
| 3992 FOR_INT32_INPUTS(i) { |
| 3993 FOR_INT32_INPUTS(j) { |
| 3994 int32_t expected_val; |
| 3995 int expected_ovf = ssub_overflow(*i, *j, &expected_val); |
| 3996 CHECK_EQ(expected_ovf, bt.call(*i, *j)); |
| 3997 CHECK_EQ(expected_val, actual_val); |
| 3998 } |
| 3999 } |
| 4000 } |
| 4001 |
| 4002 |
| 4003 TEST(RunInt32SubWithOverflowImm) { |
| 4004 int32_t actual_val = -1, expected_val = 0; |
| 4005 FOR_INT32_INPUTS(i) { |
| 4006 { |
| 4007 RawMachineAssemblerTester<int32_t> m(kMachineWord32); |
| 4008 Node* val, *ovf; |
| 4009 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0), &val, &ovf); |
| 4010 m.StoreToPointer(&actual_val, kMachineWord32, val); |
| 4011 m.Return(ovf); |
| 4012 FOR_INT32_INPUTS(j) { |
| 4013 int expected_ovf = ssub_overflow(*i, *j, &expected_val); |
| 4014 CHECK_EQ(expected_ovf, m.Call(*j)); |
| 4015 CHECK_EQ(expected_val, actual_val); |
| 4016 } |
| 4017 } |
| 4018 { |
| 4019 RawMachineAssemblerTester<int32_t> m(kMachineWord32); |
| 4020 Node* val, *ovf; |
| 4021 m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i), &val, &ovf); |
| 4022 m.StoreToPointer(&actual_val, kMachineWord32, val); |
| 4023 m.Return(ovf); |
| 4024 FOR_INT32_INPUTS(j) { |
| 4025 int expected_ovf = ssub_overflow(*j, *i, &expected_val); |
| 4026 CHECK_EQ(expected_ovf, m.Call(*j)); |
| 4027 CHECK_EQ(expected_val, actual_val); |
| 4028 } |
| 4029 } |
| 4030 FOR_INT32_INPUTS(j) { |
| 4031 RawMachineAssemblerTester<int32_t> m; |
| 4032 Node* val, *ovf; |
| 4033 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j), &val, |
| 4034 &ovf); |
| 4035 m.StoreToPointer(&actual_val, kMachineWord32, val); |
| 4036 m.Return(ovf); |
| 4037 int expected_ovf = ssub_overflow(*i, *j, &expected_val); |
| 4038 CHECK_EQ(expected_ovf, m.Call()); |
| 4039 CHECK_EQ(expected_val, actual_val); |
| 4040 } |
| 4041 } |
| 4042 } |
| 4043 |
| 4044 |
| 4045 TEST(RunInt32SubWithOverflowInBranchP) { |
| 4046 MLabel blocka, blockb; |
| 4047 RawMachineAssemblerTester<int32_t> m; |
| 4048 Int32BinopTester bt(&m); |
| 4049 Node* val, *ovf; |
| 4050 m.Int32SubWithOverflow(bt.param0, bt.param1, &val, &ovf); |
| 4051 m.Branch(ovf, &blocka, &blockb); |
| 4052 m.Bind(&blocka); |
| 4053 bt.AddReturn(m.Word32Not(val)); |
| 4054 m.Bind(&blockb); |
| 4055 bt.AddReturn(val); |
| 4056 FOR_UINT32_INPUTS(i) { |
| 4057 FOR_UINT32_INPUTS(j) { |
| 4058 int32_t expected; |
| 4059 if (ssub_overflow(*i, *j, &expected)) expected = ~expected; |
| 4060 CHECK_EQ(expected, bt.call(*i, *j)); |
| 4061 } |
| 4062 } |
| 4063 } |
| 4064 |
3975 #endif // V8_TURBOFAN_TARGET | 4065 #endif // V8_TURBOFAN_TARGET |
OLD | NEW |