| 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 |