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 "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/compiler/generic-node-inl.h" | 9 #include "src/compiler/generic-node-inl.h" |
10 #include "test/cctest/cctest.h" | 10 #include "test/cctest/cctest.h" |
(...skipping 3998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4009 m.Return(one); | 4009 m.Return(one); |
4010 m.Call(); | 4010 m.Call(); |
4011 for (int i = 0; i < kInputSize; i++) { | 4011 for (int i = 0; i < kInputSize; i++) { |
4012 CHECK_EQ(outputs[i], i + 2); | 4012 CHECK_EQ(outputs[i], i + 2); |
4013 } | 4013 } |
4014 } | 4014 } |
4015 | 4015 |
4016 #endif // MACHINE_ASSEMBLER_SUPPORTS_CALL_C | 4016 #endif // MACHINE_ASSEMBLER_SUPPORTS_CALL_C |
4017 | 4017 |
4018 | 4018 |
4019 static bool sadd_overflow(int32_t x, int32_t y, int32_t* val) { | |
4020 int32_t v = | |
4021 static_cast<int32_t>(static_cast<uint32_t>(x) + static_cast<uint32_t>(y)); | |
4022 *val = v; | |
4023 return (((v ^ x) & (v ^ y)) >> 31) & 1; | |
4024 } | |
4025 | |
4026 | |
4027 static bool ssub_overflow(int32_t x, int32_t y, int32_t* val) { | |
4028 int32_t v = | |
4029 static_cast<int32_t>(static_cast<uint32_t>(x) - static_cast<uint32_t>(y)); | |
4030 *val = v; | |
4031 return (((v ^ x) & (v ^ ~y)) >> 31) & 1; | |
4032 } | |
4033 | |
4034 | |
4035 TEST(RunInt32AddWithOverflowP) { | 4019 TEST(RunInt32AddWithOverflowP) { |
4036 int32_t actual_val = -1; | 4020 int32_t actual_val = -1; |
4037 RawMachineAssemblerTester<int32_t> m; | 4021 RawMachineAssemblerTester<int32_t> m; |
4038 Int32BinopTester bt(&m); | 4022 Int32BinopTester bt(&m); |
4039 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); | 4023 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); |
4040 Node* val = m.Projection(0, add); | 4024 Node* val = m.Projection(0, add); |
4041 Node* ovf = m.Projection(1, add); | 4025 Node* ovf = m.Projection(1, add); |
4042 m.StoreToPointer(&actual_val, kMachInt32, val); | 4026 m.StoreToPointer(&actual_val, kMachInt32, val); |
4043 bt.AddReturn(ovf); | 4027 bt.AddReturn(ovf); |
4044 FOR_INT32_INPUTS(i) { | 4028 FOR_INT32_INPUTS(i) { |
4045 FOR_INT32_INPUTS(j) { | 4029 FOR_INT32_INPUTS(j) { |
4046 int32_t expected_val; | 4030 int32_t expected_val; |
4047 int expected_ovf = sadd_overflow(*i, *j, &expected_val); | 4031 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); |
4048 CHECK_EQ(expected_ovf, bt.call(*i, *j)); | 4032 CHECK_EQ(expected_ovf, bt.call(*i, *j)); |
4049 CHECK_EQ(expected_val, actual_val); | 4033 CHECK_EQ(expected_val, actual_val); |
4050 } | 4034 } |
4051 } | 4035 } |
4052 } | 4036 } |
4053 | 4037 |
4054 | 4038 |
4055 TEST(RunInt32AddWithOverflowImm) { | 4039 TEST(RunInt32AddWithOverflowImm) { |
4056 int32_t actual_val = -1, expected_val = 0; | 4040 int32_t actual_val = -1, expected_val = 0; |
4057 FOR_INT32_INPUTS(i) { | 4041 FOR_INT32_INPUTS(i) { |
4058 { | 4042 { |
4059 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 4043 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
4060 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0)); | 4044 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0)); |
4061 Node* val = m.Projection(0, add); | 4045 Node* val = m.Projection(0, add); |
4062 Node* ovf = m.Projection(1, add); | 4046 Node* ovf = m.Projection(1, add); |
4063 m.StoreToPointer(&actual_val, kMachInt32, val); | 4047 m.StoreToPointer(&actual_val, kMachInt32, val); |
4064 m.Return(ovf); | 4048 m.Return(ovf); |
4065 FOR_INT32_INPUTS(j) { | 4049 FOR_INT32_INPUTS(j) { |
4066 int expected_ovf = sadd_overflow(*i, *j, &expected_val); | 4050 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); |
4067 CHECK_EQ(expected_ovf, m.Call(*j)); | 4051 CHECK_EQ(expected_ovf, m.Call(*j)); |
4068 CHECK_EQ(expected_val, actual_val); | 4052 CHECK_EQ(expected_val, actual_val); |
4069 } | 4053 } |
4070 } | 4054 } |
4071 { | 4055 { |
4072 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 4056 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
4073 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i)); | 4057 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i)); |
4074 Node* val = m.Projection(0, add); | 4058 Node* val = m.Projection(0, add); |
4075 Node* ovf = m.Projection(1, add); | 4059 Node* ovf = m.Projection(1, add); |
4076 m.StoreToPointer(&actual_val, kMachInt32, val); | 4060 m.StoreToPointer(&actual_val, kMachInt32, val); |
4077 m.Return(ovf); | 4061 m.Return(ovf); |
4078 FOR_INT32_INPUTS(j) { | 4062 FOR_INT32_INPUTS(j) { |
4079 int expected_ovf = sadd_overflow(*i, *j, &expected_val); | 4063 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); |
4080 CHECK_EQ(expected_ovf, m.Call(*j)); | 4064 CHECK_EQ(expected_ovf, m.Call(*j)); |
4081 CHECK_EQ(expected_val, actual_val); | 4065 CHECK_EQ(expected_val, actual_val); |
4082 } | 4066 } |
4083 } | 4067 } |
4084 FOR_INT32_INPUTS(j) { | 4068 FOR_INT32_INPUTS(j) { |
4085 RawMachineAssemblerTester<int32_t> m; | 4069 RawMachineAssemblerTester<int32_t> m; |
4086 Node* add = | 4070 Node* add = |
4087 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); | 4071 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); |
4088 Node* val = m.Projection(0, add); | 4072 Node* val = m.Projection(0, add); |
4089 Node* ovf = m.Projection(1, add); | 4073 Node* ovf = m.Projection(1, add); |
4090 m.StoreToPointer(&actual_val, kMachInt32, val); | 4074 m.StoreToPointer(&actual_val, kMachInt32, val); |
4091 m.Return(ovf); | 4075 m.Return(ovf); |
4092 int expected_ovf = sadd_overflow(*i, *j, &expected_val); | 4076 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); |
4093 CHECK_EQ(expected_ovf, m.Call()); | 4077 CHECK_EQ(expected_ovf, m.Call()); |
4094 CHECK_EQ(expected_val, actual_val); | 4078 CHECK_EQ(expected_val, actual_val); |
4095 } | 4079 } |
4096 } | 4080 } |
4097 } | 4081 } |
4098 | 4082 |
4099 | 4083 |
4100 TEST(RunInt32AddWithOverflowInBranchP) { | 4084 TEST(RunInt32AddWithOverflowInBranchP) { |
4101 int constant = 911777; | 4085 int constant = 911777; |
4102 MLabel blocka, blockb; | 4086 MLabel blocka, blockb; |
4103 RawMachineAssemblerTester<int32_t> m; | 4087 RawMachineAssemblerTester<int32_t> m; |
4104 Int32BinopTester bt(&m); | 4088 Int32BinopTester bt(&m); |
4105 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); | 4089 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); |
4106 Node* ovf = m.Projection(1, add); | 4090 Node* ovf = m.Projection(1, add); |
4107 m.Branch(ovf, &blocka, &blockb); | 4091 m.Branch(ovf, &blocka, &blockb); |
4108 m.Bind(&blocka); | 4092 m.Bind(&blocka); |
4109 bt.AddReturn(m.Int32Constant(constant)); | 4093 bt.AddReturn(m.Int32Constant(constant)); |
4110 m.Bind(&blockb); | 4094 m.Bind(&blockb); |
4111 Node* val = m.Projection(0, add); | 4095 Node* val = m.Projection(0, add); |
4112 bt.AddReturn(val); | 4096 bt.AddReturn(val); |
4113 FOR_INT32_INPUTS(i) { | 4097 FOR_INT32_INPUTS(i) { |
4114 FOR_INT32_INPUTS(j) { | 4098 FOR_INT32_INPUTS(j) { |
4115 int32_t expected; | 4099 int32_t expected; |
4116 if (sadd_overflow(*i, *j, &expected)) expected = constant; | 4100 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant; |
4117 CHECK_EQ(expected, bt.call(*i, *j)); | 4101 CHECK_EQ(expected, bt.call(*i, *j)); |
4118 } | 4102 } |
4119 } | 4103 } |
4120 } | 4104 } |
4121 | 4105 |
4122 | 4106 |
4123 TEST(RunInt32SubWithOverflowP) { | 4107 TEST(RunInt32SubWithOverflowP) { |
4124 int32_t actual_val = -1; | 4108 int32_t actual_val = -1; |
4125 RawMachineAssemblerTester<int32_t> m; | 4109 RawMachineAssemblerTester<int32_t> m; |
4126 Int32BinopTester bt(&m); | 4110 Int32BinopTester bt(&m); |
4127 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1); | 4111 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1); |
4128 Node* val = m.Projection(0, add); | 4112 Node* val = m.Projection(0, add); |
4129 Node* ovf = m.Projection(1, add); | 4113 Node* ovf = m.Projection(1, add); |
4130 m.StoreToPointer(&actual_val, kMachInt32, val); | 4114 m.StoreToPointer(&actual_val, kMachInt32, val); |
4131 bt.AddReturn(ovf); | 4115 bt.AddReturn(ovf); |
4132 FOR_INT32_INPUTS(i) { | 4116 FOR_INT32_INPUTS(i) { |
4133 FOR_INT32_INPUTS(j) { | 4117 FOR_INT32_INPUTS(j) { |
4134 int32_t expected_val; | 4118 int32_t expected_val; |
4135 int expected_ovf = ssub_overflow(*i, *j, &expected_val); | 4119 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); |
4136 CHECK_EQ(expected_ovf, bt.call(*i, *j)); | 4120 CHECK_EQ(expected_ovf, bt.call(*i, *j)); |
4137 CHECK_EQ(expected_val, actual_val); | 4121 CHECK_EQ(expected_val, actual_val); |
4138 } | 4122 } |
4139 } | 4123 } |
4140 } | 4124 } |
4141 | 4125 |
4142 | 4126 |
4143 TEST(RunInt32SubWithOverflowImm) { | 4127 TEST(RunInt32SubWithOverflowImm) { |
4144 int32_t actual_val = -1, expected_val = 0; | 4128 int32_t actual_val = -1, expected_val = 0; |
4145 FOR_INT32_INPUTS(i) { | 4129 FOR_INT32_INPUTS(i) { |
4146 { | 4130 { |
4147 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 4131 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
4148 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0)); | 4132 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0)); |
4149 Node* val = m.Projection(0, add); | 4133 Node* val = m.Projection(0, add); |
4150 Node* ovf = m.Projection(1, add); | 4134 Node* ovf = m.Projection(1, add); |
4151 m.StoreToPointer(&actual_val, kMachInt32, val); | 4135 m.StoreToPointer(&actual_val, kMachInt32, val); |
4152 m.Return(ovf); | 4136 m.Return(ovf); |
4153 FOR_INT32_INPUTS(j) { | 4137 FOR_INT32_INPUTS(j) { |
4154 int expected_ovf = ssub_overflow(*i, *j, &expected_val); | 4138 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); |
4155 CHECK_EQ(expected_ovf, m.Call(*j)); | 4139 CHECK_EQ(expected_ovf, m.Call(*j)); |
4156 CHECK_EQ(expected_val, actual_val); | 4140 CHECK_EQ(expected_val, actual_val); |
4157 } | 4141 } |
4158 } | 4142 } |
4159 { | 4143 { |
4160 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 4144 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
4161 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i)); | 4145 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i)); |
4162 Node* val = m.Projection(0, add); | 4146 Node* val = m.Projection(0, add); |
4163 Node* ovf = m.Projection(1, add); | 4147 Node* ovf = m.Projection(1, add); |
4164 m.StoreToPointer(&actual_val, kMachInt32, val); | 4148 m.StoreToPointer(&actual_val, kMachInt32, val); |
4165 m.Return(ovf); | 4149 m.Return(ovf); |
4166 FOR_INT32_INPUTS(j) { | 4150 FOR_INT32_INPUTS(j) { |
4167 int expected_ovf = ssub_overflow(*j, *i, &expected_val); | 4151 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val); |
4168 CHECK_EQ(expected_ovf, m.Call(*j)); | 4152 CHECK_EQ(expected_ovf, m.Call(*j)); |
4169 CHECK_EQ(expected_val, actual_val); | 4153 CHECK_EQ(expected_val, actual_val); |
4170 } | 4154 } |
4171 } | 4155 } |
4172 FOR_INT32_INPUTS(j) { | 4156 FOR_INT32_INPUTS(j) { |
4173 RawMachineAssemblerTester<int32_t> m; | 4157 RawMachineAssemblerTester<int32_t> m; |
4174 Node* add = | 4158 Node* add = |
4175 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); | 4159 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); |
4176 Node* val = m.Projection(0, add); | 4160 Node* val = m.Projection(0, add); |
4177 Node* ovf = m.Projection(1, add); | 4161 Node* ovf = m.Projection(1, add); |
4178 m.StoreToPointer(&actual_val, kMachInt32, val); | 4162 m.StoreToPointer(&actual_val, kMachInt32, val); |
4179 m.Return(ovf); | 4163 m.Return(ovf); |
4180 int expected_ovf = ssub_overflow(*i, *j, &expected_val); | 4164 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); |
4181 CHECK_EQ(expected_ovf, m.Call()); | 4165 CHECK_EQ(expected_ovf, m.Call()); |
4182 CHECK_EQ(expected_val, actual_val); | 4166 CHECK_EQ(expected_val, actual_val); |
4183 } | 4167 } |
4184 } | 4168 } |
4185 } | 4169 } |
4186 | 4170 |
4187 | 4171 |
4188 TEST(RunInt32SubWithOverflowInBranchP) { | 4172 TEST(RunInt32SubWithOverflowInBranchP) { |
4189 int constant = 911999; | 4173 int constant = 911999; |
4190 MLabel blocka, blockb; | 4174 MLabel blocka, blockb; |
4191 RawMachineAssemblerTester<int32_t> m; | 4175 RawMachineAssemblerTester<int32_t> m; |
4192 Int32BinopTester bt(&m); | 4176 Int32BinopTester bt(&m); |
4193 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1); | 4177 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1); |
4194 Node* ovf = m.Projection(1, sub); | 4178 Node* ovf = m.Projection(1, sub); |
4195 m.Branch(ovf, &blocka, &blockb); | 4179 m.Branch(ovf, &blocka, &blockb); |
4196 m.Bind(&blocka); | 4180 m.Bind(&blocka); |
4197 bt.AddReturn(m.Int32Constant(constant)); | 4181 bt.AddReturn(m.Int32Constant(constant)); |
4198 m.Bind(&blockb); | 4182 m.Bind(&blockb); |
4199 Node* val = m.Projection(0, sub); | 4183 Node* val = m.Projection(0, sub); |
4200 bt.AddReturn(val); | 4184 bt.AddReturn(val); |
4201 FOR_INT32_INPUTS(i) { | 4185 FOR_INT32_INPUTS(i) { |
4202 FOR_INT32_INPUTS(j) { | 4186 FOR_INT32_INPUTS(j) { |
4203 int32_t expected; | 4187 int32_t expected; |
4204 if (ssub_overflow(*i, *j, &expected)) expected = constant; | 4188 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant; |
4205 CHECK_EQ(expected, bt.call(*i, *j)); | 4189 CHECK_EQ(expected, bt.call(*i, *j)); |
4206 } | 4190 } |
4207 } | 4191 } |
4208 } | 4192 } |
4209 | 4193 |
4210 | 4194 |
4211 TEST(RunChangeInt32ToInt64P) { | 4195 TEST(RunChangeInt32ToInt64P) { |
4212 if (kPointerSize < 8) return; | 4196 if (kPointerSize < 8) return; |
4213 int64_t actual = -1; | 4197 int64_t actual = -1; |
4214 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 4198 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4314 RawMachineAssemblerTester<int32_t> m; | 4298 RawMachineAssemblerTester<int32_t> m; |
4315 m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64))); | 4299 m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64))); |
4316 for (size_t i = 0; i < arraysize(kValues); ++i) { | 4300 for (size_t i = 0; i < arraysize(kValues); ++i) { |
4317 input = kValues[i].from; | 4301 input = kValues[i].from; |
4318 uint64_t expected = static_cast<int64_t>(kValues[i].raw); | 4302 uint64_t expected = static_cast<int64_t>(kValues[i].raw); |
4319 CHECK_EQ(static_cast<int>(expected), m.Call()); | 4303 CHECK_EQ(static_cast<int>(expected), m.Call()); |
4320 } | 4304 } |
4321 } | 4305 } |
4322 | 4306 |
4323 #endif // V8_TURBOFAN_TARGET | 4307 #endif // V8_TURBOFAN_TARGET |
OLD | NEW |