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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/change-lowering.h" | 8 #include "src/compiler/change-lowering.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/graph-reducer.h" | 10 #include "src/compiler/graph-reducer.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 103 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
104 NodeProperties::SetBounds(loaded, Bounds(Type::Number())); | 104 NodeProperties::SetBounds(loaded, Bounds(Type::Number())); |
105 Node* convert = t.NumberToInt32(loaded); | 105 Node* convert = t.NumberToInt32(loaded); |
106 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), | 106 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), |
107 kMachInt32}; | 107 kMachInt32}; |
108 t.StoreField(store, t.PointerConstant(&result), convert); | 108 t.StoreField(store, t.PointerConstant(&result), convert); |
109 t.Return(t.jsgraph.TrueConstant()); | 109 t.Return(t.jsgraph.TrueConstant()); |
110 t.LowerAllNodes(); | 110 t.LowerAllNodes(); |
111 t.GenerateCode(); | 111 t.GenerateCode(); |
112 | 112 |
113 if (Pipeline::SupportedTarget()) { | |
114 FOR_FLOAT64_INPUTS(i) { | 113 FOR_FLOAT64_INPUTS(i) { |
115 input = *i; | 114 input = *i; |
116 int32_t expected = DoubleToInt32(*i); | 115 int32_t expected = DoubleToInt32(*i); |
117 t.Call(); | 116 t.Call(); |
118 CHECK_EQ(expected, result); | 117 CHECK_EQ(expected, result); |
119 } | 118 } |
120 } | |
121 } | 119 } |
122 | 120 |
123 | 121 |
124 // TODO(titzer): test tagged representation for input to NumberToUint32. | 122 // TODO(titzer): test tagged representation for input to NumberToUint32. |
125 TEST(RunNumberToUint32_float64) { | 123 TEST(RunNumberToUint32_float64) { |
126 // TODO(titzer): explicit load/stores here are only because of representations | 124 // TODO(titzer): explicit load/stores here are only because of representations |
127 double input; | 125 double input; |
128 uint32_t result; | 126 uint32_t result; |
129 SimplifiedLoweringTester<Object*> t; | 127 SimplifiedLoweringTester<Object*> t; |
130 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 128 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
131 kMachFloat64}; | 129 kMachFloat64}; |
132 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 130 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
133 NodeProperties::SetBounds(loaded, Bounds(Type::Number())); | 131 NodeProperties::SetBounds(loaded, Bounds(Type::Number())); |
134 Node* convert = t.NumberToUint32(loaded); | 132 Node* convert = t.NumberToUint32(loaded); |
135 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), | 133 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), |
136 kMachUint32}; | 134 kMachUint32}; |
137 t.StoreField(store, t.PointerConstant(&result), convert); | 135 t.StoreField(store, t.PointerConstant(&result), convert); |
138 t.Return(t.jsgraph.TrueConstant()); | 136 t.Return(t.jsgraph.TrueConstant()); |
139 t.LowerAllNodes(); | 137 t.LowerAllNodes(); |
140 t.GenerateCode(); | 138 t.GenerateCode(); |
141 | 139 |
142 if (Pipeline::SupportedTarget()) { | |
143 FOR_FLOAT64_INPUTS(i) { | 140 FOR_FLOAT64_INPUTS(i) { |
144 input = *i; | 141 input = *i; |
145 uint32_t expected = DoubleToUint32(*i); | 142 uint32_t expected = DoubleToUint32(*i); |
146 t.Call(); | 143 t.Call(); |
147 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); | 144 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); |
148 } | 145 } |
149 } | 146 } |
150 } | |
151 | 147 |
152 | 148 |
153 // Create a simple JSObject with a unique map. | 149 // Create a simple JSObject with a unique map. |
154 static Handle<JSObject> TestObject() { | 150 static Handle<JSObject> TestObject() { |
155 static int index = 0; | 151 static int index = 0; |
156 char buffer[50]; | 152 char buffer[50]; |
157 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 153 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
158 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); | 154 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); |
159 } | 155 } |
160 | 156 |
161 | 157 |
162 TEST(RunLoadMap) { | 158 TEST(RunLoadMap) { |
163 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 159 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
164 FieldAccess access = AccessBuilder::ForMap(); | 160 FieldAccess access = AccessBuilder::ForMap(); |
165 Node* load = t.LoadField(access, t.Parameter(0)); | 161 Node* load = t.LoadField(access, t.Parameter(0)); |
166 t.Return(load); | 162 t.Return(load); |
167 | 163 |
168 t.LowerAllNodes(); | 164 t.LowerAllNodes(); |
169 t.GenerateCode(); | 165 t.GenerateCode(); |
170 | 166 |
171 if (Pipeline::SupportedTarget()) { | 167 Handle<JSObject> src = TestObject(); |
172 Handle<JSObject> src = TestObject(); | 168 Handle<Map> src_map(src->map()); |
173 Handle<Map> src_map(src->map()); | 169 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
174 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 170 CHECK_EQ(*src_map, result); |
175 CHECK_EQ(*src_map, result); | |
176 } | |
177 } | 171 } |
178 | 172 |
179 | 173 |
180 TEST(RunStoreMap) { | 174 TEST(RunStoreMap) { |
181 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); | 175 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); |
182 FieldAccess access = AccessBuilder::ForMap(); | 176 FieldAccess access = AccessBuilder::ForMap(); |
183 t.StoreField(access, t.Parameter(1), t.Parameter(0)); | 177 t.StoreField(access, t.Parameter(1), t.Parameter(0)); |
184 t.Return(t.jsgraph.TrueConstant()); | 178 t.Return(t.jsgraph.TrueConstant()); |
185 | 179 |
186 t.LowerAllNodes(); | 180 t.LowerAllNodes(); |
187 t.GenerateCode(); | 181 t.GenerateCode(); |
188 | 182 |
189 if (Pipeline::SupportedTarget()) { | |
190 Handle<JSObject> src = TestObject(); | 183 Handle<JSObject> src = TestObject(); |
191 Handle<Map> src_map(src->map()); | 184 Handle<Map> src_map(src->map()); |
192 Handle<JSObject> dst = TestObject(); | 185 Handle<JSObject> dst = TestObject(); |
193 CHECK(src->map() != dst->map()); | 186 CHECK(src->map() != dst->map()); |
194 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call | 187 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call |
195 CHECK(*src_map == dst->map()); | 188 CHECK(*src_map == dst->map()); |
196 } | 189 } |
197 } | |
198 | 190 |
199 | 191 |
200 TEST(RunLoadProperties) { | 192 TEST(RunLoadProperties) { |
201 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 193 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
202 FieldAccess access = AccessBuilder::ForJSObjectProperties(); | 194 FieldAccess access = AccessBuilder::ForJSObjectProperties(); |
203 Node* load = t.LoadField(access, t.Parameter(0)); | 195 Node* load = t.LoadField(access, t.Parameter(0)); |
204 t.Return(load); | 196 t.Return(load); |
205 | 197 |
206 t.LowerAllNodes(); | 198 t.LowerAllNodes(); |
207 t.GenerateCode(); | 199 t.GenerateCode(); |
208 | 200 |
209 if (Pipeline::SupportedTarget()) { | |
210 Handle<JSObject> src = TestObject(); | 201 Handle<JSObject> src = TestObject(); |
211 Handle<FixedArray> src_props(src->properties()); | 202 Handle<FixedArray> src_props(src->properties()); |
212 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 203 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
213 CHECK_EQ(*src_props, result); | 204 CHECK_EQ(*src_props, result); |
214 } | |
215 } | 205 } |
216 | 206 |
217 | 207 |
218 TEST(RunLoadStoreMap) { | 208 TEST(RunLoadStoreMap) { |
219 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); | 209 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); |
220 FieldAccess access = AccessBuilder::ForMap(); | 210 FieldAccess access = AccessBuilder::ForMap(); |
221 Node* load = t.LoadField(access, t.Parameter(0)); | 211 Node* load = t.LoadField(access, t.Parameter(0)); |
222 t.StoreField(access, t.Parameter(1), load); | 212 t.StoreField(access, t.Parameter(1), load); |
223 t.Return(load); | 213 t.Return(load); |
224 | 214 |
225 t.LowerAllNodes(); | 215 t.LowerAllNodes(); |
226 t.GenerateCode(); | 216 t.GenerateCode(); |
227 | 217 |
228 if (Pipeline::SupportedTarget()) { | |
229 Handle<JSObject> src = TestObject(); | 218 Handle<JSObject> src = TestObject(); |
230 Handle<Map> src_map(src->map()); | 219 Handle<Map> src_map(src->map()); |
231 Handle<JSObject> dst = TestObject(); | 220 Handle<JSObject> dst = TestObject(); |
232 CHECK(src->map() != dst->map()); | 221 CHECK(src->map() != dst->map()); |
233 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call | 222 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call |
234 CHECK(result->IsMap()); | 223 CHECK(result->IsMap()); |
235 CHECK_EQ(*src_map, result); | 224 CHECK_EQ(*src_map, result); |
236 CHECK(*src_map == dst->map()); | 225 CHECK(*src_map == dst->map()); |
237 } | |
238 } | 226 } |
239 | 227 |
240 | 228 |
241 TEST(RunLoadStoreFixedArrayIndex) { | 229 TEST(RunLoadStoreFixedArrayIndex) { |
242 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 230 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
243 ElementAccess access = AccessBuilder::ForFixedArrayElement(); | 231 ElementAccess access = AccessBuilder::ForFixedArrayElement(); |
244 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); | 232 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
245 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); | 233 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
246 t.Return(load); | 234 t.Return(load); |
247 | 235 |
248 t.LowerAllNodes(); | 236 t.LowerAllNodes(); |
249 t.GenerateCode(); | 237 t.GenerateCode(); |
250 | 238 |
251 if (Pipeline::SupportedTarget()) { | |
252 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 239 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
253 Handle<JSObject> src = TestObject(); | 240 Handle<JSObject> src = TestObject(); |
254 Handle<JSObject> dst = TestObject(); | 241 Handle<JSObject> dst = TestObject(); |
255 array->set(0, *src); | 242 array->set(0, *src); |
256 array->set(1, *dst); | 243 array->set(1, *dst); |
257 Object* result = t.Call(*array); | 244 Object* result = t.Call(*array); |
258 CHECK_EQ(*src, result); | 245 CHECK_EQ(*src, result); |
259 CHECK_EQ(*src, array->get(0)); | 246 CHECK_EQ(*src, array->get(0)); |
260 CHECK_EQ(*src, array->get(1)); | 247 CHECK_EQ(*src, array->get(1)); |
261 } | |
262 } | 248 } |
263 | 249 |
264 | 250 |
265 TEST(RunLoadStoreArrayBuffer) { | 251 TEST(RunLoadStoreArrayBuffer) { |
266 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 252 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
267 const int index = 12; | 253 const int index = 12; |
268 const int array_length = 2 * index; | 254 const int array_length = 2 * index; |
269 ElementAccess buffer_access = | 255 ElementAccess buffer_access = |
270 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true); | 256 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true); |
271 Node* backing_store = t.LoadField( | 257 Node* backing_store = t.LoadField( |
272 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); | 258 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); |
273 Node* load = | 259 Node* load = |
274 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); | 260 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
275 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 261 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
276 load); | 262 load); |
277 t.Return(t.jsgraph.TrueConstant()); | 263 t.Return(t.jsgraph.TrueConstant()); |
278 | 264 |
279 t.LowerAllNodes(); | 265 t.LowerAllNodes(); |
280 t.GenerateCode(); | 266 t.GenerateCode(); |
281 | 267 |
282 if (Pipeline::SupportedTarget()) { | |
283 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); | 268 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); |
284 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); | 269 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); |
285 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); | 270 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); |
286 for (int i = 0; i < array_length; i++) { | 271 for (int i = 0; i < array_length; i++) { |
287 data[i] = i; | 272 data[i] = i; |
288 } | 273 } |
289 | 274 |
290 // TODO(titzer): raw pointers in call | 275 // TODO(titzer): raw pointers in call |
291 Object* result = t.Call(*array); | 276 Object* result = t.Call(*array); |
292 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 277 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
293 for (int i = 0; i < array_length; i++) { | 278 for (int i = 0; i < array_length; i++) { |
294 uint8_t expected = i; | 279 uint8_t expected = i; |
295 if (i == (index + 1)) expected = index; | 280 if (i == (index + 1)) expected = index; |
296 CHECK_EQ(data[i], expected); | 281 CHECK_EQ(data[i], expected); |
297 } | 282 } |
298 } | 283 } |
299 } | |
300 | 284 |
301 | 285 |
302 TEST(RunLoadFieldFromUntaggedBase) { | 286 TEST(RunLoadFieldFromUntaggedBase) { |
303 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 287 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
304 | 288 |
305 for (size_t i = 0; i < arraysize(smis); i++) { | 289 for (size_t i = 0; i < arraysize(smis); i++) { |
306 int offset = static_cast<int>(i * sizeof(Smi*)); | 290 int offset = static_cast<int>(i * sizeof(Smi*)); |
307 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 291 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), |
308 Type::Integral32(), kMachAnyTagged}; | 292 Type::Integral32(), kMachAnyTagged}; |
309 | 293 |
310 SimplifiedLoweringTester<Object*> t; | 294 SimplifiedLoweringTester<Object*> t; |
311 Node* load = t.LoadField(access, t.PointerConstant(smis)); | 295 Node* load = t.LoadField(access, t.PointerConstant(smis)); |
312 t.Return(load); | 296 t.Return(load); |
313 t.LowerAllNodes(); | 297 t.LowerAllNodes(); |
314 | 298 |
315 if (!Pipeline::SupportedTarget()) continue; | |
316 | |
317 for (int j = -5; j <= 5; j++) { | 299 for (int j = -5; j <= 5; j++) { |
318 Smi* expected = Smi::FromInt(j); | 300 Smi* expected = Smi::FromInt(j); |
319 smis[i] = expected; | 301 smis[i] = expected; |
320 CHECK_EQ(expected, t.Call()); | 302 CHECK_EQ(expected, t.Call()); |
321 } | 303 } |
322 } | 304 } |
323 } | 305 } |
324 | 306 |
325 | 307 |
326 TEST(RunStoreFieldToUntaggedBase) { | 308 TEST(RunStoreFieldToUntaggedBase) { |
327 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 309 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
328 | 310 |
329 for (size_t i = 0; i < arraysize(smis); i++) { | 311 for (size_t i = 0; i < arraysize(smis); i++) { |
330 int offset = static_cast<int>(i * sizeof(Smi*)); | 312 int offset = static_cast<int>(i * sizeof(Smi*)); |
331 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 313 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), |
332 Type::Integral32(), kMachAnyTagged}; | 314 Type::Integral32(), kMachAnyTagged}; |
333 | 315 |
334 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 316 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
335 Node* p0 = t.Parameter(0); | 317 Node* p0 = t.Parameter(0); |
336 t.StoreField(access, t.PointerConstant(smis), p0); | 318 t.StoreField(access, t.PointerConstant(smis), p0); |
337 t.Return(p0); | 319 t.Return(p0); |
338 t.LowerAllNodes(); | 320 t.LowerAllNodes(); |
339 | 321 |
340 if (!Pipeline::SupportedTarget()) continue; | |
341 | |
342 for (int j = -5; j <= 5; j++) { | 322 for (int j = -5; j <= 5; j++) { |
343 Smi* expected = Smi::FromInt(j); | 323 Smi* expected = Smi::FromInt(j); |
344 smis[i] = Smi::FromInt(-100); | 324 smis[i] = Smi::FromInt(-100); |
345 CHECK_EQ(expected, t.Call(expected)); | 325 CHECK_EQ(expected, t.Call(expected)); |
346 CHECK_EQ(expected, smis[i]); | 326 CHECK_EQ(expected, smis[i]); |
347 } | 327 } |
348 } | 328 } |
349 } | 329 } |
350 | 330 |
351 | 331 |
352 TEST(RunLoadElementFromUntaggedBase) { | 332 TEST(RunLoadElementFromUntaggedBase) { |
353 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 333 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
354 Smi::FromInt(4), Smi::FromInt(5)}; | 334 Smi::FromInt(4), Smi::FromInt(5)}; |
355 | 335 |
356 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 336 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
357 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 337 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
358 int offset = static_cast<int>(i * sizeof(Smi*)); | 338 int offset = static_cast<int>(i * sizeof(Smi*)); |
359 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 339 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
360 kMachAnyTagged}; | 340 kMachAnyTagged}; |
361 | 341 |
362 SimplifiedLoweringTester<Object*> t; | 342 SimplifiedLoweringTester<Object*> t; |
363 Node* load = t.LoadElement(access, t.PointerConstant(smis), | 343 Node* load = t.LoadElement(access, t.PointerConstant(smis), |
364 t.Int32Constant(static_cast<int>(j))); | 344 t.Int32Constant(static_cast<int>(j))); |
365 t.Return(load); | 345 t.Return(load); |
366 t.LowerAllNodes(); | 346 t.LowerAllNodes(); |
367 | 347 |
368 if (!Pipeline::SupportedTarget()) continue; | |
369 | |
370 for (int k = -5; k <= 5; k++) { | 348 for (int k = -5; k <= 5; k++) { |
371 Smi* expected = Smi::FromInt(k); | 349 Smi* expected = Smi::FromInt(k); |
372 smis[i + j] = expected; | 350 smis[i + j] = expected; |
373 CHECK_EQ(expected, t.Call()); | 351 CHECK_EQ(expected, t.Call()); |
374 } | 352 } |
375 } | 353 } |
376 } | 354 } |
377 } | 355 } |
378 | 356 |
379 | 357 |
380 TEST(RunStoreElementFromUntaggedBase) { | 358 TEST(RunStoreElementFromUntaggedBase) { |
381 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 359 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
382 Smi::FromInt(4), Smi::FromInt(5)}; | 360 Smi::FromInt(4), Smi::FromInt(5)}; |
383 | 361 |
384 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 362 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
385 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 363 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
386 int offset = static_cast<int>(i * sizeof(Smi*)); | 364 int offset = static_cast<int>(i * sizeof(Smi*)); |
387 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 365 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
388 kMachAnyTagged}; | 366 kMachAnyTagged}; |
389 | 367 |
390 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 368 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
391 Node* p0 = t.Parameter(0); | 369 Node* p0 = t.Parameter(0); |
392 t.StoreElement(access, t.PointerConstant(smis), | 370 t.StoreElement(access, t.PointerConstant(smis), |
393 t.Int32Constant(static_cast<int>(j)), p0); | 371 t.Int32Constant(static_cast<int>(j)), p0); |
394 t.Return(p0); | 372 t.Return(p0); |
395 t.LowerAllNodes(); | 373 t.LowerAllNodes(); |
396 | 374 |
397 if (!Pipeline::SupportedTarget()) continue; | |
398 | |
399 for (int k = -5; k <= 5; k++) { | 375 for (int k = -5; k <= 5; k++) { |
400 Smi* expected = Smi::FromInt(k); | 376 Smi* expected = Smi::FromInt(k); |
401 smis[i + j] = Smi::FromInt(-100); | 377 smis[i + j] = Smi::FromInt(-100); |
402 CHECK_EQ(expected, t.Call(expected)); | 378 CHECK_EQ(expected, t.Call(expected)); |
403 CHECK_EQ(expected, smis[i + j]); | 379 CHECK_EQ(expected, smis[i + j]); |
404 } | 380 } |
405 | 381 |
406 // TODO(titzer): assert the contents of the array. | 382 // TODO(titzer): assert the contents of the array. |
407 } | 383 } |
408 } | 384 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 ElementAccess access = GetElementAccess(); | 431 ElementAccess access = GetElementAccess(); |
456 | 432 |
457 SimplifiedLoweringTester<Object*> t; | 433 SimplifiedLoweringTester<Object*> t; |
458 Node* ptr = GetBaseNode(&t); | 434 Node* ptr = GetBaseNode(&t); |
459 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); | 435 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); |
460 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); | 436 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); |
461 t.Return(t.jsgraph.TrueConstant()); | 437 t.Return(t.jsgraph.TrueConstant()); |
462 t.LowerAllNodes(); | 438 t.LowerAllNodes(); |
463 t.GenerateCode(); | 439 t.GenerateCode(); |
464 | 440 |
465 if (Pipeline::SupportedTarget()) { | |
466 Object* result = t.Call(); | 441 Object* result = t.Call(); |
467 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 442 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
468 } | |
469 } | 443 } |
470 | 444 |
471 // Create and run code that copies the field in either {untagged_array} | 445 // Create and run code that copies the field in either {untagged_array} |
472 // or {tagged_array} at index {from_index} to index {to_index}. | 446 // or {tagged_array} at index {from_index} to index {to_index}. |
473 void RunCopyField(int from_index, int to_index) { | 447 void RunCopyField(int from_index, int to_index) { |
474 BoundsCheck(from_index); | 448 BoundsCheck(from_index); |
475 BoundsCheck(to_index); | 449 BoundsCheck(to_index); |
476 FieldAccess from_access = GetFieldAccess(from_index); | 450 FieldAccess from_access = GetFieldAccess(from_index); |
477 FieldAccess to_access = GetFieldAccess(to_index); | 451 FieldAccess to_access = GetFieldAccess(to_index); |
478 | 452 |
479 SimplifiedLoweringTester<Object*> t; | 453 SimplifiedLoweringTester<Object*> t; |
480 Node* ptr = GetBaseNode(&t); | 454 Node* ptr = GetBaseNode(&t); |
481 Node* load = t.LoadField(from_access, ptr); | 455 Node* load = t.LoadField(from_access, ptr); |
482 t.StoreField(to_access, ptr, load); | 456 t.StoreField(to_access, ptr, load); |
483 t.Return(t.jsgraph.TrueConstant()); | 457 t.Return(t.jsgraph.TrueConstant()); |
484 t.LowerAllNodes(); | 458 t.LowerAllNodes(); |
485 t.GenerateCode(); | 459 t.GenerateCode(); |
486 | 460 |
487 if (Pipeline::SupportedTarget()) { | |
488 Object* result = t.Call(); | 461 Object* result = t.Call(); |
489 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 462 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
490 } | |
491 } | 463 } |
492 | 464 |
493 // Create and run code that copies the elements from {this} to {that}. | 465 // Create and run code that copies the elements from {this} to {that}. |
494 void RunCopyElements(AccessTester<E>* that) { | 466 void RunCopyElements(AccessTester<E>* that) { |
495 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support. | 467 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support. |
496 #if 0 | 468 #if 0 |
497 SimplifiedLoweringTester<Object*> t; | 469 SimplifiedLoweringTester<Object*> t; |
498 | 470 |
499 Node* one = t.Int32Constant(1); | 471 Node* one = t.Int32Constant(1); |
500 Node* index = t.Int32Constant(0); | 472 Node* index = t.Int32Constant(0); |
(...skipping 17 matching lines...) Expand all Loading... |
518 t.environment()->Push(index); | 490 t.environment()->Push(index); |
519 // continue | 491 // continue |
520 loop.EndBody(); | 492 loop.EndBody(); |
521 loop.EndLoop(); | 493 loop.EndLoop(); |
522 } | 494 } |
523 index = t.environment()->Pop(); | 495 index = t.environment()->Pop(); |
524 t.Return(t.jsgraph.TrueConstant()); | 496 t.Return(t.jsgraph.TrueConstant()); |
525 t.LowerAllNodes(); | 497 t.LowerAllNodes(); |
526 t.GenerateCode(); | 498 t.GenerateCode(); |
527 | 499 |
528 if (Pipeline::SupportedTarget()) { | |
529 Object* result = t.Call(); | 500 Object* result = t.Call(); |
530 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 501 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
531 } | |
532 #endif | 502 #endif |
533 } | 503 } |
534 | 504 |
535 E GetElement(int index) { | 505 E GetElement(int index) { |
536 BoundsCheck(index); | 506 BoundsCheck(index); |
537 if (tagged) { | 507 if (tagged) { |
538 return GetTaggedElement(index); | 508 return GetTaggedElement(index); |
539 } else { | 509 } else { |
540 return untagged_array[index]; | 510 return untagged_array[index]; |
541 } | 511 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 for (int taggedness = 0; taggedness < 2; taggedness++) { | 559 for (int taggedness = 0; taggedness < 2; taggedness++) { |
590 AccessTester<E> a(taggedness == 1, rep, original_elements, num); | 560 AccessTester<E> a(taggedness == 1, rep, original_elements, num); |
591 for (int field = 0; field < 2; field++) { | 561 for (int field = 0; field < 2; field++) { |
592 for (int i = 0; i < num_elements - 1; i++) { | 562 for (int i = 0; i < num_elements - 1; i++) { |
593 a.Reinitialize(); | 563 a.Reinitialize(); |
594 if (field == 0) { | 564 if (field == 0) { |
595 a.RunCopyField(i, i + 1); // Test field read/write. | 565 a.RunCopyField(i, i + 1); // Test field read/write. |
596 } else { | 566 } else { |
597 a.RunCopyElement(i, i + 1); // Test element read/write. | 567 a.RunCopyElement(i, i + 1); // Test element read/write. |
598 } | 568 } |
599 if (Pipeline::SupportedTarget()) { // verify. | |
600 for (int j = 0; j < num_elements; j++) { | 569 for (int j = 0; j < num_elements; j++) { |
601 E expect = | 570 E expect = |
602 j == (i + 1) ? original_elements[i] : original_elements[j]; | 571 j == (i + 1) ? original_elements[i] : original_elements[j]; |
603 CHECK_EQ(expect, a.GetElement(j)); | 572 CHECK_EQ(expect, a.GetElement(j)); |
604 } | 573 } |
605 } | |
606 } | 574 } |
607 } | 575 } |
608 } | 576 } |
609 // Test array copy. | 577 // Test array copy. |
610 for (int tf = 0; tf < 2; tf++) { | 578 for (int tf = 0; tf < 2; tf++) { |
611 for (int tt = 0; tt < 2; tt++) { | 579 for (int tt = 0; tt < 2; tt++) { |
612 AccessTester<E> a(tf == 1, rep, original_elements, num); | 580 AccessTester<E> a(tf == 1, rep, original_elements, num); |
613 AccessTester<E> b(tt == 1, rep, original_elements, num); | 581 AccessTester<E> b(tt == 1, rep, original_elements, num); |
614 a.RunCopyElements(&b); | 582 a.RunCopyElements(&b); |
615 if (Pipeline::SupportedTarget()) { // verify. | |
616 for (int i = 0; i < num_elements; i++) { | 583 for (int i = 0; i < num_elements; i++) { |
617 CHECK_EQ(a.GetElement(i), b.GetElement(i)); | 584 CHECK_EQ(a.GetElement(i), b.GetElement(i)); |
618 } | |
619 } | 585 } |
620 } | 586 } |
621 } | 587 } |
622 } | 588 } |
623 | 589 |
624 | 590 |
625 TEST(RunAccessTests_uint8) { | 591 TEST(RunAccessTests_uint8) { |
626 uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99, | 592 uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99, |
627 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38}; | 593 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38}; |
628 RunAccessTest<uint8_t>(kMachInt8, data, arraysize(data)); | 594 RunAccessTest<uint8_t>(kMachInt8, data, arraysize(data)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 } | 627 } |
662 | 628 |
663 | 629 |
664 TEST(RunAccessTests_Smi) { | 630 TEST(RunAccessTests_Smi) { |
665 Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9), | 631 Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9), |
666 Smi::FromInt(0), Smi::FromInt(666), | 632 Smi::FromInt(0), Smi::FromInt(666), |
667 Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)}; | 633 Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)}; |
668 RunAccessTest<Smi*>(kMachAnyTagged, data, arraysize(data)); | 634 RunAccessTest<Smi*>(kMachAnyTagged, data, arraysize(data)); |
669 } | 635 } |
670 | 636 |
671 #if V8_TURBOFAN_TARGET | 637 |
672 TEST(RunAllocate) { | 638 TEST(RunAllocate) { |
673 PretenureFlag flag[] = {NOT_TENURED, TENURED}; | 639 PretenureFlag flag[] = {NOT_TENURED, TENURED}; |
674 | 640 |
675 for (size_t i = 0; i < arraysize(flag); i++) { | 641 for (size_t i = 0; i < arraysize(flag); i++) { |
676 SimplifiedLoweringTester<HeapObject*> t; | 642 SimplifiedLoweringTester<HeapObject*> t; |
677 FieldAccess access = AccessBuilder::ForMap(); | 643 FieldAccess access = AccessBuilder::ForMap(); |
678 Node* size = t.jsgraph.Constant(HeapNumber::kSize); | 644 Node* size = t.jsgraph.Constant(HeapNumber::kSize); |
679 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size); | 645 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size); |
680 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map()); | 646 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map()); |
681 t.StoreField(access, alloc, map); | 647 t.StoreField(access, alloc, map); |
682 t.Return(alloc); | 648 t.Return(alloc); |
683 | 649 |
684 t.LowerAllNodes(); | 650 t.LowerAllNodes(); |
685 t.GenerateCode(); | 651 t.GenerateCode(); |
686 | 652 |
687 if (Pipeline::SupportedTarget()) { | |
688 HeapObject* result = t.CallWithPotentialGC<HeapObject>(); | 653 HeapObject* result = t.CallWithPotentialGC<HeapObject>(); |
689 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); | 654 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); |
690 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); | 655 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); |
691 CHECK(result->IsHeapNumber()); | 656 CHECK(result->IsHeapNumber()); |
692 } | |
693 } | 657 } |
694 } | 658 } |
695 #endif | 659 |
696 | 660 |
697 // Fills in most of the nodes of the graph in order to make tests shorter. | 661 // Fills in most of the nodes of the graph in order to make tests shorter. |
698 class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { | 662 class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { |
699 public: | 663 public: |
700 Typer typer; | 664 Typer typer; |
701 JSOperatorBuilder javascript; | 665 JSOperatorBuilder javascript; |
702 JSGraph jsgraph; | 666 JSGraph jsgraph; |
703 Node* p0; | 667 Node* p0; |
704 Node* p1; | 668 Node* p1; |
705 Node* p2; | 669 Node* p2; |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 | 1221 |
1258 TEST(LowerReferenceEqual_to_wordeq) { | 1222 TEST(LowerReferenceEqual_to_wordeq) { |
1259 TestingGraph t(Type::Any(), Type::Any()); | 1223 TestingGraph t(Type::Any(), Type::Any()); |
1260 IrOpcode::Value opcode = | 1224 IrOpcode::Value opcode = |
1261 static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode()); | 1225 static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode()); |
1262 t.CheckLoweringBinop(opcode, t.simplified()->ReferenceEqual(Type::Any())); | 1226 t.CheckLoweringBinop(opcode, t.simplified()->ReferenceEqual(Type::Any())); |
1263 } | 1227 } |
1264 | 1228 |
1265 | 1229 |
1266 TEST(LowerStringOps_to_call_and_compare) { | 1230 TEST(LowerStringOps_to_call_and_compare) { |
1267 if (Pipeline::SupportedTarget()) { | |
1268 // These tests need linkage for the calls. | 1231 // These tests need linkage for the calls. |
1269 TestingGraph t(Type::String(), Type::String()); | 1232 TestingGraph t(Type::String(), Type::String()); |
1270 IrOpcode::Value compare_eq = | 1233 IrOpcode::Value compare_eq = |
1271 static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode()); | 1234 static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode()); |
1272 IrOpcode::Value compare_lt = | 1235 IrOpcode::Value compare_lt = |
1273 static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode()); | 1236 static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode()); |
1274 IrOpcode::Value compare_le = static_cast<IrOpcode::Value>( | 1237 IrOpcode::Value compare_le = static_cast<IrOpcode::Value>( |
1275 t.machine()->IntLessThanOrEqual()->opcode()); | 1238 t.machine()->IntLessThanOrEqual()->opcode()); |
1276 t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual()); | 1239 t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual()); |
1277 t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan()); | 1240 t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan()); |
1278 t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual()); | 1241 t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual()); |
1279 } | 1242 } |
1280 } | |
1281 | 1243 |
1282 | 1244 |
1283 void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, | 1245 void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, |
1284 MachineType to) { | 1246 MachineType to) { |
1285 TestingGraph t(Type::Any()); | 1247 TestingGraph t(Type::Any()); |
1286 Node* in = t.ExampleWithOutput(from); | 1248 Node* in = t.ExampleWithOutput(from); |
1287 Node* use = t.Use(in, to); | 1249 Node* use = t.Use(in, to); |
1288 t.Return(use); | 1250 t.Return(use); |
1289 t.Lower(); | 1251 t.Lower(); |
1290 CHECK_EQ(expected, use->InputAt(0)->opcode()); | 1252 CHECK_EQ(expected, use->InputAt(0)->opcode()); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 } | 1663 } |
1702 | 1664 |
1703 | 1665 |
1704 TEST(RunNumberDivide_minus_1_TruncatingToInt32) { | 1666 TEST(RunNumberDivide_minus_1_TruncatingToInt32) { |
1705 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1667 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1706 Node* num = t.NumberToInt32(t.Parameter(0)); | 1668 Node* num = t.NumberToInt32(t.Parameter(0)); |
1707 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); | 1669 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); |
1708 Node* trunc = t.NumberToInt32(div); | 1670 Node* trunc = t.NumberToInt32(div); |
1709 t.Return(trunc); | 1671 t.Return(trunc); |
1710 | 1672 |
1711 if (Pipeline::SupportedTarget()) { | |
1712 t.LowerAllNodesAndLowerChanges(); | 1673 t.LowerAllNodesAndLowerChanges(); |
1713 t.GenerateCode(); | 1674 t.GenerateCode(); |
1714 | 1675 |
1715 FOR_INT32_INPUTS(i) { | 1676 FOR_INT32_INPUTS(i) { |
1716 int32_t x = 0 - *i; | 1677 int32_t x = 0 - *i; |
1717 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1678 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1718 } | 1679 } |
1719 } | |
1720 } | 1680 } |
1721 | 1681 |
1722 | 1682 |
1723 TEST(NumberMultiply_TruncatingToInt32) { | 1683 TEST(NumberMultiply_TruncatingToInt32) { |
1724 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; | 1684 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; |
1725 | 1685 |
1726 for (size_t i = 0; i < arraysize(constants); i++) { | 1686 for (size_t i = 0; i < arraysize(constants); i++) { |
1727 TestingGraph t(Type::Signed32()); | 1687 TestingGraph t(Type::Signed32()); |
1728 Node* k = t.jsgraph.Constant(constants[i]); | 1688 Node* k = t.jsgraph.Constant(constants[i]); |
1729 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); | 1689 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); |
(...skipping 10 matching lines...) Expand all Loading... |
1740 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999}; | 1700 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999}; |
1741 | 1701 |
1742 for (size_t i = 0; i < arraysize(constants); i++) { | 1702 for (size_t i = 0; i < arraysize(constants); i++) { |
1743 double k = static_cast<double>(constants[i]); | 1703 double k = static_cast<double>(constants[i]); |
1744 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1704 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1745 Node* num = t.NumberToInt32(t.Parameter(0)); | 1705 Node* num = t.NumberToInt32(t.Parameter(0)); |
1746 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); | 1706 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); |
1747 Node* trunc = t.NumberToInt32(mul); | 1707 Node* trunc = t.NumberToInt32(mul); |
1748 t.Return(trunc); | 1708 t.Return(trunc); |
1749 | 1709 |
1750 if (Pipeline::SupportedTarget()) { | |
1751 t.LowerAllNodesAndLowerChanges(); | 1710 t.LowerAllNodesAndLowerChanges(); |
1752 t.GenerateCode(); | 1711 t.GenerateCode(); |
1753 | 1712 |
1754 FOR_INT32_INPUTS(i) { | 1713 FOR_INT32_INPUTS(i) { |
1755 int32_t x = DoubleToInt32(static_cast<double>(*i) * k); | 1714 int32_t x = DoubleToInt32(static_cast<double>(*i) * k); |
1756 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1715 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1757 } | 1716 } |
1758 } | 1717 } |
1759 } | |
1760 } | 1718 } |
1761 | 1719 |
1762 | 1720 |
1763 TEST(RunNumberMultiply_TruncatingToUint32) { | 1721 TEST(RunNumberMultiply_TruncatingToUint32) { |
1764 uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999}; | 1722 uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999}; |
1765 | 1723 |
1766 for (size_t i = 0; i < arraysize(constants); i++) { | 1724 for (size_t i = 0; i < arraysize(constants); i++) { |
1767 double k = static_cast<double>(constants[i]); | 1725 double k = static_cast<double>(constants[i]); |
1768 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1726 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1769 Node* num = t.NumberToUint32(t.Parameter(0)); | 1727 Node* num = t.NumberToUint32(t.Parameter(0)); |
1770 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); | 1728 Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); |
1771 Node* trunc = t.NumberToUint32(mul); | 1729 Node* trunc = t.NumberToUint32(mul); |
1772 t.Return(trunc); | 1730 t.Return(trunc); |
1773 | 1731 |
1774 if (Pipeline::SupportedTarget()) { | |
1775 t.LowerAllNodesAndLowerChanges(); | 1732 t.LowerAllNodesAndLowerChanges(); |
1776 t.GenerateCode(); | 1733 t.GenerateCode(); |
1777 | 1734 |
1778 FOR_UINT32_INPUTS(i) { | 1735 FOR_UINT32_INPUTS(i) { |
1779 uint32_t x = DoubleToUint32(static_cast<double>(*i) * k); | 1736 uint32_t x = DoubleToUint32(static_cast<double>(*i) * k); |
1780 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1737 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1781 } | |
1782 } | 1738 } |
1783 } | 1739 } |
1784 } | 1740 } |
1785 | 1741 |
1786 | 1742 |
1787 TEST(RunNumberDivide_2_TruncatingToUint32) { | 1743 TEST(RunNumberDivide_2_TruncatingToUint32) { |
1788 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1744 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1789 Node* num = t.NumberToUint32(t.Parameter(0)); | 1745 Node* num = t.NumberToUint32(t.Parameter(0)); |
1790 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2)); | 1746 Node* div = t.NumberDivide(num, t.jsgraph.Constant(2)); |
1791 Node* trunc = t.NumberToUint32(div); | 1747 Node* trunc = t.NumberToUint32(div); |
1792 t.Return(trunc); | 1748 t.Return(trunc); |
1793 | 1749 |
1794 if (Pipeline::SupportedTarget()) { | |
1795 t.LowerAllNodesAndLowerChanges(); | 1750 t.LowerAllNodesAndLowerChanges(); |
1796 t.GenerateCode(); | 1751 t.GenerateCode(); |
1797 | 1752 |
1798 FOR_UINT32_INPUTS(i) { | 1753 FOR_UINT32_INPUTS(i) { |
1799 uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0)); | 1754 uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0)); |
1800 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1755 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1801 } | 1756 } |
1802 } | |
1803 } | 1757 } |
1804 | 1758 |
1805 | 1759 |
1806 TEST(NumberMultiply_ConstantOutOfRange) { | 1760 TEST(NumberMultiply_ConstantOutOfRange) { |
1807 TestingGraph t(Type::Signed32()); | 1761 TestingGraph t(Type::Signed32()); |
1808 Node* k = t.jsgraph.Constant(1000000023); | 1762 Node* k = t.jsgraph.Constant(1000000023); |
1809 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); | 1763 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); |
1810 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul); | 1764 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul); |
1811 t.Return(trunc); | 1765 t.Return(trunc); |
1812 t.Lower(); | 1766 t.Lower(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; | 1800 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; |
1847 | 1801 |
1848 for (size_t i = 0; i < arraysize(constants); i++) { | 1802 for (size_t i = 0; i < arraysize(constants); i++) { |
1849 int32_t k = constants[i]; | 1803 int32_t k = constants[i]; |
1850 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1804 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1851 Node* num = t.NumberToInt32(t.Parameter(0)); | 1805 Node* num = t.NumberToInt32(t.Parameter(0)); |
1852 Node* div = t.NumberDivide(num, t.jsgraph.Constant(k)); | 1806 Node* div = t.NumberDivide(num, t.jsgraph.Constant(k)); |
1853 Node* trunc = t.NumberToInt32(div); | 1807 Node* trunc = t.NumberToInt32(div); |
1854 t.Return(trunc); | 1808 t.Return(trunc); |
1855 | 1809 |
1856 if (Pipeline::SupportedTarget()) { | |
1857 t.LowerAllNodesAndLowerChanges(); | 1810 t.LowerAllNodesAndLowerChanges(); |
1858 t.GenerateCode(); | 1811 t.GenerateCode(); |
1859 | 1812 |
1860 FOR_INT32_INPUTS(i) { | 1813 FOR_INT32_INPUTS(i) { |
1861 if (*i == INT_MAX) continue; // exclude max int. | 1814 if (*i == INT_MAX) continue; // exclude max int. |
1862 int32_t x = DoubleToInt32(static_cast<double>(*i) / k); | 1815 int32_t x = DoubleToInt32(static_cast<double>(*i) / k); |
1863 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1816 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1864 } | |
1865 } | 1817 } |
1866 } | 1818 } |
1867 } | 1819 } |
1868 | 1820 |
1869 | 1821 |
1870 TEST(NumberDivide_TruncatingToUint32) { | 1822 TEST(NumberDivide_TruncatingToUint32) { |
1871 double constants[] = {1, 3, 100, 1000, 100998348}; | 1823 double constants[] = {1, 3, 100, 1000, 100998348}; |
1872 | 1824 |
1873 for (size_t i = 0; i < arraysize(constants); i++) { | 1825 for (size_t i = 0; i < arraysize(constants); i++) { |
1874 TestingGraph t(Type::Unsigned32()); | 1826 TestingGraph t(Type::Unsigned32()); |
(...skipping 12 matching lines...) Expand all Loading... |
1887 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048}; | 1839 uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048}; |
1888 | 1840 |
1889 for (size_t i = 0; i < arraysize(constants); i++) { | 1841 for (size_t i = 0; i < arraysize(constants); i++) { |
1890 uint32_t k = constants[i]; | 1842 uint32_t k = constants[i]; |
1891 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1843 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1892 Node* num = t.NumberToUint32(t.Parameter(0)); | 1844 Node* num = t.NumberToUint32(t.Parameter(0)); |
1893 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k))); | 1845 Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k))); |
1894 Node* trunc = t.NumberToUint32(div); | 1846 Node* trunc = t.NumberToUint32(div); |
1895 t.Return(trunc); | 1847 t.Return(trunc); |
1896 | 1848 |
1897 if (Pipeline::SupportedTarget()) { | |
1898 t.LowerAllNodesAndLowerChanges(); | 1849 t.LowerAllNodesAndLowerChanges(); |
1899 t.GenerateCode(); | 1850 t.GenerateCode(); |
1900 | 1851 |
1901 FOR_UINT32_INPUTS(i) { | 1852 FOR_UINT32_INPUTS(i) { |
1902 uint32_t x = *i / k; | 1853 uint32_t x = *i / k; |
1903 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1854 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1904 } | |
1905 } | 1855 } |
1906 } | 1856 } |
1907 } | 1857 } |
1908 | 1858 |
1909 | 1859 |
1910 TEST(NumberDivide_BadConstants) { | 1860 TEST(NumberDivide_BadConstants) { |
1911 { | 1861 { |
1912 TestingGraph t(Type::Signed32()); | 1862 TestingGraph t(Type::Signed32()); |
1913 Node* k = t.jsgraph.Constant(-1); | 1863 Node* k = t.jsgraph.Constant(-1); |
1914 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); | 1864 Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; | 1915 int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048}; |
1966 | 1916 |
1967 for (size_t i = 0; i < arraysize(constants); i++) { | 1917 for (size_t i = 0; i < arraysize(constants); i++) { |
1968 int32_t k = constants[i]; | 1918 int32_t k = constants[i]; |
1969 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1919 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1970 Node* num = t.NumberToInt32(t.Parameter(0)); | 1920 Node* num = t.NumberToInt32(t.Parameter(0)); |
1971 Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k)); | 1921 Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k)); |
1972 Node* trunc = t.NumberToInt32(mod); | 1922 Node* trunc = t.NumberToInt32(mod); |
1973 t.Return(trunc); | 1923 t.Return(trunc); |
1974 | 1924 |
1975 if (Pipeline::SupportedTarget()) { | |
1976 t.LowerAllNodesAndLowerChanges(); | 1925 t.LowerAllNodesAndLowerChanges(); |
1977 t.GenerateCode(); | 1926 t.GenerateCode(); |
1978 | 1927 |
1979 FOR_INT32_INPUTS(i) { | 1928 FOR_INT32_INPUTS(i) { |
1980 if (*i == INT_MAX) continue; // exclude max int. | 1929 if (*i == INT_MAX) continue; // exclude max int. |
1981 int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k)); | 1930 int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k)); |
1982 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1931 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1983 } | |
1984 } | 1932 } |
1985 } | 1933 } |
1986 } | 1934 } |
1987 | 1935 |
1988 | 1936 |
1989 TEST(NumberModulus_TruncatingToUint32) { | 1937 TEST(NumberModulus_TruncatingToUint32) { |
1990 double constants[] = {1, 3, 100, 1000, 100998348}; | 1938 double constants[] = {1, 3, 100, 1000, 100998348}; |
1991 | 1939 |
1992 for (size_t i = 0; i < arraysize(constants); i++) { | 1940 for (size_t i = 0; i < arraysize(constants); i++) { |
1993 TestingGraph t(Type::Unsigned32()); | 1941 TestingGraph t(Type::Unsigned32()); |
(...skipping 13 matching lines...) Expand all Loading... |
2007 | 1955 |
2008 for (size_t i = 0; i < arraysize(constants); i++) { | 1956 for (size_t i = 0; i < arraysize(constants); i++) { |
2009 uint32_t k = constants[i]; | 1957 uint32_t k = constants[i]; |
2010 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1958 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
2011 Node* num = t.NumberToUint32(t.Parameter(0)); | 1959 Node* num = t.NumberToUint32(t.Parameter(0)); |
2012 Node* mod = | 1960 Node* mod = |
2013 t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k))); | 1961 t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k))); |
2014 Node* trunc = t.NumberToUint32(mod); | 1962 Node* trunc = t.NumberToUint32(mod); |
2015 t.Return(trunc); | 1963 t.Return(trunc); |
2016 | 1964 |
2017 if (Pipeline::SupportedTarget()) { | |
2018 t.LowerAllNodesAndLowerChanges(); | 1965 t.LowerAllNodesAndLowerChanges(); |
2019 t.GenerateCode(); | 1966 t.GenerateCode(); |
2020 | 1967 |
2021 FOR_UINT32_INPUTS(i) { | 1968 FOR_UINT32_INPUTS(i) { |
2022 uint32_t x = *i % k; | 1969 uint32_t x = *i % k; |
2023 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1970 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
2024 } | |
2025 } | 1971 } |
2026 } | 1972 } |
2027 } | 1973 } |
2028 | 1974 |
2029 | 1975 |
2030 TEST(NumberModulus_Int32) { | 1976 TEST(NumberModulus_Int32) { |
2031 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; | 1977 int32_t constants[] = {-100, -10, 1, 4, 100, 1000}; |
2032 | 1978 |
2033 for (size_t i = 0; i < arraysize(constants); i++) { | 1979 for (size_t i = 0; i < arraysize(constants); i++) { |
2034 TestingGraph t(Type::Signed32()); | 1980 TestingGraph t(Type::Signed32()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z); | 2042 Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z); |
2097 NodeProperties::SetBounds(phi, phi_bounds); | 2043 NodeProperties::SetBounds(phi, phi_bounds); |
2098 | 2044 |
2099 Node* use = t.Use(phi, d.use); | 2045 Node* use = t.Use(phi, d.use); |
2100 t.Return(use); | 2046 t.Return(use); |
2101 t.Lower(); | 2047 t.Lower(); |
2102 | 2048 |
2103 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); | 2049 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); |
2104 } | 2050 } |
2105 } | 2051 } |
OLD | NEW |