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 <cmath> | 5 #include <cmath> |
6 #include <functional> | 6 #include <functional> |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/utils/random-number-generator.h" | 10 #include "src/base/utils/random-number-generator.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 m.Return(m.Int32Constant(constant)); | 157 m.Return(m.Int32Constant(constant)); |
158 | 158 |
159 CHECK_EQ(constant, m.Call()); | 159 CHECK_EQ(constant, m.Call()); |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 template <typename R> | 163 template <typename R> |
164 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, | 164 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, |
165 MachineType type, Node* true_node, | 165 MachineType type, Node* true_node, |
166 Node* false_node) { | 166 Node* false_node) { |
167 MLabel blocka, blockb; | 167 MLabel blocka, blockb, end; |
168 MLabel* end = m->Exit(); | |
169 m->Branch(cond_node, &blocka, &blockb); | 168 m->Branch(cond_node, &blocka, &blockb); |
170 m->Bind(&blocka); | 169 m->Bind(&blocka); |
171 m->Goto(end); | 170 m->Goto(&end); |
172 m->Bind(&blockb); | 171 m->Bind(&blockb); |
173 m->Goto(end); | 172 m->Goto(&end); |
174 | 173 |
175 m->Bind(end); | 174 m->Bind(&end); |
176 Node* phi = m->Phi(type, true_node, false_node); | 175 Node* phi = m->Phi(type, true_node, false_node); |
177 m->Return(phi); | 176 m->Return(phi); |
178 } | 177 } |
179 | 178 |
180 | 179 |
181 TEST(RunDiamondPhiConst) { | 180 TEST(RunDiamondPhiConst) { |
182 RawMachineAssemblerTester<int32_t> m(kMachInt32); | 181 RawMachineAssemblerTester<int32_t> m(kMachInt32); |
183 int false_val = 0xFF666; | 182 int false_val = 0xFF666; |
184 int true_val = 0x00DDD; | 183 int true_val = 0x00DDD; |
185 Node* true_node = m.Int32Constant(true_val); | 184 Node* true_node = m.Int32Constant(true_val); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 TEST(RunLoopPhiConst) { | 229 TEST(RunLoopPhiConst) { |
231 RawMachineAssemblerTester<int32_t> m; | 230 RawMachineAssemblerTester<int32_t> m; |
232 int true_val = 0x44000; | 231 int true_val = 0x44000; |
233 int false_val = 0x00888; | 232 int false_val = 0x00888; |
234 | 233 |
235 Node* cond_node = m.Int32Constant(0); | 234 Node* cond_node = m.Int32Constant(0); |
236 Node* true_node = m.Int32Constant(true_val); | 235 Node* true_node = m.Int32Constant(true_val); |
237 Node* false_node = m.Int32Constant(false_val); | 236 Node* false_node = m.Int32Constant(false_val); |
238 | 237 |
239 // x = false_val; while(false) { x = true_val; } return x; | 238 // x = false_val; while(false) { x = true_val; } return x; |
240 MLabel body, header; | 239 MLabel body, header, end; |
241 MLabel* end = m.Exit(); | |
242 | 240 |
243 m.Goto(&header); | 241 m.Goto(&header); |
244 m.Bind(&header); | 242 m.Bind(&header); |
245 Node* phi = m.Phi(kMachInt32, false_node, true_node); | 243 Node* phi = m.Phi(kMachInt32, false_node, true_node); |
246 m.Branch(cond_node, &body, end); | 244 m.Branch(cond_node, &body, &end); |
247 m.Bind(&body); | 245 m.Bind(&body); |
248 m.Goto(&header); | 246 m.Goto(&header); |
249 m.Bind(end); | 247 m.Bind(&end); |
250 m.Return(phi); | 248 m.Return(phi); |
251 | 249 |
252 CHECK_EQ(false_val, m.Call()); | 250 CHECK_EQ(false_val, m.Call()); |
253 } | 251 } |
254 | 252 |
255 | 253 |
256 TEST(RunLoopPhiParam) { | 254 TEST(RunLoopPhiParam) { |
257 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); | 255 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); |
258 | 256 |
259 MLabel blocka, blockb; | 257 MLabel blocka, blockb, end; |
260 MLabel* end = m.Exit(); | |
261 | 258 |
262 m.Goto(&blocka); | 259 m.Goto(&blocka); |
263 | 260 |
264 m.Bind(&blocka); | 261 m.Bind(&blocka); |
265 Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2)); | 262 Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2)); |
266 Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0)); | 263 Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0)); |
267 m.Branch(cond, &blockb, end); | 264 m.Branch(cond, &blockb, &end); |
268 | 265 |
269 m.Bind(&blockb); | 266 m.Bind(&blockb); |
270 m.Goto(&blocka); | 267 m.Goto(&blocka); |
271 | 268 |
272 m.Bind(end); | 269 m.Bind(&end); |
273 m.Return(phi); | 270 m.Return(phi); |
274 | 271 |
275 int32_t c1 = 0xa81903b4; | 272 int32_t c1 = 0xa81903b4; |
276 int32_t c2 = 0x5a1207da; | 273 int32_t c2 = 0x5a1207da; |
277 int result = m.Call(0, c1, c2); | 274 int result = m.Call(0, c1, c2); |
278 CHECK_EQ(c1, result); | 275 CHECK_EQ(c1, result); |
279 result = m.Call(1, c1, c2); | 276 result = m.Call(1, c1, c2); |
280 CHECK_EQ(c2, result); | 277 CHECK_EQ(c2, result); |
281 } | 278 } |
282 | 279 |
283 | 280 |
284 TEST(RunLoopPhiInduction) { | 281 TEST(RunLoopPhiInduction) { |
285 RawMachineAssemblerTester<int32_t> m; | 282 RawMachineAssemblerTester<int32_t> m; |
286 | 283 |
287 int false_val = 0x10777; | 284 int false_val = 0x10777; |
288 | 285 |
289 // x = false_val; while(false) { x++; } return x; | 286 // x = false_val; while(false) { x++; } return x; |
290 MLabel header, body; | 287 MLabel header, body, end; |
291 MLabel* end = m.Exit(); | |
292 Node* false_node = m.Int32Constant(false_val); | 288 Node* false_node = m.Int32Constant(false_val); |
293 | 289 |
294 m.Goto(&header); | 290 m.Goto(&header); |
295 | 291 |
296 m.Bind(&header); | 292 m.Bind(&header); |
297 Node* phi = m.Phi(kMachInt32, false_node, false_node); | 293 Node* phi = m.Phi(kMachInt32, false_node, false_node); |
298 m.Branch(m.Int32Constant(0), &body, end); | 294 m.Branch(m.Int32Constant(0), &body, &end); |
299 | 295 |
300 m.Bind(&body); | 296 m.Bind(&body); |
301 Node* add = m.Int32Add(phi, m.Int32Constant(1)); | 297 Node* add = m.Int32Add(phi, m.Int32Constant(1)); |
302 phi->ReplaceInput(1, add); | 298 phi->ReplaceInput(1, add); |
303 m.Goto(&header); | 299 m.Goto(&header); |
304 | 300 |
305 m.Bind(end); | 301 m.Bind(&end); |
306 m.Return(phi); | 302 m.Return(phi); |
307 | 303 |
308 CHECK_EQ(false_val, m.Call()); | 304 CHECK_EQ(false_val, m.Call()); |
309 } | 305 } |
310 | 306 |
311 | 307 |
312 TEST(RunLoopIncrement) { | 308 TEST(RunLoopIncrement) { |
313 RawMachineAssemblerTester<int32_t> m; | 309 RawMachineAssemblerTester<int32_t> m; |
314 Int32BinopTester bt(&m); | 310 Int32BinopTester bt(&m); |
315 | 311 |
316 // x = 0; while(x ^ param) { x++; } return x; | 312 // x = 0; while(x ^ param) { x++; } return x; |
317 MLabel header, body; | 313 MLabel header, body, end; |
318 MLabel* end = m.Exit(); | |
319 Node* zero = m.Int32Constant(0); | 314 Node* zero = m.Int32Constant(0); |
320 | 315 |
321 m.Goto(&header); | 316 m.Goto(&header); |
322 | 317 |
323 m.Bind(&header); | 318 m.Bind(&header); |
324 Node* phi = m.Phi(kMachInt32, zero, zero); | 319 Node* phi = m.Phi(kMachInt32, zero, zero); |
325 m.Branch(m.WordXor(phi, bt.param0), &body, end); | 320 m.Branch(m.WordXor(phi, bt.param0), &body, &end); |
326 | 321 |
327 m.Bind(&body); | 322 m.Bind(&body); |
328 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); | 323 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); |
329 m.Goto(&header); | 324 m.Goto(&header); |
330 | 325 |
331 m.Bind(end); | 326 m.Bind(&end); |
332 bt.AddReturn(phi); | 327 bt.AddReturn(phi); |
333 | 328 |
334 CHECK_EQ(11, bt.call(11, 0)); | 329 CHECK_EQ(11, bt.call(11, 0)); |
335 CHECK_EQ(110, bt.call(110, 0)); | 330 CHECK_EQ(110, bt.call(110, 0)); |
336 CHECK_EQ(176, bt.call(176, 0)); | 331 CHECK_EQ(176, bt.call(176, 0)); |
337 } | 332 } |
338 | 333 |
339 | 334 |
340 TEST(RunLoopIncrement2) { | 335 TEST(RunLoopIncrement2) { |
341 RawMachineAssemblerTester<int32_t> m; | 336 RawMachineAssemblerTester<int32_t> m; |
342 Int32BinopTester bt(&m); | 337 Int32BinopTester bt(&m); |
343 | 338 |
344 // x = 0; while(x < param) { x++; } return x; | 339 // x = 0; while(x < param) { x++; } return x; |
345 MLabel header, body; | 340 MLabel header, body, end; |
346 MLabel* end = m.Exit(); | |
347 Node* zero = m.Int32Constant(0); | 341 Node* zero = m.Int32Constant(0); |
348 | 342 |
349 m.Goto(&header); | 343 m.Goto(&header); |
350 | 344 |
351 m.Bind(&header); | 345 m.Bind(&header); |
352 Node* phi = m.Phi(kMachInt32, zero, zero); | 346 Node* phi = m.Phi(kMachInt32, zero, zero); |
353 m.Branch(m.Int32LessThan(phi, bt.param0), &body, end); | 347 m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end); |
354 | 348 |
355 m.Bind(&body); | 349 m.Bind(&body); |
356 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); | 350 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); |
357 m.Goto(&header); | 351 m.Goto(&header); |
358 | 352 |
359 m.Bind(end); | 353 m.Bind(&end); |
360 bt.AddReturn(phi); | 354 bt.AddReturn(phi); |
361 | 355 |
362 CHECK_EQ(11, bt.call(11, 0)); | 356 CHECK_EQ(11, bt.call(11, 0)); |
363 CHECK_EQ(110, bt.call(110, 0)); | 357 CHECK_EQ(110, bt.call(110, 0)); |
364 CHECK_EQ(176, bt.call(176, 0)); | 358 CHECK_EQ(176, bt.call(176, 0)); |
365 CHECK_EQ(0, bt.call(-200, 0)); | 359 CHECK_EQ(0, bt.call(-200, 0)); |
366 } | 360 } |
367 | 361 |
368 | 362 |
369 TEST(RunLoopIncrement3) { | 363 TEST(RunLoopIncrement3) { |
370 RawMachineAssemblerTester<int32_t> m; | 364 RawMachineAssemblerTester<int32_t> m; |
371 Int32BinopTester bt(&m); | 365 Int32BinopTester bt(&m); |
372 | 366 |
373 // x = 0; while(x < param) { x++; } return x; | 367 // x = 0; while(x < param) { x++; } return x; |
374 MLabel header, body; | 368 MLabel header, body, end; |
375 MLabel* end = m.Exit(); | |
376 Node* zero = m.Int32Constant(0); | 369 Node* zero = m.Int32Constant(0); |
377 | 370 |
378 m.Goto(&header); | 371 m.Goto(&header); |
379 | 372 |
380 m.Bind(&header); | 373 m.Bind(&header); |
381 Node* phi = m.Phi(kMachInt32, zero, zero); | 374 Node* phi = m.Phi(kMachInt32, zero, zero); |
382 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end); | 375 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end); |
383 | 376 |
384 m.Bind(&body); | 377 m.Bind(&body); |
385 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); | 378 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); |
386 m.Goto(&header); | 379 m.Goto(&header); |
387 | 380 |
388 m.Bind(end); | 381 m.Bind(&end); |
389 bt.AddReturn(phi); | 382 bt.AddReturn(phi); |
390 | 383 |
391 CHECK_EQ(11, bt.call(11, 0)); | 384 CHECK_EQ(11, bt.call(11, 0)); |
392 CHECK_EQ(110, bt.call(110, 0)); | 385 CHECK_EQ(110, bt.call(110, 0)); |
393 CHECK_EQ(176, bt.call(176, 0)); | 386 CHECK_EQ(176, bt.call(176, 0)); |
394 CHECK_EQ(200, bt.call(200, 0)); | 387 CHECK_EQ(200, bt.call(200, 0)); |
395 } | 388 } |
396 | 389 |
397 | 390 |
398 TEST(RunLoopDecrement) { | 391 TEST(RunLoopDecrement) { |
399 RawMachineAssemblerTester<int32_t> m; | 392 RawMachineAssemblerTester<int32_t> m; |
400 Int32BinopTester bt(&m); | 393 Int32BinopTester bt(&m); |
401 | 394 |
402 // x = param; while(x) { x--; } return x; | 395 // x = param; while(x) { x--; } return x; |
403 MLabel header, body; | 396 MLabel header, body, end; |
404 MLabel* end = m.Exit(); | |
405 | 397 |
406 m.Goto(&header); | 398 m.Goto(&header); |
407 | 399 |
408 m.Bind(&header); | 400 m.Bind(&header); |
409 Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0)); | 401 Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0)); |
410 m.Branch(phi, &body, end); | 402 m.Branch(phi, &body, &end); |
411 | 403 |
412 m.Bind(&body); | 404 m.Bind(&body); |
413 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1))); | 405 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1))); |
414 m.Goto(&header); | 406 m.Goto(&header); |
415 | 407 |
416 m.Bind(end); | 408 m.Bind(&end); |
417 bt.AddReturn(phi); | 409 bt.AddReturn(phi); |
418 | 410 |
419 CHECK_EQ(0, bt.call(11, 0)); | 411 CHECK_EQ(0, bt.call(11, 0)); |
420 CHECK_EQ(0, bt.call(110, 0)); | 412 CHECK_EQ(0, bt.call(110, 0)); |
421 CHECK_EQ(0, bt.call(197, 0)); | 413 CHECK_EQ(0, bt.call(197, 0)); |
422 } | 414 } |
423 | 415 |
424 | 416 |
425 TEST(RunLoopIncrementFloat32) { | 417 TEST(RunLoopIncrementFloat32) { |
426 RawMachineAssemblerTester<int32_t> m; | 418 RawMachineAssemblerTester<int32_t> m; |
427 | 419 |
428 // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x; | 420 // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x; |
429 MLabel header, body; | 421 MLabel header, body, end; |
430 MLabel* end = m.Exit(); | |
431 Node* minus_3 = m.Float32Constant(-3.0f); | 422 Node* minus_3 = m.Float32Constant(-3.0f); |
432 Node* ten = m.Float32Constant(10.0f); | 423 Node* ten = m.Float32Constant(10.0f); |
433 | 424 |
434 m.Goto(&header); | 425 m.Goto(&header); |
435 | 426 |
436 m.Bind(&header); | 427 m.Bind(&header); |
437 Node* phi = m.Phi(kMachFloat32, minus_3, ten); | 428 Node* phi = m.Phi(kMachFloat32, minus_3, ten); |
438 m.Branch(m.Float32LessThan(phi, ten), &body, end); | 429 m.Branch(m.Float32LessThan(phi, ten), &body, &end); |
439 | 430 |
440 m.Bind(&body); | 431 m.Bind(&body); |
441 phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f))); | 432 phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f))); |
442 m.Goto(&header); | 433 m.Goto(&header); |
443 | 434 |
444 m.Bind(end); | 435 m.Bind(&end); |
445 m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi))); | 436 m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi))); |
446 | 437 |
447 CHECK_EQ(10, m.Call()); | 438 CHECK_EQ(10, m.Call()); |
448 } | 439 } |
449 | 440 |
450 | 441 |
451 TEST(RunLoopIncrementFloat64) { | 442 TEST(RunLoopIncrementFloat64) { |
452 RawMachineAssemblerTester<int32_t> m; | 443 RawMachineAssemblerTester<int32_t> m; |
453 | 444 |
454 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x; | 445 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x; |
455 MLabel header, body; | 446 MLabel header, body, end; |
456 MLabel* end = m.Exit(); | |
457 Node* minus_3 = m.Float64Constant(-3.0); | 447 Node* minus_3 = m.Float64Constant(-3.0); |
458 Node* ten = m.Float64Constant(10.0); | 448 Node* ten = m.Float64Constant(10.0); |
459 | 449 |
460 m.Goto(&header); | 450 m.Goto(&header); |
461 | 451 |
462 m.Bind(&header); | 452 m.Bind(&header); |
463 Node* phi = m.Phi(kMachFloat64, minus_3, ten); | 453 Node* phi = m.Phi(kMachFloat64, minus_3, ten); |
464 m.Branch(m.Float64LessThan(phi, ten), &body, end); | 454 m.Branch(m.Float64LessThan(phi, ten), &body, &end); |
465 | 455 |
466 m.Bind(&body); | 456 m.Bind(&body); |
467 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5))); | 457 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5))); |
468 m.Goto(&header); | 458 m.Goto(&header); |
469 | 459 |
470 m.Bind(end); | 460 m.Bind(&end); |
471 m.Return(m.ChangeFloat64ToInt32(phi)); | 461 m.Return(m.ChangeFloat64ToInt32(phi)); |
472 | 462 |
473 CHECK_EQ(10, m.Call()); | 463 CHECK_EQ(10, m.Call()); |
474 } | 464 } |
475 | 465 |
476 | 466 |
477 TEST(RunSwitch1) { | 467 TEST(RunSwitch1) { |
478 RawMachineAssemblerTester<int32_t> m; | 468 RawMachineAssemblerTester<int32_t> m; |
479 | 469 |
480 int constant = 11223344; | 470 int constant = 11223344; |
(...skipping 4661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5142 m.Return(m.Int32Constant(0)); | 5132 m.Return(m.Int32Constant(0)); |
5143 for (size_t i = 0; i < arraysize(kValues); ++i) { | 5133 for (size_t i = 0; i < arraysize(kValues); ++i) { |
5144 input = kValues[i]; | 5134 input = kValues[i]; |
5145 CHECK_EQ(0, m.Call()); | 5135 CHECK_EQ(0, m.Call()); |
5146 double expected = round(kValues[i]); | 5136 double expected = round(kValues[i]); |
5147 CHECK_EQ(expected, result); | 5137 CHECK_EQ(expected, result); |
5148 } | 5138 } |
5149 } | 5139 } |
5150 | 5140 |
5151 #endif // V8_TURBOFAN_TARGET | 5141 #endif // V8_TURBOFAN_TARGET |
OLD | NEW |