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 3 // found in the LICENSE file. 4 5 #include <functional> 6 #include <limits> 7 8 #include "src/base/bits.h" 9 #include "src/compiler/generic-node-inl.h" 10 #include "test/cctest/cctest.h" 11 #include "test/cctest/compiler/codegen-tester.h" 12 #include "test/cctest/compiler/value-helper.h" 13 14 #if V8_TURBOFAN_TARGET 15 16 using namespace v8::base; 17 18 #define CHECK_UINT32_EQ(x, y) \ 19 CHECK_EQ(static_cast<int32_t>(x), static_cast<int32_t>(y)) 20 21 using namespace v8::internal; 22 using namespace v8::internal::compiler; 23 24 typedef RawMachineAssembler::Label MLabel; 25 26 TEST(RunInt32Add) { 27 RawMachineAssemblerTester<int32_t> m; 28 Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1)); 29 m.Return(add); 30 CHECK_EQ(1, m.Call()); 31 } 32 33 34 static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) { 35 switch (index) { 36 case 0: 37 return m->Parameter(0); 38 case 1: 39 return m->Parameter(1); 40 case 2: 41 return m->Int32Constant(0); 42 case 3: 43 return m->Int32Constant(1); 44 case 4: 45 return m->Int32Constant(-1); 46 case 5: 47 return m->Int32Constant(0xff); 48 case 6: 49 return m->Int32Constant(0x01234567); 50 case 7: 51 return m->Load(kMachInt32, m->PointerConstant(NULL)); 52 default: 53 return NULL; 54 } 55 } 56 57 58 TEST(CodeGenInt32Binop) { 59 RawMachineAssemblerTester<void> m; 60 61 const Operator* ops[] = { 62 m.machine()->Word32And(), m.machine()->Word32Or(), 63 m.machine()->Word32Xor(), m.machine()->Word32Shl(), 64 m.machine()->Word32Shr(), m.machine()->Word32Sar(), 65 m.machine()->Word32Equal(), m.machine()->Int32Add(), 66 m.machine()->Int32Sub(), m.machine()->Int32Mul(), 67 m.machine()->Int32Div(), m.machine()->Int32UDiv(), 68 m.machine()->Int32Mod(), m.machine()->Int32UMod(), 69 m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(), 70 m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual(), 71 NULL}; 72 73 for (int i = 0; ops[i] != NULL; i++) { 74 for (int j = 0; j < 8; j++) { 75 for (int k = 0; k < 8; k++) { 76 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); 77 Node* a = Int32Input(&m, j); 78 Node* b = Int32Input(&m, k); 79 m.Return(m.NewNode(ops[i], a, b)); 80 m.GenerateCode(); 81 } 82 } 83 } 84 } 85 86 87 TEST(RunGoto) { 88 RawMachineAssemblerTester<int32_t> m; 89 int constant = 99999; 90 91 MLabel next; 92 m.Goto(&next); 93 m.Bind(&next); 94 m.Return(m.Int32Constant(constant)); 95 96 CHECK_EQ(constant, m.Call()); 97 } 98 99 100 TEST(RunGotoMultiple) { 101 RawMachineAssemblerTester<int32_t> m; 102 int constant = 9999977; 103 104 MLabel labels[10]; 105 for (size_t i = 0; i < arraysize(labels); i++) { 106 m.Goto(&labels[i]); 107 m.Bind(&labels[i]); 108 } 109 m.Return(m.Int32Constant(constant)); 110 111 CHECK_EQ(constant, m.Call()); 112 } 113 114 115 TEST(RunBranch) { 116 RawMachineAssemblerTester<int32_t> m; 117 int constant = 999777; 118 119 MLabel blocka, blockb; 120 m.Branch(m.Int32Constant(0), &blocka, &blockb); 121 m.Bind(&blocka); 122 m.Return(m.Int32Constant(0 - constant)); 123 m.Bind(&blockb); 124 m.Return(m.Int32Constant(constant)); 125 126 CHECK_EQ(constant, m.Call()); 127 } 128 129 130 TEST(RunRedundantBranch1) { 131 RawMachineAssemblerTester<int32_t> m; 132 int constant = 944777; 133 134 MLabel blocka; 135 m.Branch(m.Int32Constant(0), &blocka, &blocka); 136 m.Bind(&blocka); 137 m.Return(m.Int32Constant(constant)); 138 139 CHECK_EQ(constant, m.Call()); 140 } 141 142 143 TEST(RunRedundantBranch2) { 144 RawMachineAssemblerTester<int32_t> m; 145 int constant = 955777; 146 147 MLabel blocka, blockb; 148 m.Branch(m.Int32Constant(0), &blocka, &blocka); 149 m.Bind(&blockb); 150 m.Goto(&blocka); 151 m.Bind(&blocka); 152 m.Return(m.Int32Constant(constant)); 153 154 CHECK_EQ(constant, m.Call()); 155 } 156 157 158 TEST(RunRedundantBranch3) { 159 RawMachineAssemblerTester<int32_t> m; 160 int constant = 966777; 161 162 MLabel blocka, blockb, blockc; 163 m.Branch(m.Int32Constant(0), &blocka, &blockc); 164 m.Bind(&blocka); 165 m.Branch(m.Int32Constant(0), &blockb, &blockb); 166 m.Bind(&blockc); 167 m.Goto(&blockb); 168 m.Bind(&blockb); 169 m.Return(m.Int32Constant(constant)); 170 171 CHECK_EQ(constant, m.Call()); 172 } 173 174 175 TEST(RunDiamond2) { 176 RawMachineAssemblerTester<int32_t> m; 177 178 int constant = 995666; 179 180 MLabel blocka, blockb, end; 181 m.Branch(m.Int32Constant(0), &blocka, &blockb); 182 m.Bind(&blocka); 183 m.Goto(&end); 184 m.Bind(&blockb); 185 m.Goto(&end); 186 m.Bind(&end); 187 m.Return(m.Int32Constant(constant)); 188 189 CHECK_EQ(constant, m.Call()); 190 } 191 192 193 TEST(RunLoop) { 194 RawMachineAssemblerTester<int32_t> m; 195 int constant = 999555; 196 197 MLabel header, body, exit; 198 m.Goto(&header); 199 m.Bind(&header); 200 m.Branch(m.Int32Constant(0), &body, &exit); 201 m.Bind(&body); 202 m.Goto(&header); 203 m.Bind(&exit); 204 m.Return(m.Int32Constant(constant)); 205 206 CHECK_EQ(constant, m.Call()); 207 } 208 209 210 template <typename R> 211 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, 212 MachineType type, Node* true_node, 213 Node* false_node) { 214 MLabel blocka, blockb; 215 MLabel* end = m->Exit(); 216 m->Branch(cond_node, &blocka, &blockb); 217 m->Bind(&blocka); 218 m->Goto(end); 219 m->Bind(&blockb); 220 m->Goto(end); 221 222 m->Bind(end); 223 Node* phi = m->Phi(type, true_node, false_node); 224 m->Return(phi); 225 } 226 227 228 TEST(RunDiamondPhiConst) { 229 RawMachineAssemblerTester<int32_t> m(kMachInt32); 230 int false_val = 0xFF666; 231 int true_val = 0x00DDD; 232 Node* true_node = m.Int32Constant(true_val); 233 Node* false_node = m.Int32Constant(false_val); 234 BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, true_node, false_node); 235 CHECK_EQ(false_val, m.Call(0)); 236 CHECK_EQ(true_val, m.Call(1)); 237 } 238 239 240 TEST(RunDiamondPhiNumber) { 241 RawMachineAssemblerTester<Object*> m(kMachInt32); 242 double false_val = -11.1; 243 double true_val = 200.1; 244 Node* true_node = m.NumberConstant(true_val); 245 Node* false_node = m.NumberConstant(false_val); 246 BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node); 247 m.CheckNumber(false_val, m.Call(0)); 248 m.CheckNumber(true_val, m.Call(1)); 249 } 250 251 252 TEST(RunDiamondPhiString) { 253 RawMachineAssemblerTester<Object*> m(kMachInt32); 254 const char* false_val = "false"; 255 const char* true_val = "true"; 256 Node* true_node = m.StringConstant(true_val); 257 Node* false_node = m.StringConstant(false_val); 258 BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node); 259 m.CheckString(false_val, m.Call(0)); 260 m.CheckString(true_val, m.Call(1)); 261 } 262 263 264 TEST(RunDiamondPhiParam) { 265 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); 266 BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, m.Parameter(1), 267 m.Parameter(2)); 268 int32_t c1 = 0x260cb75a; 269 int32_t c2 = 0xcd3e9c8b; 270 int result = m.Call(0, c1, c2); 271 CHECK_EQ(c2, result); 272 result = m.Call(1, c1, c2); 273 CHECK_EQ(c1, result); 274 } 275 276 277 TEST(RunLoopPhiConst) { 278 RawMachineAssemblerTester<int32_t> m; 279 int true_val = 0x44000; 280 int false_val = 0x00888; 281 282 Node* cond_node = m.Int32Constant(0); 283 Node* true_node = m.Int32Constant(true_val); 284 Node* false_node = m.Int32Constant(false_val); 285 286 // x = false_val; while(false) { x = true_val; } return x; 287 MLabel body, header; 288 MLabel* end = m.Exit(); 289 290 m.Goto(&header); 291 m.Bind(&header); 292 Node* phi = m.Phi(kMachInt32, false_node, true_node); 293 m.Branch(cond_node, &body, end); 294 m.Bind(&body); 295 m.Goto(&header); 296 m.Bind(end); 297 m.Return(phi); 298 299 CHECK_EQ(false_val, m.Call()); 300 } 301 302 303 TEST(RunLoopPhiParam) { 304 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); 305 306 MLabel blocka, blockb; 307 MLabel* end = m.Exit(); 308 309 m.Goto(&blocka); 310 311 m.Bind(&blocka); 312 Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2)); 313 Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0)); 314 m.Branch(cond, &blockb, end); 315 316 m.Bind(&blockb); 317 m.Goto(&blocka); 318 319 m.Bind(end); 320 m.Return(phi); 321 322 int32_t c1 = 0xa81903b4; 323 int32_t c2 = 0x5a1207da; 324 int result = m.Call(0, c1, c2); 325 CHECK_EQ(c1, result); 326 result = m.Call(1, c1, c2); 327 CHECK_EQ(c2, result); 328 } 329 330 331 TEST(RunLoopPhiInduction) { 332 RawMachineAssemblerTester<int32_t> m; 333 334 int false_val = 0x10777; 335 336 // x = false_val; while(false) { x++; } return x; 337 MLabel header, body; 338 MLabel* end = m.Exit(); 339 Node* false_node = m.Int32Constant(false_val); 340 341 m.Goto(&header); 342 343 m.Bind(&header); 344 Node* phi = m.Phi(kMachInt32, false_node, false_node); 345 m.Branch(m.Int32Constant(0), &body, end); 346 347 m.Bind(&body); 348 Node* add = m.Int32Add(phi, m.Int32Constant(1)); 349 phi->ReplaceInput(1, add); 350 m.Goto(&header); 351 352 m.Bind(end); 353 m.Return(phi); 354 355 CHECK_EQ(false_val, m.Call()); 356 } 357 358 359 TEST(RunLoopIncrement) { 360 RawMachineAssemblerTester<int32_t> m; 361 Int32BinopTester bt(&m); 362 363 // x = 0; while(x ^ param) { x++; } return x; 364 MLabel header, body; 365 MLabel* end = m.Exit(); 366 Node* zero = m.Int32Constant(0); 367 368 m.Goto(&header); 369 370 m.Bind(&header); 371 Node* phi = m.Phi(kMachInt32, zero, zero); 372 m.Branch(m.WordXor(phi, bt.param0), &body, end); 373 374 m.Bind(&body); 375 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 376 m.Goto(&header); 377 378 m.Bind(end); 379 bt.AddReturn(phi); 380 381 CHECK_EQ(11, bt.call(11, 0)); 382 CHECK_EQ(110, bt.call(110, 0)); 383 CHECK_EQ(176, bt.call(176, 0)); 384 } 385 386 387 TEST(RunLoopIncrement2) { 388 RawMachineAssemblerTester<int32_t> m; 389 Int32BinopTester bt(&m); 390 391 // x = 0; while(x < param) { x++; } return x; 392 MLabel header, body; 393 MLabel* end = m.Exit(); 394 Node* zero = m.Int32Constant(0); 395 396 m.Goto(&header); 397 398 m.Bind(&header); 399 Node* phi = m.Phi(kMachInt32, zero, zero); 400 m.Branch(m.Int32LessThan(phi, bt.param0), &body, end); 401 402 m.Bind(&body); 403 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 404 m.Goto(&header); 405 406 m.Bind(end); 407 bt.AddReturn(phi); 408 409 CHECK_EQ(11, bt.call(11, 0)); 410 CHECK_EQ(110, bt.call(110, 0)); 411 CHECK_EQ(176, bt.call(176, 0)); 412 CHECK_EQ(0, bt.call(-200, 0)); 413 } 414 415 416 TEST(RunLoopIncrement3) { 417 RawMachineAssemblerTester<int32_t> m; 418 Int32BinopTester bt(&m); 419 420 // x = 0; while(x < param) { x++; } return x; 421 MLabel header, body; 422 MLabel* end = m.Exit(); 423 Node* zero = m.Int32Constant(0); 424 425 m.Goto(&header); 426 427 m.Bind(&header); 428 Node* phi = m.Phi(kMachInt32, zero, zero); 429 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end); 430 431 m.Bind(&body); 432 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 433 m.Goto(&header); 434 435 m.Bind(end); 436 bt.AddReturn(phi); 437 438 CHECK_EQ(11, bt.call(11, 0)); 439 CHECK_EQ(110, bt.call(110, 0)); 440 CHECK_EQ(176, bt.call(176, 0)); 441 CHECK_EQ(200, bt.call(200, 0)); 442 } 443 444 445 TEST(RunLoopDecrement) { 446 RawMachineAssemblerTester<int32_t> m; 447 Int32BinopTester bt(&m); 448 449 // x = param; while(x) { x--; } return x; 450 MLabel header, body; 451 MLabel* end = m.Exit(); 452 453 m.Goto(&header); 454 455 m.Bind(&header); 456 Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0)); 457 m.Branch(phi, &body, end); 458 459 m.Bind(&body); 460 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1))); 461 m.Goto(&header); 462 463 m.Bind(end); 464 bt.AddReturn(phi); 465 466 CHECK_EQ(0, bt.call(11, 0)); 467 CHECK_EQ(0, bt.call(110, 0)); 468 CHECK_EQ(0, bt.call(197, 0)); 469 } 470 471 472 TEST(RunLoopIncrementFloat64) { 473 RawMachineAssemblerTester<int32_t> m; 474 475 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x; 476 MLabel header, body; 477 MLabel* end = m.Exit(); 478 Node* minus_3 = m.Float64Constant(-3.0); 479 Node* ten = m.Float64Constant(10.0); 480 481 m.Goto(&header); 482 483 m.Bind(&header); 484 Node* phi = m.Phi(kMachFloat64, minus_3, ten); 485 m.Branch(m.Float64LessThan(phi, ten), &body, end); 486 487 m.Bind(&body); 488 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5))); 489 m.Goto(&header); 490 491 m.Bind(end); 492 m.Return(m.ChangeFloat64ToInt32(phi)); 493 494 CHECK_EQ(10, m.Call()); 495 } 496 497 498 TEST(RunLoadInt32) { 499 RawMachineAssemblerTester<int32_t> m; 500 501 int32_t p1 = 0; // loads directly from this location. 502 m.Return(m.LoadFromPointer(&p1, kMachInt32)); 503 504 FOR_INT32_INPUTS(i) { 505 p1 = *i; 506 CHECK_EQ(p1, m.Call()); 507 } 508 } 509 510 511 TEST(RunLoadInt32Offset) { 512 int32_t p1 = 0; // loads directly from this location. 513 514 int32_t offsets[] = {-2000000, -100, -101, 1, 3, 515 7, 120, 2000, 2000000000, 0xff}; 516 517 for (size_t i = 0; i < arraysize(offsets); i++) { 518 RawMachineAssemblerTester<int32_t> m; 519 int32_t offset = offsets[i]; 520 byte* pointer = reinterpret_cast<byte*>(&p1) - offset; 521 // generate load [#base + #index] 522 m.Return(m.LoadFromPointer(pointer, kMachInt32, offset)); 523 524 FOR_INT32_INPUTS(j) { 525 p1 = *j; 526 CHECK_EQ(p1, m.Call()); 527 } 528 } 529 } 530 531 532 TEST(RunLoadStoreFloat64Offset) { 533 double p1 = 0; // loads directly from this location. 534 double p2 = 0; // and stores directly into this location. 535 536 FOR_INT32_INPUTS(i) { 537 int32_t magic = 0x2342aabb + *i * 3; 538 RawMachineAssemblerTester<int32_t> m; 539 int32_t offset = *i; 540 byte* from = reinterpret_cast<byte*>(&p1) - offset; 541 byte* to = reinterpret_cast<byte*>(&p2) - offset; 542 // generate load [#base + #index] 543 Node* load = 544 m.Load(kMachFloat64, m.PointerConstant(from), m.Int32Constant(offset)); 545 m.Store(kMachFloat64, m.PointerConstant(to), m.Int32Constant(offset), load); 546 m.Return(m.Int32Constant(magic)); 547 548 FOR_FLOAT64_INPUTS(j) { 549 p1 = *j; 550 p2 = *j - 5; 551 CHECK_EQ(magic, m.Call()); 552 CHECK_EQ(p1, p2); 553 } 554 } 555 } 556 557 558 TEST(RunInt32AddP) { 559 RawMachineAssemblerTester<int32_t> m; 560 Int32BinopTester bt(&m); 561 562 bt.AddReturn(m.Int32Add(bt.param0, bt.param1)); 563 564 FOR_INT32_INPUTS(i) { 565 FOR_INT32_INPUTS(j) { 566 // Use uint32_t because signed overflow is UB in C. 567 int expected = static_cast<int32_t>(*i + *j); 568 CHECK_EQ(expected, bt.call(*i, *j)); 569 } 570 } 571 } 572 573 574 TEST(RunInt32AddAndWord32SarP) { 575 { 576 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); 577 m.Return(m.Int32Add(m.Parameter(0), 578 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 579 FOR_UINT32_INPUTS(i) { 580 FOR_INT32_INPUTS(j) { 581 FOR_UINT32_SHIFTS(shift) { 582 // Use uint32_t because signed overflow is UB in C. 583 int32_t expected = *i + (*j >> shift); 584 CHECK_EQ(expected, m.Call(*i, *j, shift)); 585 } 586 } 587 } 588 } 589 { 590 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); 591 m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 592 m.Parameter(2))); 593 FOR_INT32_INPUTS(i) { 594 FOR_UINT32_SHIFTS(shift) { 595 FOR_UINT32_INPUTS(k) { 596 // Use uint32_t because signed overflow is UB in C. 597 int32_t expected = (*i >> shift) + *k; 598 CHECK_EQ(expected, m.Call(*i, shift, *k)); 599 } 600 } 601 } 602 } 603 } 604 605 606 TEST(RunInt32AddAndWord32ShlP) { 607 { 608 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); 609 m.Return(m.Int32Add(m.Parameter(0), 610 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 611 FOR_UINT32_INPUTS(i) { 612 FOR_INT32_INPUTS(j) { 613 FOR_UINT32_SHIFTS(shift) { 614 // Use uint32_t because signed overflow is UB in C. 615 int32_t expected = *i + (*j << shift); 616 CHECK_EQ(expected, m.Call(*i, *j, shift)); 617 } 618 } 619 } 620 } 621 { 622 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); 623 m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 624 m.Parameter(2))); 625 FOR_INT32_INPUTS(i) { 626 FOR_UINT32_SHIFTS(shift) { 627 FOR_UINT32_INPUTS(k) { 628 // Use uint32_t because signed overflow is UB in C. 629 int32_t expected = (*i << shift) + *k; 630 CHECK_EQ(expected, m.Call(*i, shift, *k)); 631 } 632 } 633 } 634 } 635 } 636 637 638 TEST(RunInt32AddAndWord32ShrP) { 639 { 640 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 641 m.Return(m.Int32Add(m.Parameter(0), 642 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 643 FOR_UINT32_INPUTS(i) { 644 FOR_UINT32_INPUTS(j) { 645 FOR_UINT32_SHIFTS(shift) { 646 // Use uint32_t because signed overflow is UB in C. 647 int32_t expected = *i + (*j >> shift); 648 CHECK_EQ(expected, m.Call(*i, *j, shift)); 649 } 650 } 651 } 652 } 653 { 654 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 655 m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 656 m.Parameter(2))); 657 FOR_UINT32_INPUTS(i) { 658 FOR_UINT32_SHIFTS(shift) { 659 FOR_UINT32_INPUTS(k) { 660 // Use uint32_t because signed overflow is UB in C. 661 int32_t expected = (*i >> shift) + *k; 662 CHECK_EQ(expected, m.Call(*i, shift, *k)); 663 } 664 } 665 } 666 } 667 } 668 669 670 TEST(RunInt32AddInBranch) { 671 static const int32_t constant = 987654321; 672 { 673 RawMachineAssemblerTester<int32_t> m; 674 Uint32BinopTester bt(&m); 675 MLabel blocka, blockb; 676 m.Branch( 677 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), 678 &blocka, &blockb); 679 m.Bind(&blocka); 680 bt.AddReturn(m.Int32Constant(constant)); 681 m.Bind(&blockb); 682 bt.AddReturn(m.Int32Constant(0 - constant)); 683 FOR_UINT32_INPUTS(i) { 684 FOR_UINT32_INPUTS(j) { 685 int32_t expected = (*i + *j) == 0 ? constant : 0 - constant; 686 CHECK_EQ(expected, bt.call(*i, *j)); 687 } 688 } 689 } 690 { 691 RawMachineAssemblerTester<int32_t> m; 692 Uint32BinopTester bt(&m); 693 MLabel blocka, blockb; 694 m.Branch( 695 m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), 696 &blocka, &blockb); 697 m.Bind(&blocka); 698 bt.AddReturn(m.Int32Constant(constant)); 699 m.Bind(&blockb); 700 bt.AddReturn(m.Int32Constant(0 - constant)); 701 FOR_UINT32_INPUTS(i) { 702 FOR_UINT32_INPUTS(j) { 703 int32_t expected = (*i + *j) != 0 ? constant : 0 - constant; 704 CHECK_EQ(expected, bt.call(*i, *j)); 705 } 706 } 707 } 708 { 709 FOR_UINT32_INPUTS(i) { 710 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 711 MLabel blocka, blockb; 712 m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 713 m.Int32Constant(0)), 714 &blocka, &blockb); 715 m.Bind(&blocka); 716 m.Return(m.Int32Constant(constant)); 717 m.Bind(&blockb); 718 m.Return(m.Int32Constant(0 - constant)); 719 FOR_UINT32_INPUTS(j) { 720 uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant; 721 CHECK_UINT32_EQ(expected, m.Call(*j)); 722 } 723 } 724 } 725 { 726 FOR_UINT32_INPUTS(i) { 727 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 728 MLabel blocka, blockb; 729 m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 730 m.Int32Constant(0)), 731 &blocka, &blockb); 732 m.Bind(&blocka); 733 m.Return(m.Int32Constant(constant)); 734 m.Bind(&blockb); 735 m.Return(m.Int32Constant(0 - constant)); 736 FOR_UINT32_INPUTS(j) { 737 uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant; 738 CHECK_UINT32_EQ(expected, m.Call(*j)); 739 } 740 } 741 } 742 { 743 RawMachineAssemblerTester<void> m; 744 const Operator* shops[] = {m.machine()->Word32Sar(), 745 m.machine()->Word32Shl(), 746 m.machine()->Word32Shr()}; 747 for (size_t n = 0; n < arraysize(shops); n++) { 748 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 749 kMachUint32); 750 MLabel blocka, blockb; 751 m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0), 752 m.NewNode(shops[n], m.Parameter(1), 753 m.Parameter(2))), 754 m.Int32Constant(0)), 755 &blocka, &blockb); 756 m.Bind(&blocka); 757 m.Return(m.Int32Constant(constant)); 758 m.Bind(&blockb); 759 m.Return(m.Int32Constant(0 - constant)); 760 FOR_UINT32_INPUTS(i) { 761 FOR_INT32_INPUTS(j) { 762 FOR_UINT32_SHIFTS(shift) { 763 int32_t right; 764 switch (shops[n]->opcode()) { 765 default: 766 UNREACHABLE(); 767 case IrOpcode::kWord32Sar: 768 right = *j >> shift; 769 break; 770 case IrOpcode::kWord32Shl: 771 right = *j << shift; 772 break; 773 case IrOpcode::kWord32Shr: 774 right = static_cast<uint32_t>(*j) >> shift; 775 break; 776 } 777 int32_t expected = ((*i + right) == 0) ? constant : 0 - constant; 778 CHECK_EQ(expected, m.Call(*i, *j, shift)); 779 } 780 } 781 } 782 } 783 } 784 } 785 786 787 TEST(RunInt32AddInComparison) { 788 { 789 RawMachineAssemblerTester<int32_t> m; 790 Uint32BinopTester bt(&m); 791 bt.AddReturn( 792 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0))); 793 FOR_UINT32_INPUTS(i) { 794 FOR_UINT32_INPUTS(j) { 795 uint32_t expected = (*i + *j) == 0; 796 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 797 } 798 } 799 } 800 { 801 RawMachineAssemblerTester<int32_t> m; 802 Uint32BinopTester bt(&m); 803 bt.AddReturn( 804 m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1))); 805 FOR_UINT32_INPUTS(i) { 806 FOR_UINT32_INPUTS(j) { 807 uint32_t expected = (*i + *j) == 0; 808 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 809 } 810 } 811 } 812 { 813 FOR_UINT32_INPUTS(i) { 814 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 815 m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 816 m.Int32Constant(0))); 817 FOR_UINT32_INPUTS(j) { 818 uint32_t expected = (*i + *j) == 0; 819 CHECK_UINT32_EQ(expected, m.Call(*j)); 820 } 821 } 822 } 823 { 824 FOR_UINT32_INPUTS(i) { 825 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 826 m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)), 827 m.Int32Constant(0))); 828 FOR_UINT32_INPUTS(j) { 829 uint32_t expected = (*j + *i) == 0; 830 CHECK_UINT32_EQ(expected, m.Call(*j)); 831 } 832 } 833 } 834 { 835 RawMachineAssemblerTester<void> m; 836 const Operator* shops[] = {m.machine()->Word32Sar(), 837 m.machine()->Word32Shl(), 838 m.machine()->Word32Shr()}; 839 for (size_t n = 0; n < arraysize(shops); n++) { 840 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 841 kMachUint32); 842 m.Return(m.Word32Equal( 843 m.Int32Add(m.Parameter(0), 844 m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))), 845 m.Int32Constant(0))); 846 FOR_UINT32_INPUTS(i) { 847 FOR_INT32_INPUTS(j) { 848 FOR_UINT32_SHIFTS(shift) { 849 int32_t right; 850 switch (shops[n]->opcode()) { 851 default: 852 UNREACHABLE(); 853 case IrOpcode::kWord32Sar: 854 right = *j >> shift; 855 break; 856 case IrOpcode::kWord32Shl: 857 right = *j << shift; 858 break; 859 case IrOpcode::kWord32Shr: 860 right = static_cast<uint32_t>(*j) >> shift; 861 break; 862 } 863 int32_t expected = (*i + right) == 0; 864 CHECK_EQ(expected, m.Call(*i, *j, shift)); 865 } 866 } 867 } 868 } 869 } 870 } 871 872 873 TEST(RunInt32SubP) { 874 RawMachineAssemblerTester<int32_t> m; 875 Uint32BinopTester bt(&m); 876 877 m.Return(m.Int32Sub(bt.param0, bt.param1)); 878 879 FOR_UINT32_INPUTS(i) { 880 FOR_UINT32_INPUTS(j) { 881 uint32_t expected = static_cast<int32_t>(*i - *j); 882 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 883 } 884 } 885 } 886 887 888 TEST(RunInt32SubImm) { 889 { 890 FOR_UINT32_INPUTS(i) { 891 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 892 m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0))); 893 FOR_UINT32_INPUTS(j) { 894 uint32_t expected = *i - *j; 895 CHECK_UINT32_EQ(expected, m.Call(*j)); 896 } 897 } 898 } 899 { 900 FOR_UINT32_INPUTS(i) { 901 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 902 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i))); 903 FOR_UINT32_INPUTS(j) { 904 uint32_t expected = *j - *i; 905 CHECK_UINT32_EQ(expected, m.Call(*j)); 906 } 907 } 908 } 909 } 910 911 912 TEST(RunInt32SubAndWord32SarP) { 913 { 914 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); 915 m.Return(m.Int32Sub(m.Parameter(0), 916 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 917 FOR_UINT32_INPUTS(i) { 918 FOR_INT32_INPUTS(j) { 919 FOR_UINT32_SHIFTS(shift) { 920 int32_t expected = *i - (*j >> shift); 921 CHECK_EQ(expected, m.Call(*i, *j, shift)); 922 } 923 } 924 } 925 } 926 { 927 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); 928 m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 929 m.Parameter(2))); 930 FOR_INT32_INPUTS(i) { 931 FOR_UINT32_SHIFTS(shift) { 932 FOR_UINT32_INPUTS(k) { 933 int32_t expected = (*i >> shift) - *k; 934 CHECK_EQ(expected, m.Call(*i, shift, *k)); 935 } 936 } 937 } 938 } 939 } 940 941 942 TEST(RunInt32SubAndWord32ShlP) { 943 { 944 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); 945 m.Return(m.Int32Sub(m.Parameter(0), 946 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 947 FOR_UINT32_INPUTS(i) { 948 FOR_INT32_INPUTS(j) { 949 FOR_UINT32_SHIFTS(shift) { 950 int32_t expected = *i - (*j << shift); 951 CHECK_EQ(expected, m.Call(*i, *j, shift)); 952 } 953 } 954 } 955 } 956 { 957 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); 958 m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 959 m.Parameter(2))); 960 FOR_INT32_INPUTS(i) { 961 FOR_UINT32_SHIFTS(shift) { 962 FOR_UINT32_INPUTS(k) { 963 // Use uint32_t because signed overflow is UB in C. 964 int32_t expected = (*i << shift) - *k; 965 CHECK_EQ(expected, m.Call(*i, shift, *k)); 966 } 967 } 968 } 969 } 970 } 971 972 973 TEST(RunInt32SubAndWord32ShrP) { 974 { 975 RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32, 976 kMachUint32); 977 m.Return(m.Int32Sub(m.Parameter(0), 978 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 979 FOR_UINT32_INPUTS(i) { 980 FOR_UINT32_INPUTS(j) { 981 FOR_UINT32_SHIFTS(shift) { 982 // Use uint32_t because signed overflow is UB in C. 983 int32_t expected = *i - (*j >> shift); 984 CHECK_UINT32_EQ(expected, m.Call(*i, *j, shift)); 985 } 986 } 987 } 988 } 989 { 990 RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32, 991 kMachUint32); 992 m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 993 m.Parameter(2))); 994 FOR_UINT32_INPUTS(i) { 995 FOR_UINT32_SHIFTS(shift) { 996 FOR_UINT32_INPUTS(k) { 997 // Use uint32_t because signed overflow is UB in C. 998 int32_t expected = (*i >> shift) - *k; 999 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1000 } 1001 } 1002 } 1003 } 1004 } 1005 1006 1007 TEST(RunInt32SubInBranch) { 1008 static const int constant = 987654321; 1009 { 1010 RawMachineAssemblerTester<int32_t> m; 1011 Uint32BinopTester bt(&m); 1012 MLabel blocka, blockb; 1013 m.Branch( 1014 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), 1015 &blocka, &blockb); 1016 m.Bind(&blocka); 1017 bt.AddReturn(m.Int32Constant(constant)); 1018 m.Bind(&blockb); 1019 bt.AddReturn(m.Int32Constant(0 - constant)); 1020 FOR_UINT32_INPUTS(i) { 1021 FOR_UINT32_INPUTS(j) { 1022 int32_t expected = (*i - *j) == 0 ? constant : 0 - constant; 1023 CHECK_EQ(expected, bt.call(*i, *j)); 1024 } 1025 } 1026 } 1027 { 1028 RawMachineAssemblerTester<int32_t> m; 1029 Uint32BinopTester bt(&m); 1030 MLabel blocka, blockb; 1031 m.Branch( 1032 m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), 1033 &blocka, &blockb); 1034 m.Bind(&blocka); 1035 bt.AddReturn(m.Int32Constant(constant)); 1036 m.Bind(&blockb); 1037 bt.AddReturn(m.Int32Constant(0 - constant)); 1038 FOR_UINT32_INPUTS(i) { 1039 FOR_UINT32_INPUTS(j) { 1040 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant; 1041 CHECK_EQ(expected, bt.call(*i, *j)); 1042 } 1043 } 1044 } 1045 { 1046 FOR_UINT32_INPUTS(i) { 1047 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1048 MLabel blocka, blockb; 1049 m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1050 m.Int32Constant(0)), 1051 &blocka, &blockb); 1052 m.Bind(&blocka); 1053 m.Return(m.Int32Constant(constant)); 1054 m.Bind(&blockb); 1055 m.Return(m.Int32Constant(0 - constant)); 1056 FOR_UINT32_INPUTS(j) { 1057 int32_t expected = (*i - *j) == 0 ? constant : 0 - constant; 1058 CHECK_EQ(expected, m.Call(*j)); 1059 } 1060 } 1061 } 1062 { 1063 FOR_UINT32_INPUTS(i) { 1064 RawMachineAssemblerTester<int32_t> m(kMachUint32); 1065 MLabel blocka, blockb; 1066 m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1067 m.Int32Constant(0)), 1068 &blocka, &blockb); 1069 m.Bind(&blocka); 1070 m.Return(m.Int32Constant(constant)); 1071 m.Bind(&blockb); 1072 m.Return(m.Int32Constant(0 - constant)); 1073 FOR_UINT32_INPUTS(j) { 1074 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant; 1075 CHECK_EQ(expected, m.Call(*j)); 1076 } 1077 } 1078 } 1079 { 1080 RawMachineAssemblerTester<void> m; 1081 const Operator* shops[] = {m.machine()->Word32Sar(), 1082 m.machine()->Word32Shl(), 1083 m.machine()->Word32Shr()}; 1084 for (size_t n = 0; n < arraysize(shops); n++) { 1085 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 1086 kMachUint32); 1087 MLabel blocka, blockb; 1088 m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0), 1089 m.NewNode(shops[n], m.Parameter(1), 1090 m.Parameter(2))), 1091 m.Int32Constant(0)), 1092 &blocka, &blockb); 1093 m.Bind(&blocka); 1094 m.Return(m.Int32Constant(constant)); 1095 m.Bind(&blockb); 1096 m.Return(m.Int32Constant(0 - constant)); 1097 FOR_UINT32_INPUTS(i) { 1098 FOR_INT32_INPUTS(j) { 1099 FOR_UINT32_SHIFTS(shift) { 1100 int32_t right; 1101 switch (shops[n]->opcode()) { 1102 default: 1103 UNREACHABLE(); 1104 case IrOpcode::kWord32Sar: 1105 right = *j >> shift; 1106 break; 1107 case IrOpcode::kWord32Shl: 1108 right = *j << shift; 1109 break; 1110 case IrOpcode::kWord32Shr: 1111 right = static_cast<uint32_t>(*j) >> shift; 1112 break; 1113 } 1114 int32_t expected = ((*i - right) == 0) ? constant : 0 - constant; 1115 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1116 } 1117 } 1118 } 1119 } 1120 } 1121 } 1122 1123 1124 TEST(RunInt32SubInComparison) { 1125 { 1126 RawMachineAssemblerTester<int32_t> m; 1127 Uint32BinopTester bt(&m); 1128 bt.AddReturn( 1129 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0))); 1130 FOR_UINT32_INPUTS(i) { 1131 FOR_UINT32_INPUTS(j) { 1132 uint32_t expected = (*i - *j) == 0; 1133 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1134 } 1135 } 1136 } 1137 { 1138 RawMachineAssemblerTester<int32_t> m; 1139 Uint32BinopTester bt(&m); 1140 bt.AddReturn( 1141 m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1))); 1142 FOR_UINT32_INPUTS(i) { 1143 FOR_UINT32_INPUTS(j) { 1144 uint32_t expected = (*i - *j) == 0; 1145 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1146 } 1147 } 1148 } 1149 { 1150 FOR_UINT32_INPUTS(i) { 1151 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1152 m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1153 m.Int32Constant(0))); 1154 FOR_UINT32_INPUTS(j) { 1155 uint32_t expected = (*i - *j) == 0; 1156 CHECK_UINT32_EQ(expected, m.Call(*j)); 1157 } 1158 } 1159 } 1160 { 1161 FOR_UINT32_INPUTS(i) { 1162 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1163 m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)), 1164 m.Int32Constant(0))); 1165 FOR_UINT32_INPUTS(j) { 1166 uint32_t expected = (*j - *i) == 0; 1167 CHECK_UINT32_EQ(expected, m.Call(*j)); 1168 } 1169 } 1170 } 1171 { 1172 RawMachineAssemblerTester<void> m; 1173 const Operator* shops[] = {m.machine()->Word32Sar(), 1174 m.machine()->Word32Shl(), 1175 m.machine()->Word32Shr()}; 1176 for (size_t n = 0; n < arraysize(shops); n++) { 1177 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 1178 kMachUint32); 1179 m.Return(m.Word32Equal( 1180 m.Int32Sub(m.Parameter(0), 1181 m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))), 1182 m.Int32Constant(0))); 1183 FOR_UINT32_INPUTS(i) { 1184 FOR_INT32_INPUTS(j) { 1185 FOR_UINT32_SHIFTS(shift) { 1186 int32_t right; 1187 switch (shops[n]->opcode()) { 1188 default: 1189 UNREACHABLE(); 1190 case IrOpcode::kWord32Sar: 1191 right = *j >> shift; 1192 break; 1193 case IrOpcode::kWord32Shl: 1194 right = *j << shift; 1195 break; 1196 case IrOpcode::kWord32Shr: 1197 right = static_cast<uint32_t>(*j) >> shift; 1198 break; 1199 } 1200 int32_t expected = (*i - right) == 0; 1201 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1202 } 1203 } 1204 } 1205 } 1206 } 1207 } 1208 1209 1210 TEST(RunInt32MulP) { 1211 { 1212 RawMachineAssemblerTester<int32_t> m; 1213 Int32BinopTester bt(&m); 1214 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1)); 1215 FOR_INT32_INPUTS(i) { 1216 FOR_INT32_INPUTS(j) { 1217 int expected = static_cast<int32_t>(*i * *j); 1218 CHECK_EQ(expected, bt.call(*i, *j)); 1219 } 1220 } 1221 } 1222 { 1223 RawMachineAssemblerTester<int32_t> m; 1224 Uint32BinopTester bt(&m); 1225 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1)); 1226 FOR_UINT32_INPUTS(i) { 1227 FOR_UINT32_INPUTS(j) { 1228 uint32_t expected = *i * *j; 1229 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1230 } 1231 } 1232 } 1233 } 1234 1235 1236 TEST(RunInt32MulImm) { 1237 { 1238 FOR_UINT32_INPUTS(i) { 1239 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1240 m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0))); 1241 FOR_UINT32_INPUTS(j) { 1242 uint32_t expected = *i * *j; 1243 CHECK_UINT32_EQ(expected, m.Call(*j)); 1244 } 1245 } 1246 } 1247 { 1248 FOR_UINT32_INPUTS(i) { 1249 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1250 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i))); 1251 FOR_UINT32_INPUTS(j) { 1252 uint32_t expected = *j * *i; 1253 CHECK_UINT32_EQ(expected, m.Call(*j)); 1254 } 1255 } 1256 } 1257 } 1258 1259 1260 TEST(RunInt32MulAndInt32AddP) { 1261 { 1262 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); 1263 m.Return( 1264 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); 1265 FOR_INT32_INPUTS(i) { 1266 FOR_INT32_INPUTS(j) { 1267 FOR_INT32_INPUTS(k) { 1268 int32_t p0 = *i; 1269 int32_t p1 = *j; 1270 int32_t p2 = *k; 1271 int expected = p0 + static_cast<int32_t>(p1 * p2); 1272 CHECK_EQ(expected, m.Call(p0, p1, p2)); 1273 } 1274 } 1275 } 1276 } 1277 { 1278 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); 1279 m.Return( 1280 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); 1281 FOR_INT32_INPUTS(i) { 1282 FOR_INT32_INPUTS(j) { 1283 FOR_INT32_INPUTS(k) { 1284 int32_t p0 = *i; 1285 int32_t p1 = *j; 1286 int32_t p2 = *k; 1287 int expected = static_cast<int32_t>(p0 * p1) + p2; 1288 CHECK_EQ(expected, m.Call(p0, p1, p2)); 1289 } 1290 } 1291 } 1292 } 1293 { 1294 FOR_INT32_INPUTS(i) { 1295 RawMachineAssemblerTester<int32_t> m; 1296 Int32BinopTester bt(&m); 1297 bt.AddReturn( 1298 m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1))); 1299 FOR_INT32_INPUTS(j) { 1300 FOR_INT32_INPUTS(k) { 1301 int32_t p0 = *j; 1302 int32_t p1 = *k; 1303 int expected = *i + static_cast<int32_t>(p0 * p1); 1304 CHECK_EQ(expected, bt.call(p0, p1)); 1305 } 1306 } 1307 } 1308 } 1309 } 1310 1311 1312 TEST(RunInt32MulAndInt32SubP) { 1313 { 1314 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachInt32); 1315 m.Return( 1316 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); 1317 FOR_UINT32_INPUTS(i) { 1318 FOR_INT32_INPUTS(j) { 1319 FOR_INT32_INPUTS(k) { 1320 uint32_t p0 = *i; 1321 int32_t p1 = *j; 1322 int32_t p2 = *k; 1323 // Use uint32_t because signed overflow is UB in C. 1324 int expected = p0 - static_cast<uint32_t>(p1 * p2); 1325 CHECK_EQ(expected, m.Call(p0, p1, p2)); 1326 } 1327 } 1328 } 1329 } 1330 { 1331 FOR_UINT32_INPUTS(i) { 1332 RawMachineAssemblerTester<int32_t> m; 1333 Int32BinopTester bt(&m); 1334 bt.AddReturn( 1335 m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1))); 1336 FOR_INT32_INPUTS(j) { 1337 FOR_INT32_INPUTS(k) { 1338 int32_t p0 = *j; 1339 int32_t p1 = *k; 1340 // Use uint32_t because signed overflow is UB in C. 1341 int expected = *i - static_cast<uint32_t>(p0 * p1); 1342 CHECK_EQ(expected, bt.call(p0, p1)); 1343 } 1344 } 1345 } 1346 } 1347 } 1348 1349 1350 TEST(RunInt32DivP) { 1351 { 1352 RawMachineAssemblerTester<int32_t> m; 1353 Int32BinopTester bt(&m); 1354 bt.AddReturn(m.Int32Div(bt.param0, bt.param1)); 1355 FOR_INT32_INPUTS(i) { 1356 FOR_INT32_INPUTS(j) { 1357 int p0 = *i; 1358 int p1 = *j; 1359 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 1360 int expected = static_cast<int32_t>(p0 / p1); 1361 CHECK_EQ(expected, bt.call(p0, p1)); 1362 } 1363 } 1364 } 1365 } 1366 { 1367 RawMachineAssemblerTester<int32_t> m; 1368 Int32BinopTester bt(&m); 1369 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1))); 1370 FOR_INT32_INPUTS(i) { 1371 FOR_INT32_INPUTS(j) { 1372 int p0 = *i; 1373 int p1 = *j; 1374 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 1375 int expected = static_cast<int32_t>(p0 + (p0 / p1)); 1376 CHECK_EQ(expected, bt.call(p0, p1)); 1377 } 1378 } 1379 } 1380 } 1381 } 1382 1383 1384 TEST(RunInt32UDivP) { 1385 { 1386 RawMachineAssemblerTester<int32_t> m; 1387 Int32BinopTester bt(&m); 1388 bt.AddReturn(m.Int32UDiv(bt.param0, bt.param1)); 1389 FOR_UINT32_INPUTS(i) { 1390 FOR_UINT32_INPUTS(j) { 1391 uint32_t p0 = *i; 1392 uint32_t p1 = *j; 1393 if (p1 != 0) { 1394 uint32_t expected = static_cast<uint32_t>(p0 / p1); 1395 CHECK_EQ(expected, bt.call(p0, p1)); 1396 } 1397 } 1398 } 1399 } 1400 { 1401 RawMachineAssemblerTester<int32_t> m; 1402 Int32BinopTester bt(&m); 1403 bt.AddReturn(m.Int32Add(bt.param0, m.Int32UDiv(bt.param0, bt.param1))); 1404 FOR_UINT32_INPUTS(i) { 1405 FOR_UINT32_INPUTS(j) { 1406 uint32_t p0 = *i; 1407 uint32_t p1 = *j; 1408 if (p1 != 0) { 1409 uint32_t expected = static_cast<uint32_t>(p0 + (p0 / p1)); 1410 CHECK_EQ(expected, bt.call(p0, p1)); 1411 } 1412 } 1413 } 1414 } 1415 } 1416 1417 1418 TEST(RunInt32ModP) { 1419 { 1420 RawMachineAssemblerTester<int32_t> m; 1421 Int32BinopTester bt(&m); 1422 bt.AddReturn(m.Int32Mod(bt.param0, bt.param1)); 1423 FOR_INT32_INPUTS(i) { 1424 FOR_INT32_INPUTS(j) { 1425 int p0 = *i; 1426 int p1 = *j; 1427 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 1428 int expected = static_cast<int32_t>(p0 % p1); 1429 CHECK_EQ(expected, bt.call(p0, p1)); 1430 } 1431 } 1432 } 1433 } 1434 { 1435 RawMachineAssemblerTester<int32_t> m; 1436 Int32BinopTester bt(&m); 1437 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1))); 1438 FOR_INT32_INPUTS(i) { 1439 FOR_INT32_INPUTS(j) { 1440 int p0 = *i; 1441 int p1 = *j; 1442 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 1443 int expected = static_cast<int32_t>(p0 + (p0 % p1)); 1444 CHECK_EQ(expected, bt.call(p0, p1)); 1445 } 1446 } 1447 } 1448 } 1449 } 1450 1451 1452 TEST(RunInt32UModP) { 1453 { 1454 RawMachineAssemblerTester<int32_t> m; 1455 Int32BinopTester bt(&m); 1456 bt.AddReturn(m.Int32UMod(bt.param0, bt.param1)); 1457 FOR_UINT32_INPUTS(i) { 1458 FOR_UINT32_INPUTS(j) { 1459 uint32_t p0 = *i; 1460 uint32_t p1 = *j; 1461 if (p1 != 0) { 1462 uint32_t expected = static_cast<uint32_t>(p0 % p1); 1463 CHECK_EQ(expected, bt.call(p0, p1)); 1464 } 1465 } 1466 } 1467 } 1468 { 1469 RawMachineAssemblerTester<int32_t> m; 1470 Int32BinopTester bt(&m); 1471 bt.AddReturn(m.Int32Add(bt.param0, m.Int32UMod(bt.param0, bt.param1))); 1472 FOR_UINT32_INPUTS(i) { 1473 FOR_UINT32_INPUTS(j) { 1474 uint32_t p0 = *i; 1475 uint32_t p1 = *j; 1476 if (p1 != 0) { 1477 uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1)); 1478 CHECK_EQ(expected, bt.call(p0, p1)); 1479 } 1480 } 1481 } 1482 } 1483 } 1484 1485 1486 TEST(RunWord32AndP) { 1487 { 1488 RawMachineAssemblerTester<int32_t> m; 1489 Int32BinopTester bt(&m); 1490 bt.AddReturn(m.Word32And(bt.param0, bt.param1)); 1491 FOR_UINT32_INPUTS(i) { 1492 FOR_UINT32_INPUTS(j) { 1493 uint32_t expected = *i & *j; 1494 CHECK_EQ(expected, bt.call(*i, *j)); 1495 } 1496 } 1497 } 1498 { 1499 RawMachineAssemblerTester<int32_t> m; 1500 Int32BinopTester bt(&m); 1501 bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1))); 1502 FOR_UINT32_INPUTS(i) { 1503 FOR_UINT32_INPUTS(j) { 1504 uint32_t expected = *i & ~(*j); 1505 CHECK_EQ(expected, bt.call(*i, *j)); 1506 } 1507 } 1508 } 1509 { 1510 RawMachineAssemblerTester<int32_t> m; 1511 Int32BinopTester bt(&m); 1512 bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1)); 1513 FOR_UINT32_INPUTS(i) { 1514 FOR_UINT32_INPUTS(j) { 1515 uint32_t expected = ~(*i) & *j; 1516 CHECK_EQ(expected, bt.call(*i, *j)); 1517 } 1518 } 1519 } 1520 } 1521 1522 1523 TEST(RunWord32AndAndWord32ShlP) { 1524 { 1525 RawMachineAssemblerTester<int32_t> m; 1526 Uint32BinopTester bt(&m); 1527 bt.AddReturn( 1528 m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 1529 FOR_UINT32_INPUTS(i) { 1530 FOR_UINT32_INPUTS(j) { 1531 uint32_t expected = *i << (*j & 0x1f); 1532 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1533 } 1534 } 1535 } 1536 { 1537 RawMachineAssemblerTester<int32_t> m; 1538 Uint32BinopTester bt(&m); 1539 bt.AddReturn( 1540 m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 1541 FOR_UINT32_INPUTS(i) { 1542 FOR_UINT32_INPUTS(j) { 1543 uint32_t expected = *i << (0x1f & *j); 1544 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1545 } 1546 } 1547 } 1548 } 1549 1550 1551 TEST(RunWord32AndAndWord32ShrP) { 1552 { 1553 RawMachineAssemblerTester<int32_t> m; 1554 Uint32BinopTester bt(&m); 1555 bt.AddReturn( 1556 m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 1557 FOR_UINT32_INPUTS(i) { 1558 FOR_UINT32_INPUTS(j) { 1559 uint32_t expected = *i >> (*j & 0x1f); 1560 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1561 } 1562 } 1563 } 1564 { 1565 RawMachineAssemblerTester<int32_t> m; 1566 Uint32BinopTester bt(&m); 1567 bt.AddReturn( 1568 m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 1569 FOR_UINT32_INPUTS(i) { 1570 FOR_UINT32_INPUTS(j) { 1571 uint32_t expected = *i >> (0x1f & *j); 1572 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1573 } 1574 } 1575 } 1576 } 1577 1578 1579 TEST(RunWord32AndAndWord32SarP) { 1580 { 1581 RawMachineAssemblerTester<int32_t> m; 1582 Int32BinopTester bt(&m); 1583 bt.AddReturn( 1584 m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 1585 FOR_INT32_INPUTS(i) { 1586 FOR_INT32_INPUTS(j) { 1587 int32_t expected = *i >> (*j & 0x1f); 1588 CHECK_EQ(expected, bt.call(*i, *j)); 1589 } 1590 } 1591 } 1592 { 1593 RawMachineAssemblerTester<int32_t> m; 1594 Int32BinopTester bt(&m); 1595 bt.AddReturn( 1596 m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 1597 FOR_INT32_INPUTS(i) { 1598 FOR_INT32_INPUTS(j) { 1599 uint32_t expected = *i >> (0x1f & *j); 1600 CHECK_EQ(expected, bt.call(*i, *j)); 1601 } 1602 } 1603 } 1604 } 1605 1606 1607 TEST(RunWord32AndImm) { 1608 { 1609 FOR_UINT32_INPUTS(i) { 1610 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1611 m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0))); 1612 FOR_UINT32_INPUTS(j) { 1613 uint32_t expected = *i & *j; 1614 CHECK_UINT32_EQ(expected, m.Call(*j)); 1615 } 1616 } 1617 } 1618 { 1619 FOR_UINT32_INPUTS(i) { 1620 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1621 m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 1622 FOR_UINT32_INPUTS(j) { 1623 uint32_t expected = *i & ~(*j); 1624 CHECK_UINT32_EQ(expected, m.Call(*j)); 1625 } 1626 } 1627 } 1628 } 1629 1630 1631 TEST(RunWord32AndInBranch) { 1632 static const int constant = 987654321; 1633 { 1634 RawMachineAssemblerTester<int32_t> m; 1635 Uint32BinopTester bt(&m); 1636 MLabel blocka, blockb; 1637 m.Branch( 1638 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), 1639 &blocka, &blockb); 1640 m.Bind(&blocka); 1641 bt.AddReturn(m.Int32Constant(constant)); 1642 m.Bind(&blockb); 1643 bt.AddReturn(m.Int32Constant(0 - constant)); 1644 FOR_UINT32_INPUTS(i) { 1645 FOR_UINT32_INPUTS(j) { 1646 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant; 1647 CHECK_EQ(expected, bt.call(*i, *j)); 1648 } 1649 } 1650 } 1651 { 1652 RawMachineAssemblerTester<int32_t> m; 1653 Uint32BinopTester bt(&m); 1654 MLabel blocka, blockb; 1655 m.Branch( 1656 m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), 1657 &blocka, &blockb); 1658 m.Bind(&blocka); 1659 bt.AddReturn(m.Int32Constant(constant)); 1660 m.Bind(&blockb); 1661 bt.AddReturn(m.Int32Constant(0 - constant)); 1662 FOR_UINT32_INPUTS(i) { 1663 FOR_UINT32_INPUTS(j) { 1664 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant; 1665 CHECK_EQ(expected, bt.call(*i, *j)); 1666 } 1667 } 1668 } 1669 { 1670 FOR_UINT32_INPUTS(i) { 1671 RawMachineAssemblerTester<int32_t> m(kMachUint32); 1672 MLabel blocka, blockb; 1673 m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 1674 m.Int32Constant(0)), 1675 &blocka, &blockb); 1676 m.Bind(&blocka); 1677 m.Return(m.Int32Constant(constant)); 1678 m.Bind(&blockb); 1679 m.Return(m.Int32Constant(0 - constant)); 1680 FOR_UINT32_INPUTS(j) { 1681 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant; 1682 CHECK_EQ(expected, m.Call(*j)); 1683 } 1684 } 1685 } 1686 { 1687 FOR_UINT32_INPUTS(i) { 1688 RawMachineAssemblerTester<int32_t> m(kMachUint32); 1689 MLabel blocka, blockb; 1690 m.Branch( 1691 m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 1692 m.Int32Constant(0)), 1693 &blocka, &blockb); 1694 m.Bind(&blocka); 1695 m.Return(m.Int32Constant(constant)); 1696 m.Bind(&blockb); 1697 m.Return(m.Int32Constant(0 - constant)); 1698 FOR_UINT32_INPUTS(j) { 1699 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant; 1700 CHECK_EQ(expected, m.Call(*j)); 1701 } 1702 } 1703 } 1704 { 1705 RawMachineAssemblerTester<void> m; 1706 const Operator* shops[] = {m.machine()->Word32Sar(), 1707 m.machine()->Word32Shl(), 1708 m.machine()->Word32Shr()}; 1709 for (size_t n = 0; n < arraysize(shops); n++) { 1710 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 1711 kMachUint32); 1712 MLabel blocka, blockb; 1713 m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0), 1714 m.NewNode(shops[n], m.Parameter(1), 1715 m.Parameter(2))), 1716 m.Int32Constant(0)), 1717 &blocka, &blockb); 1718 m.Bind(&blocka); 1719 m.Return(m.Int32Constant(constant)); 1720 m.Bind(&blockb); 1721 m.Return(m.Int32Constant(0 - constant)); 1722 FOR_UINT32_INPUTS(i) { 1723 FOR_INT32_INPUTS(j) { 1724 FOR_UINT32_SHIFTS(shift) { 1725 int32_t right; 1726 switch (shops[n]->opcode()) { 1727 default: 1728 UNREACHABLE(); 1729 case IrOpcode::kWord32Sar: 1730 right = *j >> shift; 1731 break; 1732 case IrOpcode::kWord32Shl: 1733 right = *j << shift; 1734 break; 1735 case IrOpcode::kWord32Shr: 1736 right = static_cast<uint32_t>(*j) >> shift; 1737 break; 1738 } 1739 int32_t expected = ((*i & right) == 0) ? constant : 0 - constant; 1740 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1741 } 1742 } 1743 } 1744 } 1745 } 1746 } 1747 1748 1749 TEST(RunWord32AndInComparison) { 1750 { 1751 RawMachineAssemblerTester<int32_t> m; 1752 Uint32BinopTester bt(&m); 1753 bt.AddReturn( 1754 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0))); 1755 FOR_UINT32_INPUTS(i) { 1756 FOR_UINT32_INPUTS(j) { 1757 uint32_t expected = (*i & *j) == 0; 1758 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1759 } 1760 } 1761 } 1762 { 1763 RawMachineAssemblerTester<int32_t> m; 1764 Uint32BinopTester bt(&m); 1765 bt.AddReturn( 1766 m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1))); 1767 FOR_UINT32_INPUTS(i) { 1768 FOR_UINT32_INPUTS(j) { 1769 uint32_t expected = (*i & *j) == 0; 1770 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1771 } 1772 } 1773 } 1774 { 1775 FOR_UINT32_INPUTS(i) { 1776 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1777 m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 1778 m.Int32Constant(0))); 1779 FOR_UINT32_INPUTS(j) { 1780 uint32_t expected = (*i & *j) == 0; 1781 CHECK_UINT32_EQ(expected, m.Call(*j)); 1782 } 1783 } 1784 } 1785 { 1786 FOR_UINT32_INPUTS(i) { 1787 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1788 m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)), 1789 m.Int32Constant(0))); 1790 FOR_UINT32_INPUTS(j) { 1791 uint32_t expected = (*j & *i) == 0; 1792 CHECK_UINT32_EQ(expected, m.Call(*j)); 1793 } 1794 } 1795 } 1796 } 1797 1798 1799 TEST(RunWord32OrP) { 1800 { 1801 RawMachineAssemblerTester<int32_t> m; 1802 Uint32BinopTester bt(&m); 1803 bt.AddReturn(m.Word32Or(bt.param0, bt.param1)); 1804 FOR_UINT32_INPUTS(i) { 1805 FOR_UINT32_INPUTS(j) { 1806 uint32_t expected = *i | *j; 1807 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1808 } 1809 } 1810 } 1811 { 1812 RawMachineAssemblerTester<int32_t> m; 1813 Uint32BinopTester bt(&m); 1814 bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1))); 1815 FOR_UINT32_INPUTS(i) { 1816 FOR_UINT32_INPUTS(j) { 1817 uint32_t expected = *i | ~(*j); 1818 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1819 } 1820 } 1821 } 1822 { 1823 RawMachineAssemblerTester<int32_t> m; 1824 Uint32BinopTester bt(&m); 1825 bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1)); 1826 FOR_UINT32_INPUTS(i) { 1827 FOR_UINT32_INPUTS(j) { 1828 uint32_t expected = ~(*i) | *j; 1829 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 1830 } 1831 } 1832 } 1833 } 1834 1835 1836 TEST(RunWord32OrImm) { 1837 { 1838 FOR_UINT32_INPUTS(i) { 1839 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1840 m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0))); 1841 FOR_UINT32_INPUTS(j) { 1842 uint32_t expected = *i | *j; 1843 CHECK_UINT32_EQ(expected, m.Call(*j)); 1844 } 1845 } 1846 } 1847 { 1848 FOR_UINT32_INPUTS(i) { 1849 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 1850 m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 1851 FOR_UINT32_INPUTS(j) { 1852 uint32_t expected = *i | ~(*j); 1853 CHECK_UINT32_EQ(expected, m.Call(*j)); 1854 } 1855 } 1856 } 1857 } 1858 1859 1860 TEST(RunWord32OrInBranch) { 1861 static const int constant = 987654321; 1862 { 1863 RawMachineAssemblerTester<int32_t> m; 1864 Int32BinopTester bt(&m); 1865 MLabel blocka, blockb; 1866 m.Branch( 1867 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), 1868 &blocka, &blockb); 1869 m.Bind(&blocka); 1870 bt.AddReturn(m.Int32Constant(constant)); 1871 m.Bind(&blockb); 1872 bt.AddReturn(m.Int32Constant(0 - constant)); 1873 FOR_INT32_INPUTS(i) { 1874 FOR_INT32_INPUTS(j) { 1875 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant; 1876 CHECK_EQ(expected, bt.call(*i, *j)); 1877 } 1878 } 1879 } 1880 { 1881 RawMachineAssemblerTester<int32_t> m; 1882 Int32BinopTester bt(&m); 1883 MLabel blocka, blockb; 1884 m.Branch( 1885 m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), 1886 &blocka, &blockb); 1887 m.Bind(&blocka); 1888 bt.AddReturn(m.Int32Constant(constant)); 1889 m.Bind(&blockb); 1890 bt.AddReturn(m.Int32Constant(0 - constant)); 1891 FOR_INT32_INPUTS(i) { 1892 FOR_INT32_INPUTS(j) { 1893 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant; 1894 CHECK_EQ(expected, bt.call(*i, *j)); 1895 } 1896 } 1897 } 1898 { 1899 FOR_INT32_INPUTS(i) { 1900 RawMachineAssemblerTester<int32_t> m(kMachInt32); 1901 MLabel blocka, blockb; 1902 m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 1903 m.Int32Constant(0)), 1904 &blocka, &blockb); 1905 m.Bind(&blocka); 1906 m.Return(m.Int32Constant(constant)); 1907 m.Bind(&blockb); 1908 m.Return(m.Int32Constant(0 - constant)); 1909 FOR_INT32_INPUTS(j) { 1910 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant; 1911 CHECK_EQ(expected, m.Call(*j)); 1912 } 1913 } 1914 } 1915 { 1916 FOR_INT32_INPUTS(i) { 1917 RawMachineAssemblerTester<int32_t> m(kMachInt32); 1918 MLabel blocka, blockb; 1919 m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 1920 m.Int32Constant(0)), 1921 &blocka, &blockb); 1922 m.Bind(&blocka); 1923 m.Return(m.Int32Constant(constant)); 1924 m.Bind(&blockb); 1925 m.Return(m.Int32Constant(0 - constant)); 1926 FOR_INT32_INPUTS(j) { 1927 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant; 1928 CHECK_EQ(expected, m.Call(*j)); 1929 } 1930 } 1931 } 1932 { 1933 RawMachineAssemblerTester<void> m; 1934 const Operator* shops[] = {m.machine()->Word32Sar(), 1935 m.machine()->Word32Shl(), 1936 m.machine()->Word32Shr()}; 1937 for (size_t n = 0; n < arraysize(shops); n++) { 1938 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 1939 kMachUint32); 1940 MLabel blocka, blockb; 1941 m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0), 1942 m.NewNode(shops[n], m.Parameter(1), 1943 m.Parameter(2))), 1944 m.Int32Constant(0)), 1945 &blocka, &blockb); 1946 m.Bind(&blocka); 1947 m.Return(m.Int32Constant(constant)); 1948 m.Bind(&blockb); 1949 m.Return(m.Int32Constant(0 - constant)); 1950 FOR_UINT32_INPUTS(i) { 1951 FOR_INT32_INPUTS(j) { 1952 FOR_UINT32_SHIFTS(shift) { 1953 int32_t right; 1954 switch (shops[n]->opcode()) { 1955 default: 1956 UNREACHABLE(); 1957 case IrOpcode::kWord32Sar: 1958 right = *j >> shift; 1959 break; 1960 case IrOpcode::kWord32Shl: 1961 right = *j << shift; 1962 break; 1963 case IrOpcode::kWord32Shr: 1964 right = static_cast<uint32_t>(*j) >> shift; 1965 break; 1966 } 1967 int32_t expected = ((*i | right) == 0) ? constant : 0 - constant; 1968 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1969 } 1970 } 1971 } 1972 } 1973 } 1974 } 1975 1976 1977 TEST(RunWord32OrInComparison) { 1978 { 1979 RawMachineAssemblerTester<int32_t> m; 1980 Uint32BinopTester bt(&m); 1981 bt.AddReturn( 1982 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0))); 1983 FOR_UINT32_INPUTS(i) { 1984 FOR_UINT32_INPUTS(j) { 1985 int32_t expected = (*i | *j) == 0; 1986 CHECK_EQ(expected, bt.call(*i, *j)); 1987 } 1988 } 1989 } 1990 { 1991 RawMachineAssemblerTester<int32_t> m; 1992 Uint32BinopTester bt(&m); 1993 bt.AddReturn( 1994 m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1))); 1995 FOR_UINT32_INPUTS(i) { 1996 FOR_UINT32_INPUTS(j) { 1997 int32_t expected = (*i | *j) == 0; 1998 CHECK_EQ(expected, bt.call(*i, *j)); 1999 } 2000 } 2001 } 2002 { 2003 FOR_UINT32_INPUTS(i) { 2004 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2005 m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 2006 m.Int32Constant(0))); 2007 FOR_UINT32_INPUTS(j) { 2008 uint32_t expected = (*i | *j) == 0; 2009 CHECK_UINT32_EQ(expected, m.Call(*j)); 2010 } 2011 } 2012 } 2013 { 2014 FOR_UINT32_INPUTS(i) { 2015 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2016 m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)), 2017 m.Int32Constant(0))); 2018 FOR_UINT32_INPUTS(j) { 2019 uint32_t expected = (*j | *i) == 0; 2020 CHECK_UINT32_EQ(expected, m.Call(*j)); 2021 } 2022 } 2023 } 2024 } 2025 2026 2027 TEST(RunWord32XorP) { 2028 { 2029 FOR_UINT32_INPUTS(i) { 2030 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2031 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0))); 2032 FOR_UINT32_INPUTS(j) { 2033 uint32_t expected = *i ^ *j; 2034 CHECK_UINT32_EQ(expected, m.Call(*j)); 2035 } 2036 } 2037 } 2038 { 2039 RawMachineAssemblerTester<int32_t> m; 2040 Uint32BinopTester bt(&m); 2041 bt.AddReturn(m.Word32Xor(bt.param0, bt.param1)); 2042 FOR_UINT32_INPUTS(i) { 2043 FOR_UINT32_INPUTS(j) { 2044 int32_t expected = *i ^ *j; 2045 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 2046 } 2047 } 2048 } 2049 { 2050 RawMachineAssemblerTester<int32_t> m; 2051 Int32BinopTester bt(&m); 2052 bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1))); 2053 FOR_INT32_INPUTS(i) { 2054 FOR_INT32_INPUTS(j) { 2055 int32_t expected = *i ^ ~(*j); 2056 CHECK_EQ(expected, bt.call(*i, *j)); 2057 } 2058 } 2059 } 2060 { 2061 RawMachineAssemblerTester<int32_t> m; 2062 Int32BinopTester bt(&m); 2063 bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1)); 2064 FOR_INT32_INPUTS(i) { 2065 FOR_INT32_INPUTS(j) { 2066 int32_t expected = ~(*i) ^ *j; 2067 CHECK_EQ(expected, bt.call(*i, *j)); 2068 } 2069 } 2070 } 2071 { 2072 FOR_UINT32_INPUTS(i) { 2073 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2074 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 2075 FOR_UINT32_INPUTS(j) { 2076 uint32_t expected = *i ^ ~(*j); 2077 CHECK_UINT32_EQ(expected, m.Call(*j)); 2078 } 2079 } 2080 } 2081 } 2082 2083 2084 TEST(RunWord32XorInBranch) { 2085 static const uint32_t constant = 987654321; 2086 { 2087 RawMachineAssemblerTester<int32_t> m; 2088 Uint32BinopTester bt(&m); 2089 MLabel blocka, blockb; 2090 m.Branch( 2091 m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), 2092 &blocka, &blockb); 2093 m.Bind(&blocka); 2094 bt.AddReturn(m.Int32Constant(constant)); 2095 m.Bind(&blockb); 2096 bt.AddReturn(m.Int32Constant(0 - constant)); 2097 FOR_UINT32_INPUTS(i) { 2098 FOR_UINT32_INPUTS(j) { 2099 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant; 2100 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 2101 } 2102 } 2103 } 2104 { 2105 RawMachineAssemblerTester<int32_t> m; 2106 Uint32BinopTester bt(&m); 2107 MLabel blocka, blockb; 2108 m.Branch( 2109 m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), 2110 &blocka, &blockb); 2111 m.Bind(&blocka); 2112 bt.AddReturn(m.Int32Constant(constant)); 2113 m.Bind(&blockb); 2114 bt.AddReturn(m.Int32Constant(0 - constant)); 2115 FOR_UINT32_INPUTS(i) { 2116 FOR_UINT32_INPUTS(j) { 2117 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant; 2118 CHECK_UINT32_EQ(expected, bt.call(*i, *j)); 2119 } 2120 } 2121 } 2122 { 2123 FOR_UINT32_INPUTS(i) { 2124 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2125 MLabel blocka, blockb; 2126 m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), 2127 m.Int32Constant(0)), 2128 &blocka, &blockb); 2129 m.Bind(&blocka); 2130 m.Return(m.Int32Constant(constant)); 2131 m.Bind(&blockb); 2132 m.Return(m.Int32Constant(0 - constant)); 2133 FOR_UINT32_INPUTS(j) { 2134 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant; 2135 CHECK_UINT32_EQ(expected, m.Call(*j)); 2136 } 2137 } 2138 } 2139 { 2140 FOR_UINT32_INPUTS(i) { 2141 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2142 MLabel blocka, blockb; 2143 m.Branch( 2144 m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), 2145 m.Int32Constant(0)), 2146 &blocka, &blockb); 2147 m.Bind(&blocka); 2148 m.Return(m.Int32Constant(constant)); 2149 m.Bind(&blockb); 2150 m.Return(m.Int32Constant(0 - constant)); 2151 FOR_UINT32_INPUTS(j) { 2152 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant; 2153 CHECK_UINT32_EQ(expected, m.Call(*j)); 2154 } 2155 } 2156 } 2157 { 2158 RawMachineAssemblerTester<void> m; 2159 const Operator* shops[] = {m.machine()->Word32Sar(), 2160 m.machine()->Word32Shl(), 2161 m.machine()->Word32Shr()}; 2162 for (size_t n = 0; n < arraysize(shops); n++) { 2163 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, 2164 kMachUint32); 2165 MLabel blocka, blockb; 2166 m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0), 2167 m.NewNode(shops[n], m.Parameter(1), 2168 m.Parameter(2))), 2169 m.Int32Constant(0)), 2170 &blocka, &blockb); 2171 m.Bind(&blocka); 2172 m.Return(m.Int32Constant(constant)); 2173 m.Bind(&blockb); 2174 m.Return(m.Int32Constant(0 - constant)); 2175 FOR_UINT32_INPUTS(i) { 2176 FOR_INT32_INPUTS(j) { 2177 FOR_UINT32_SHIFTS(shift) { 2178 int32_t right; 2179 switch (shops[n]->opcode()) { 2180 default: 2181 UNREACHABLE(); 2182 case IrOpcode::kWord32Sar: 2183 right = *j >> shift; 2184 break; 2185 case IrOpcode::kWord32Shl: 2186 right = *j << shift; 2187 break; 2188 case IrOpcode::kWord32Shr: 2189 right = static_cast<uint32_t>(*j) >> shift; 2190 break; 2191 } 2192 int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant; 2193 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2194 } 2195 } 2196 } 2197 } 2198 } 2199 } 2200 2201 2202 TEST(RunWord32ShlP) { 2203 { 2204 FOR_UINT32_SHIFTS(shift) { 2205 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2206 m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))); 2207 FOR_UINT32_INPUTS(j) { 2208 uint32_t expected = *j << shift; 2209 CHECK_UINT32_EQ(expected, m.Call(*j)); 2210 } 2211 } 2212 } 2213 { 2214 RawMachineAssemblerTester<int32_t> m; 2215 Uint32BinopTester bt(&m); 2216 bt.AddReturn(m.Word32Shl(bt.param0, bt.param1)); 2217 FOR_UINT32_INPUTS(i) { 2218 FOR_UINT32_SHIFTS(shift) { 2219 uint32_t expected = *i << shift; 2220 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2221 } 2222 } 2223 } 2224 } 2225 2226 2227 TEST(RunWord32ShlInComparison) { 2228 { 2229 RawMachineAssemblerTester<int32_t> m; 2230 Uint32BinopTester bt(&m); 2231 bt.AddReturn( 2232 m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0))); 2233 FOR_UINT32_INPUTS(i) { 2234 FOR_UINT32_SHIFTS(shift) { 2235 uint32_t expected = 0 == (*i << shift); 2236 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2237 } 2238 } 2239 } 2240 { 2241 RawMachineAssemblerTester<int32_t> m; 2242 Uint32BinopTester bt(&m); 2243 bt.AddReturn( 2244 m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1))); 2245 FOR_UINT32_INPUTS(i) { 2246 FOR_UINT32_SHIFTS(shift) { 2247 uint32_t expected = 0 == (*i << shift); 2248 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2249 } 2250 } 2251 } 2252 { 2253 FOR_UINT32_SHIFTS(shift) { 2254 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2255 m.Return( 2256 m.Word32Equal(m.Int32Constant(0), 2257 m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)))); 2258 FOR_UINT32_INPUTS(i) { 2259 uint32_t expected = 0 == (*i << shift); 2260 CHECK_UINT32_EQ(expected, m.Call(*i)); 2261 } 2262 } 2263 } 2264 { 2265 FOR_UINT32_SHIFTS(shift) { 2266 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2267 m.Return( 2268 m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)), 2269 m.Int32Constant(0))); 2270 FOR_UINT32_INPUTS(i) { 2271 uint32_t expected = 0 == (*i << shift); 2272 CHECK_UINT32_EQ(expected, m.Call(*i)); 2273 } 2274 } 2275 } 2276 } 2277 2278 2279 TEST(RunWord32ShrP) { 2280 { 2281 FOR_UINT32_SHIFTS(shift) { 2282 RawMachineAssemblerTester<uint32_t> m(kMachUint32); 2283 m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))); 2284 FOR_UINT32_INPUTS(j) { 2285 uint32_t expected = *j >> shift; 2286 CHECK_UINT32_EQ(expected, m.Call(*j)); 2287 } 2288 } 2289 } 2290 { 2291 RawMachineAssemblerTester<int32_t> m; 2292 Uint32BinopTester bt(&m); 2293 bt.AddReturn(m.Word32Shr(bt.param0, bt.param1)); 2294 FOR_UINT32_INPUTS(i) { 2295 FOR_UINT32_SHIFTS(shift) { 2296 uint32_t expected = *i >> shift; 2297 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2298 } 2299 } 2300 CHECK_EQ(0x00010000, bt.call(0x80000000, 15)); 2301 } 2302 } 2303 2304 2305 TEST(RunWord32ShrInComparison) { 2306 { 2307 RawMachineAssemblerTester<int32_t> m; 2308 Uint32BinopTester bt(&m); 2309 bt.AddReturn( 2310 m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0))); 2311 FOR_UINT32_INPUTS(i) { 2312 FOR_UINT32_SHIFTS(shift) { 2313 uint32_t expected = 0 == (*i >> shift); 2314 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2315 } 2316 } 2317 } 2318 { 2319 RawMachineAssemblerTester<int32_t> m; 2320 Uint32BinopTester bt(&m); 2321 bt.AddReturn( 2322 m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1))); 2323 FOR_UINT32_INPUTS(i) { 2324 FOR_UINT32_SHIFTS(shift) { 2325 uint32_t expected = 0 == (*i >> shift); 2326 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2327 } 2328 } 2329 } 2330 { 2331 FOR_UINT32_SHIFTS(shift) { 2332 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2333 m.Return( 2334 m.Word32Equal(m.Int32Constant(0), 2335 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); 2336 FOR_UINT32_INPUTS(i) { 2337 uint32_t expected = 0 == (*i >> shift); 2338 CHECK_UINT32_EQ(expected, m.Call(*i)); 2339 } 2340 } 2341 } 2342 { 2343 FOR_UINT32_SHIFTS(shift) { 2344 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2345 m.Return( 2346 m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), 2347 m.Int32Constant(0))); 2348 FOR_UINT32_INPUTS(i) { 2349 uint32_t expected = 0 == (*i >> shift); 2350 CHECK_UINT32_EQ(expected, m.Call(*i)); 2351 } 2352 } 2353 } 2354 } 2355 2356 2357 TEST(RunWord32SarP) { 2358 { 2359 FOR_INT32_SHIFTS(shift) { 2360 RawMachineAssemblerTester<int32_t> m(kMachInt32); 2361 m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))); 2362 FOR_INT32_INPUTS(j) { 2363 int32_t expected = *j >> shift; 2364 CHECK_EQ(expected, m.Call(*j)); 2365 } 2366 } 2367 } 2368 { 2369 RawMachineAssemblerTester<int32_t> m; 2370 Int32BinopTester bt(&m); 2371 bt.AddReturn(m.Word32Sar(bt.param0, bt.param1)); 2372 FOR_INT32_INPUTS(i) { 2373 FOR_INT32_SHIFTS(shift) { 2374 int32_t expected = *i >> shift; 2375 CHECK_EQ(expected, bt.call(*i, shift)); 2376 } 2377 } 2378 CHECK_EQ(0xFFFF0000, bt.call(0x80000000, 15)); 2379 } 2380 } 2381 2382 2383 TEST(RunWord32SarInComparison) { 2384 { 2385 RawMachineAssemblerTester<int32_t> m; 2386 Int32BinopTester bt(&m); 2387 bt.AddReturn( 2388 m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0))); 2389 FOR_INT32_INPUTS(i) { 2390 FOR_INT32_SHIFTS(shift) { 2391 int32_t expected = 0 == (*i >> shift); 2392 CHECK_EQ(expected, bt.call(*i, shift)); 2393 } 2394 } 2395 } 2396 { 2397 RawMachineAssemblerTester<int32_t> m; 2398 Int32BinopTester bt(&m); 2399 bt.AddReturn( 2400 m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1))); 2401 FOR_INT32_INPUTS(i) { 2402 FOR_INT32_SHIFTS(shift) { 2403 int32_t expected = 0 == (*i >> shift); 2404 CHECK_EQ(expected, bt.call(*i, shift)); 2405 } 2406 } 2407 } 2408 { 2409 FOR_INT32_SHIFTS(shift) { 2410 RawMachineAssemblerTester<int32_t> m(kMachInt32); 2411 m.Return( 2412 m.Word32Equal(m.Int32Constant(0), 2413 m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)))); 2414 FOR_INT32_INPUTS(i) { 2415 int32_t expected = 0 == (*i >> shift); 2416 CHECK_EQ(expected, m.Call(*i)); 2417 } 2418 } 2419 } 2420 { 2421 FOR_INT32_SHIFTS(shift) { 2422 RawMachineAssemblerTester<int32_t> m(kMachInt32); 2423 m.Return( 2424 m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)), 2425 m.Int32Constant(0))); 2426 FOR_INT32_INPUTS(i) { 2427 uint32_t expected = 0 == (*i >> shift); 2428 CHECK_EQ(expected, m.Call(*i)); 2429 } 2430 } 2431 } 2432 } 2433 2434 2435 TEST(RunWord32RorP) { 2436 { 2437 FOR_UINT32_SHIFTS(shift) { 2438 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2439 m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))); 2440 FOR_UINT32_INPUTS(j) { 2441 int32_t expected = bits::RotateRight32(*j, shift); 2442 CHECK_EQ(expected, m.Call(*j)); 2443 } 2444 } 2445 } 2446 { 2447 RawMachineAssemblerTester<int32_t> m; 2448 Uint32BinopTester bt(&m); 2449 bt.AddReturn(m.Word32Ror(bt.param0, bt.param1)); 2450 FOR_UINT32_INPUTS(i) { 2451 FOR_UINT32_SHIFTS(shift) { 2452 uint32_t expected = bits::RotateRight32(*i, shift); 2453 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2454 } 2455 } 2456 } 2457 } 2458 2459 2460 TEST(RunWord32RorInComparison) { 2461 { 2462 RawMachineAssemblerTester<int32_t> m; 2463 Uint32BinopTester bt(&m); 2464 bt.AddReturn( 2465 m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0))); 2466 FOR_UINT32_INPUTS(i) { 2467 FOR_UINT32_SHIFTS(shift) { 2468 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 2469 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2470 } 2471 } 2472 } 2473 { 2474 RawMachineAssemblerTester<int32_t> m; 2475 Uint32BinopTester bt(&m); 2476 bt.AddReturn( 2477 m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1))); 2478 FOR_UINT32_INPUTS(i) { 2479 FOR_UINT32_SHIFTS(shift) { 2480 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 2481 CHECK_UINT32_EQ(expected, bt.call(*i, shift)); 2482 } 2483 } 2484 } 2485 { 2486 FOR_UINT32_SHIFTS(shift) { 2487 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2488 m.Return( 2489 m.Word32Equal(m.Int32Constant(0), 2490 m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)))); 2491 FOR_UINT32_INPUTS(i) { 2492 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 2493 CHECK_UINT32_EQ(expected, m.Call(*i)); 2494 } 2495 } 2496 } 2497 { 2498 FOR_UINT32_SHIFTS(shift) { 2499 RawMachineAssemblerTester<int32_t> m(kMachUint32); 2500 m.Return( 2501 m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)), 2502 m.Int32Constant(0))); 2503 FOR_UINT32_INPUTS(i) { 2504 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 2505 CHECK_UINT32_EQ(expected, m.Call(*i)); 2506 } 2507 } 2508 } 2509 } 2510 2511 2512 TEST(RunWord32NotP) { 2513 RawMachineAssemblerTester<int32_t> m(kMachInt32); 2514 m.Return(m.Word32Not(m.Parameter(0))); 2515 FOR_INT32_INPUTS(i) { 2516 int expected = ~(*i); 2517 CHECK_EQ(expected, m.Call(*i)); 2518 } 2519 } 2520 2521 2522 TEST(RunInt32NegP) { 2523 RawMachineAssemblerTester<int32_t> m(kMachInt32); 2524 m.Return(m.Int32Neg(m.Parameter(0))); 2525 FOR_INT32_INPUTS(i) { 2526 int expected = -*i; 2527 CHECK_EQ(expected, m.Call(*i)); 2528 } 2529 } 2530 2531 2532 TEST(RunWord32EqualAndWord32SarP) { 2533 { 2534 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachUint32); 2535 m.Return(m.Word32Equal(m.Parameter(0), 2536 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 2537 FOR_INT32_INPUTS(i) { 2538 FOR_INT32_INPUTS(j) { 2539 FOR_UINT32_SHIFTS(shift) { 2540 int32_t expected = (*i == (*j >> shift)); 2541 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2542 } 2543 } 2544 } 2545 } 2546 { 2547 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachInt32); 2548 m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 2549 m.Parameter(2))); 2550 FOR_INT32_INPUTS(i) { 2551 FOR_UINT32_SHIFTS(shift) { 2552 FOR_INT32_INPUTS(k) { 2553 int32_t expected = ((*i >> shift) == *k); 2554 CHECK_EQ(expected, m.Call(*i, shift, *k)); 2555 } 2556 } 2557 } 2558 } 2559 } 2560 2561 2562 TEST(RunWord32EqualAndWord32ShlP) { 2563 { 2564 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 2565 m.Return(m.Word32Equal(m.Parameter(0), 2566 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 2567 FOR_UINT32_INPUTS(i) { 2568 FOR_UINT32_INPUTS(j) { 2569 FOR_UINT32_SHIFTS(shift) { 2570 int32_t expected = (*i == (*j << shift)); 2571 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2572 } 2573 } 2574 } 2575 } 2576 { 2577 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 2578 m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 2579 m.Parameter(2))); 2580 FOR_UINT32_INPUTS(i) { 2581 FOR_UINT32_SHIFTS(shift) { 2582 FOR_UINT32_INPUTS(k) { 2583 int32_t expected = ((*i << shift) == *k); 2584 CHECK_EQ(expected, m.Call(*i, shift, *k)); 2585 } 2586 } 2587 } 2588 } 2589 } 2590 2591 2592 TEST(RunWord32EqualAndWord32ShrP) { 2593 { 2594 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 2595 m.Return(m.Word32Equal(m.Parameter(0), 2596 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 2597 FOR_UINT32_INPUTS(i) { 2598 FOR_UINT32_INPUTS(j) { 2599 FOR_UINT32_SHIFTS(shift) { 2600 int32_t expected = (*i == (*j >> shift)); 2601 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2602 } 2603 } 2604 } 2605 } 2606 { 2607 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); 2608 m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 2609 m.Parameter(2))); 2610 FOR_UINT32_INPUTS(i) { 2611 FOR_UINT32_SHIFTS(shift) { 2612 FOR_UINT32_INPUTS(k) { 2613 int32_t expected = ((*i >> shift) == *k); 2614 CHECK_EQ(expected, m.Call(*i, shift, *k)); 2615 } 2616 } 2617 } 2618 } 2619 } 2620 2621 2622 TEST(RunDeadNodes) { 2623 for (int i = 0; true; i++) { 2624 RawMachineAssemblerTester<int32_t> m(i == 5 ? kMachInt32 : kMachNone); 2625 int constant = 0x55 + i; 2626 switch (i) { 2627 case 0: 2628 m.Int32Constant(44); 2629 break; 2630 case 1: 2631 m.StringConstant("unused"); 2632 break; 2633 case 2: 2634 m.NumberConstant(11.1); 2635 break; 2636 case 3: 2637 m.PointerConstant(&constant); 2638 break; 2639 case 4: 2640 m.LoadFromPointer(&constant, kMachInt32); 2641 break; 2642 case 5: 2643 m.Parameter(0); 2644 break; 2645 default: 2646 return; 2647 } 2648 m.Return(m.Int32Constant(constant)); 2649 if (i != 5) { 2650 CHECK_EQ(constant, m.Call()); 2651 } else { 2652 CHECK_EQ(constant, m.Call(0)); 2653 } 2654 } 2655 } 2656 2657 2658 TEST(RunDeadInt32Binops) { 2659 RawMachineAssemblerTester<int32_t> m; 2660 2661 const Operator* ops[] = { 2662 m.machine()->Word32And(), m.machine()->Word32Or(), 2663 m.machine()->Word32Xor(), m.machine()->Word32Shl(), 2664 m.machine()->Word32Shr(), m.machine()->Word32Sar(), 2665 m.machine()->Word32Ror(), m.machine()->Word32Equal(), 2666 m.machine()->Int32Add(), m.machine()->Int32Sub(), 2667 m.machine()->Int32Mul(), m.machine()->Int32Div(), 2668 m.machine()->Int32UDiv(), m.machine()->Int32Mod(), 2669 m.machine()->Int32UMod(), m.machine()->Int32LessThan(), 2670 m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(), 2671 m.machine()->Uint32LessThanOrEqual(), NULL}; 2672 2673 for (int i = 0; ops[i] != NULL; i++) { 2674 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); 2675 int constant = 0x55555 + i; 2676 m.NewNode(ops[i], m.Parameter(0), m.Parameter(1)); 2677 m.Return(m.Int32Constant(constant)); 2678 2679 CHECK_EQ(constant, m.Call(1, 1)); 2680 } 2681 } 2682 2683 2684 template <typename Type> 2685 static void RunLoadImmIndex(MachineType rep) { 2686 const int kNumElems = 3; 2687 Type buffer[kNumElems]; 2688 2689 // initialize the buffer with raw data. 2690 byte* raw = reinterpret_cast<byte*>(buffer); 2691 for (size_t i = 0; i < sizeof(buffer); i++) { 2692 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 2693 } 2694 2695 // Test with various large and small offsets. 2696 for (int offset = -1; offset <= 200000; offset *= -5) { 2697 for (int i = 0; i < kNumElems; i++) { 2698 RawMachineAssemblerTester<Type> m; 2699 Node* base = m.PointerConstant(buffer - offset); 2700 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0])); 2701 m.Return(m.Load(rep, base, index)); 2702 2703 Type expected = buffer[i]; 2704 Type actual = m.Call(); 2705 CHECK(expected == actual); 2706 } 2707 } 2708 } 2709 2710 2711 TEST(RunLoadImmIndex) { 2712 RunLoadImmIndex<int8_t>(kMachInt8); 2713 RunLoadImmIndex<uint8_t>(kMachUint8); 2714 RunLoadImmIndex<int16_t>(kMachInt16); 2715 RunLoadImmIndex<uint16_t>(kMachUint16); 2716 RunLoadImmIndex<int32_t>(kMachInt32); 2717 RunLoadImmIndex<uint32_t>(kMachUint32); 2718 RunLoadImmIndex<int32_t*>(kMachAnyTagged); 2719 2720 // TODO(titzer): test kRepBit loads 2721 // TODO(titzer): test kMachFloat64 loads 2722 // TODO(titzer): test various indexing modes. 2723 } 2724 2725 2726 template <typename CType> 2727 static void RunLoadStore(MachineType rep) { 2728 const int kNumElems = 4; 2729 CType buffer[kNumElems]; 2730 2731 for (int32_t x = 0; x < kNumElems; x++) { 2732 int32_t y = kNumElems - x - 1; 2733 // initialize the buffer with raw data. 2734 byte* raw = reinterpret_cast<byte*>(buffer); 2735 for (size_t i = 0; i < sizeof(buffer); i++) { 2736 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 2737 } 2738 2739 RawMachineAssemblerTester<int32_t> m; 2740 int32_t OK = 0x29000 + x; 2741 Node* base = m.PointerConstant(buffer); 2742 Node* index0 = m.Int32Constant(x * sizeof(buffer[0])); 2743 Node* load = m.Load(rep, base, index0); 2744 Node* index1 = m.Int32Constant(y * sizeof(buffer[0])); 2745 m.Store(rep, base, index1, load); 2746 m.Return(m.Int32Constant(OK)); 2747 2748 CHECK(buffer[x] != buffer[y]); 2749 CHECK_EQ(OK, m.Call()); 2750 CHECK(buffer[x] == buffer[y]); 2751 } 2752 } 2753 2754 2755 TEST(RunLoadStore) { 2756 RunLoadStore<int8_t>(kMachInt8); 2757 RunLoadStore<uint8_t>(kMachUint8); 2758 RunLoadStore<int16_t>(kMachInt16); 2759 RunLoadStore<uint16_t>(kMachUint16); 2760 RunLoadStore<int32_t>(kMachInt32); 2761 RunLoadStore<uint32_t>(kMachUint32); 2762 RunLoadStore<void*>(kMachAnyTagged); 2763 RunLoadStore<float>(kMachFloat32); 2764 RunLoadStore<double>(kMachFloat64); 2765 } 2766 2767 2768 TEST(RunFloat64Binop) { 2769 RawMachineAssemblerTester<int32_t> m; 2770 double result; 2771 2772 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(), 2773 m.machine()->Float64Mul(), m.machine()->Float64Div(), 2774 m.machine()->Float64Mod(), NULL}; 2775 2776 double inf = V8_INFINITY; 2777 const Operator* inputs[] = { 2778 m.common()->Float64Constant(0), m.common()->Float64Constant(1), 2779 m.common()->Float64Constant(1), m.common()->Float64Constant(0), 2780 m.common()->Float64Constant(0), m.common()->Float64Constant(-1), 2781 m.common()->Float64Constant(-1), m.common()->Float64Constant(0), 2782 m.common()->Float64Constant(0.22), m.common()->Float64Constant(-1.22), 2783 m.common()->Float64Constant(-1.22), m.common()->Float64Constant(0.22), 2784 m.common()->Float64Constant(inf), m.common()->Float64Constant(0.22), 2785 m.common()->Float64Constant(inf), m.common()->Float64Constant(-inf), 2786 NULL}; 2787 2788 for (int i = 0; ops[i] != NULL; i++) { 2789 for (int j = 0; inputs[j] != NULL; j += 2) { 2790 RawMachineAssemblerTester<int32_t> m; 2791 Node* a = m.NewNode(inputs[j]); 2792 Node* b = m.NewNode(inputs[j + 1]); 2793 Node* binop = m.NewNode(ops[i], a, b); 2794 Node* base = m.PointerConstant(&result); 2795 Node* zero = m.Int32Constant(0); 2796 m.Store(kMachFloat64, base, zero, binop); 2797 m.Return(m.Int32Constant(i + j)); 2798 CHECK_EQ(i + j, m.Call()); 2799 } 2800 } 2801 } 2802 2803 2804 TEST(RunDeadFloat64Binops) { 2805 RawMachineAssemblerTester<int32_t> m; 2806 2807 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(), 2808 m.machine()->Float64Mul(), m.machine()->Float64Div(), 2809 m.machine()->Float64Mod(), NULL}; 2810 2811 for (int i = 0; ops[i] != NULL; i++) { 2812 RawMachineAssemblerTester<int32_t> m; 2813 int constant = 0x53355 + i; 2814 m.NewNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11)); 2815 m.Return(m.Int32Constant(constant)); 2816 CHECK_EQ(constant, m.Call()); 2817 } 2818 } 2819 2820 2821 TEST(RunFloat64AddP) { 2822 RawMachineAssemblerTester<int32_t> m; 2823 Float64BinopTester bt(&m); 2824 2825 bt.AddReturn(m.Float64Add(bt.param0, bt.param1)); 2826 2827 FOR_FLOAT64_INPUTS(pl) { 2828 FOR_FLOAT64_INPUTS(pr) { 2829 double expected = *pl + *pr; 2830 CHECK_EQ(expected, bt.call(*pl, *pr)); 2831 } 2832 } 2833 } 2834 2835 2836 TEST(RunFloat64SubP) { 2837 RawMachineAssemblerTester<int32_t> m; 2838 Float64BinopTester bt(&m); 2839 2840 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1)); 2841 2842 FOR_FLOAT64_INPUTS(pl) { 2843 FOR_FLOAT64_INPUTS(pr) { 2844 double expected = *pl - *pr; 2845 CHECK_EQ(expected, bt.call(*pl, *pr)); 2846 } 2847 } 2848 } 2849 2850 2851 TEST(RunFloat64SubImm1) { 2852 double input = 0.0; 2853 double output = 0.0; 2854 2855 FOR_FLOAT64_INPUTS(i) { 2856 RawMachineAssemblerTester<int32_t> m; 2857 Node* t0 = m.LoadFromPointer(&input, kMachFloat64); 2858 Node* t1 = m.Float64Sub(m.Float64Constant(*i), t0); 2859 m.StoreToPointer(&output, kMachFloat64, t1); 2860 m.Return(m.Int32Constant(0)); 2861 FOR_FLOAT64_INPUTS(j) { 2862 input = *j; 2863 double expected = *i - input; 2864 CHECK_EQ(0, m.Call()); 2865 CHECK_EQ(expected, output); 2866 } 2867 } 2868 } 2869 2870 2871 TEST(RunFloat64SubImm2) { 2872 double input = 0.0; 2873 double output = 0.0; 2874 2875 FOR_FLOAT64_INPUTS(i) { 2876 RawMachineAssemblerTester<int32_t> m; 2877 Node* t0 = m.LoadFromPointer(&input, kMachFloat64); 2878 Node* t1 = m.Float64Sub(t0, m.Float64Constant(*i)); 2879 m.StoreToPointer(&output, kMachFloat64, t1); 2880 m.Return(m.Int32Constant(0)); 2881 FOR_FLOAT64_INPUTS(j) { 2882 input = *j; 2883 double expected = input - *i; 2884 CHECK_EQ(0, m.Call()); 2885 CHECK_EQ(expected, output); 2886 } 2887 } 2888 } 2889 2890 2891 TEST(RunFloat64MulP) { 2892 RawMachineAssemblerTester<int32_t> m; 2893 Float64BinopTester bt(&m); 2894 2895 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1)); 2896 2897 FOR_FLOAT64_INPUTS(pl) { 2898 FOR_FLOAT64_INPUTS(pr) { 2899 double expected = *pl * *pr; 2900 CHECK_EQ(expected, bt.call(*pl, *pr)); 2901 } 2902 } 2903 } 2904 2905 2906 TEST(RunFloat64MulAndFloat64AddP) { 2907 double input_a = 0.0; 2908 double input_b = 0.0; 2909 double input_c = 0.0; 2910 double output = 0.0; 2911 2912 { 2913 RawMachineAssemblerTester<int32_t> m; 2914 Node* a = m.LoadFromPointer(&input_a, kMachFloat64); 2915 Node* b = m.LoadFromPointer(&input_b, kMachFloat64); 2916 Node* c = m.LoadFromPointer(&input_c, kMachFloat64); 2917 m.StoreToPointer(&output, kMachFloat64, 2918 m.Float64Add(m.Float64Mul(a, b), c)); 2919 m.Return(m.Int32Constant(0)); 2920 FOR_FLOAT64_INPUTS(i) { 2921 FOR_FLOAT64_INPUTS(j) { 2922 FOR_FLOAT64_INPUTS(k) { 2923 input_a = *i; 2924 input_b = *j; 2925 input_c = *k; 2926 volatile double temp = input_a * input_b; 2927 volatile double expected = temp + input_c; 2928 CHECK_EQ(0, m.Call()); 2929 CHECK_EQ(expected, output); 2930 } 2931 } 2932 } 2933 } 2934 { 2935 RawMachineAssemblerTester<int32_t> m; 2936 Node* a = m.LoadFromPointer(&input_a, kMachFloat64); 2937 Node* b = m.LoadFromPointer(&input_b, kMachFloat64); 2938 Node* c = m.LoadFromPointer(&input_c, kMachFloat64); 2939 m.StoreToPointer(&output, kMachFloat64, 2940 m.Float64Add(a, m.Float64Mul(b, c))); 2941 m.Return(m.Int32Constant(0)); 2942 FOR_FLOAT64_INPUTS(i) { 2943 FOR_FLOAT64_INPUTS(j) { 2944 FOR_FLOAT64_INPUTS(k) { 2945 input_a = *i; 2946 input_b = *j; 2947 input_c = *k; 2948 volatile double temp = input_b * input_c; 2949 volatile double expected = input_a + temp; 2950 CHECK_EQ(0, m.Call()); 2951 CHECK_EQ(expected, output); 2952 } 2953 } 2954 } 2955 } 2956 } 2957 2958 2959 TEST(RunFloat64MulAndFloat64SubP) { 2960 double input_a = 0.0; 2961 double input_b = 0.0; 2962 double input_c = 0.0; 2963 double output = 0.0; 2964 2965 RawMachineAssemblerTester<int32_t> m; 2966 Node* a = m.LoadFromPointer(&input_a, kMachFloat64); 2967 Node* b = m.LoadFromPointer(&input_b, kMachFloat64); 2968 Node* c = m.LoadFromPointer(&input_c, kMachFloat64); 2969 m.StoreToPointer(&output, kMachFloat64, m.Float64Sub(a, m.Float64Mul(b, c))); 2970 m.Return(m.Int32Constant(0)); 2971 2972 FOR_FLOAT64_INPUTS(i) { 2973 FOR_FLOAT64_INPUTS(j) { 2974 FOR_FLOAT64_INPUTS(k) { 2975 input_a = *i; 2976 input_b = *j; 2977 input_c = *k; 2978 volatile double temp = input_b * input_c; 2979 volatile double expected = input_a - temp; 2980 CHECK_EQ(0, m.Call()); 2981 CHECK_EQ(expected, output); 2982 } 2983 } 2984 } 2985 } 2986 2987 2988 TEST(RunFloat64MulImm) { 2989 double input = 0.0; 2990 double output = 0.0; 2991 2992 { 2993 FOR_FLOAT64_INPUTS(i) { 2994 RawMachineAssemblerTester<int32_t> m; 2995 Node* t0 = m.LoadFromPointer(&input, kMachFloat64); 2996 Node* t1 = m.Float64Mul(m.Float64Constant(*i), t0); 2997 m.StoreToPointer(&output, kMachFloat64, t1); 2998 m.Return(m.Int32Constant(0)); 2999 FOR_FLOAT64_INPUTS(j) { 3000 input = *j; 3001 double expected = *i * input; 3002 CHECK_EQ(0, m.Call()); 3003 CHECK_EQ(expected, output); 3004 } 3005 } 3006 } 3007 { 3008 FOR_FLOAT64_INPUTS(i) { 3009 RawMachineAssemblerTester<int32_t> m; 3010 Node* t0 = m.LoadFromPointer(&input, kMachFloat64); 3011 Node* t1 = m.Float64Mul(t0, m.Float64Constant(*i)); 3012 m.StoreToPointer(&output, kMachFloat64, t1); 3013 m.Return(m.Int32Constant(0)); 3014 FOR_FLOAT64_INPUTS(j) { 3015 input = *j; 3016 double expected = input * *i; 3017 CHECK_EQ(0, m.Call()); 3018 CHECK_EQ(expected, output); 3019 } 3020 } 3021 } 3022 } 3023 3024 3025 TEST(RunFloat64DivP) { 3026 RawMachineAssemblerTester<int32_t> m; 3027 Float64BinopTester bt(&m); 3028 3029 bt.AddReturn(m.Float64Div(bt.param0, bt.param1)); 3030 3031 FOR_FLOAT64_INPUTS(pl) { 3032 FOR_FLOAT64_INPUTS(pr) { 3033 double expected = *pl / *pr; 3034 CHECK_EQ(expected, bt.call(*pl, *pr)); 3035 } 3036 } 3037 } 3038 3039 3040 TEST(RunFloat64ModP) { 3041 RawMachineAssemblerTester<int32_t> m; 3042 Float64BinopTester bt(&m); 3043 3044 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1)); 3045 3046 FOR_FLOAT64_INPUTS(i) { 3047 FOR_FLOAT64_INPUTS(j) { 3048 double expected = modulo(*i, *j); 3049 double found = bt.call(*i, *j); 3050 CHECK_EQ(expected, found); 3051 } 3052 } 3053 } 3054 3055 3056 TEST(RunChangeInt32ToFloat64_A) { 3057 RawMachineAssemblerTester<int32_t> m; 3058 int32_t magic = 0x986234; 3059 double result = 0; 3060 3061 Node* convert = m.ChangeInt32ToFloat64(m.Int32Constant(magic)); 3062 m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(0), 3063 convert); 3064 m.Return(m.Int32Constant(magic)); 3065 3066 CHECK_EQ(magic, m.Call()); 3067 CHECK_EQ(static_cast<double>(magic), result); 3068 } 3069 3070 3071 TEST(RunChangeInt32ToFloat64_B) { 3072 RawMachineAssemblerTester<int32_t> m(kMachInt32); 3073 double output = 0; 3074 3075 Node* convert = m.ChangeInt32ToFloat64(m.Parameter(0)); 3076 m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0), 3077 convert); 3078 m.Return(m.Parameter(0)); 3079 3080 FOR_INT32_INPUTS(i) { 3081 int32_t expect = *i; 3082 CHECK_EQ(expect, m.Call(expect)); 3083 CHECK_EQ(static_cast<double>(expect), output); 3084 } 3085 } 3086 3087 3088 TEST(RunChangeUint32ToFloat64_B) { 3089 RawMachineAssemblerTester<int32_t> m(kMachUint32); 3090 double output = 0; 3091 3092 Node* convert = m.ChangeUint32ToFloat64(m.Parameter(0)); 3093 m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0), 3094 convert); 3095 m.Return(m.Parameter(0)); 3096 3097 FOR_UINT32_INPUTS(i) { 3098 uint32_t expect = *i; 3099 CHECK_EQ(expect, m.Call(expect)); 3100 CHECK_EQ(static_cast<double>(expect), output); 3101 } 3102 } 3103 3104 3105 TEST(RunChangeFloat64ToInt32_A) { 3106 RawMachineAssemblerTester<int32_t> m; 3107 int32_t magic = 0x786234; 3108 double input = 11.1; 3109 int32_t result = 0; 3110 3111 m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(0), 3112 m.ChangeFloat64ToInt32(m.Float64Constant(input))); 3113 m.Return(m.Int32Constant(magic)); 3114 3115 CHECK_EQ(magic, m.Call()); 3116 CHECK_EQ(static_cast<int32_t>(input), result); 3117 } 3118 3119 3120 TEST(RunChangeFloat64ToInt32_B) { 3121 RawMachineAssemblerTester<int32_t> m; 3122 double input = 0; 3123 int32_t output = 0; 3124 3125 Node* load = 3126 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0)); 3127 Node* convert = m.ChangeFloat64ToInt32(load); 3128 m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert); 3129 m.Return(convert); 3130 3131 { 3132 FOR_INT32_INPUTS(i) { 3133 input = *i; 3134 int32_t expect = *i; 3135 CHECK_EQ(expect, m.Call()); 3136 CHECK_EQ(expect, output); 3137 } 3138 } 3139 3140 // Check various powers of 2. 3141 for (int32_t n = 1; n < 31; ++n) { 3142 { 3143 input = 1 << n; 3144 int32_t expect = static_cast<int32_t>(input); 3145 CHECK_EQ(expect, m.Call()); 3146 CHECK_EQ(expect, output); 3147 } 3148 3149 { 3150 input = 3 << n; 3151 int32_t expect = static_cast<int32_t>(input); 3152 CHECK_EQ(expect, m.Call()); 3153 CHECK_EQ(expect, output); 3154 } 3155 } 3156 // Note we don't check fractional inputs, because these Convert operators 3157 // really should be Change operators. 3158 } 3159 3160 3161 TEST(RunChangeFloat64ToUint32_B) { 3162 RawMachineAssemblerTester<int32_t> m; 3163 double input = 0; 3164 int32_t output = 0; 3165 3166 Node* load = 3167 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0)); 3168 Node* convert = m.ChangeFloat64ToUint32(load); 3169 m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert); 3170 m.Return(convert); 3171 3172 { 3173 FOR_UINT32_INPUTS(i) { 3174 input = *i; 3175 // TODO(titzer): add a CheckEqualsHelper overload for uint32_t. 3176 int32_t expect = static_cast<int32_t>(*i); 3177 CHECK_EQ(expect, m.Call()); 3178 CHECK_EQ(expect, output); 3179 } 3180 } 3181 3182 // Check various powers of 2. 3183 for (int32_t n = 1; n < 31; ++n) { 3184 { 3185 input = 1u << n; 3186 int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input)); 3187 CHECK_EQ(expect, m.Call()); 3188 CHECK_EQ(expect, output); 3189 } 3190 3191 { 3192 input = 3u << n; 3193 int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input)); 3194 CHECK_EQ(expect, m.Call()); 3195 CHECK_EQ(expect, output); 3196 } 3197 } 3198 // Note we don't check fractional inputs, because these Convert operators 3199 // really should be Change operators. 3200 } 3201 3202 3203 TEST(RunChangeFloat64ToInt32_spilled) { 3204 RawMachineAssemblerTester<int32_t> m; 3205 const int kNumInputs = 32; 3206 int32_t magic = 0x786234; 3207 double input[kNumInputs]; 3208 int32_t result[kNumInputs]; 3209 Node* input_node[kNumInputs]; 3210 3211 for (int i = 0; i < kNumInputs; i++) { 3212 input_node[i] = 3213 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8)); 3214 } 3215 3216 for (int i = 0; i < kNumInputs; i++) { 3217 m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(i * 4), 3218 m.ChangeFloat64ToInt32(input_node[i])); 3219 } 3220 3221 m.Return(m.Int32Constant(magic)); 3222 3223 for (int i = 0; i < kNumInputs; i++) { 3224 input[i] = 100.9 + i; 3225 } 3226 3227 CHECK_EQ(magic, m.Call()); 3228 3229 for (int i = 0; i < kNumInputs; i++) { 3230 CHECK_EQ(result[i], 100 + i); 3231 } 3232 } 3233 3234 3235 TEST(RunChangeFloat64ToUint32_spilled) { 3236 RawMachineAssemblerTester<uint32_t> m; 3237 const int kNumInputs = 32; 3238 int32_t magic = 0x786234; 3239 double input[kNumInputs]; 3240 uint32_t result[kNumInputs]; 3241 Node* input_node[kNumInputs]; 3242 3243 for (int i = 0; i < kNumInputs; i++) { 3244 input_node[i] = 3245 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8)); 3246 } 3247 3248 for (int i = 0; i < kNumInputs; i++) { 3249 m.Store(kMachUint32, m.PointerConstant(&result), m.Int32Constant(i * 4), 3250 m.ChangeFloat64ToUint32(input_node[i])); 3251 } 3252 3253 m.Return(m.Int32Constant(magic)); 3254 3255 for (int i = 0; i < kNumInputs; i++) { 3256 if (i % 2) { 3257 input[i] = 100 + i + 2147483648u; 3258 } else { 3259 input[i] = 100 + i; 3260 } 3261 } 3262 3263 CHECK_EQ(magic, m.Call()); 3264 3265 for (int i = 0; i < kNumInputs; i++) { 3266 if (i % 2) { 3267 CHECK_UINT32_EQ(result[i], static_cast<uint32_t>(100 + i + 2147483648u)); 3268 } else { 3269 CHECK_UINT32_EQ(result[i], static_cast<uint32_t>(100 + i)); 3270 } 3271 } 3272 } 3273 3274 3275 TEST(RunDeadChangeFloat64ToInt32) { 3276 RawMachineAssemblerTester<int32_t> m; 3277 const int magic = 0x88abcda4; 3278 m.ChangeFloat64ToInt32(m.Float64Constant(999.78)); 3279 m.Return(m.Int32Constant(magic)); 3280 CHECK_EQ(magic, m.Call()); 3281 } 3282 3283 3284 TEST(RunDeadChangeInt32ToFloat64) { 3285 RawMachineAssemblerTester<int32_t> m; 3286 const int magic = 0x8834abcd; 3287 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888)); 3288 m.Return(m.Int32Constant(magic)); 3289 CHECK_EQ(magic, m.Call()); 3290 } 3291 3292 3293 TEST(RunLoopPhiInduction2) { 3294 RawMachineAssemblerTester<int32_t> m; 3295 3296 int false_val = 0x10777; 3297 3298 // x = false_val; while(false) { x++; } return x; 3299 MLabel header, body, end; 3300 Node* false_node = m.Int32Constant(false_val); 3301 m.Goto(&header); 3302 m.Bind(&header); 3303 Node* phi = m.Phi(kMachInt32, false_node, false_node); 3304 m.Branch(m.Int32Constant(0), &body, &end); 3305 m.Bind(&body); 3306 Node* add = m.Int32Add(phi, m.Int32Constant(1)); 3307 phi->ReplaceInput(1, add); 3308 m.Goto(&header); 3309 m.Bind(&end); 3310 m.Return(phi); 3311 3312 CHECK_EQ(false_val, m.Call()); 3313 } 3314 3315 3316 TEST(RunDoubleDiamond) { 3317 RawMachineAssemblerTester<int32_t> m; 3318 3319 const int magic = 99645; 3320 double buffer = 0.1; 3321 double constant = 99.99; 3322 3323 MLabel blocka, blockb, end; 3324 Node* k1 = m.Float64Constant(constant); 3325 Node* k2 = m.Float64Constant(0 - constant); 3326 m.Branch(m.Int32Constant(0), &blocka, &blockb); 3327 m.Bind(&blocka); 3328 m.Goto(&end); 3329 m.Bind(&blockb); 3330 m.Goto(&end); 3331 m.Bind(&end); 3332 Node* phi = m.Phi(kMachFloat64, k2, k1); 3333 m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi); 3334 m.Return(m.Int32Constant(magic)); 3335 3336 CHECK_EQ(magic, m.Call()); 3337 CHECK_EQ(constant, buffer); 3338 } 3339 3340 3341 TEST(RunRefDiamond) { 3342 RawMachineAssemblerTester<int32_t> m; 3343 3344 const int magic = 99644; 3345 Handle<String> rexpected = 3346 CcTest::i_isolate()->factory()->InternalizeUtf8String("A"); 3347 String* buffer; 3348 3349 MLabel blocka, blockb, end; 3350 Node* k1 = m.StringConstant("A"); 3351 Node* k2 = m.StringConstant("B"); 3352 m.Branch(m.Int32Constant(0), &blocka, &blockb); 3353 m.Bind(&blocka); 3354 m.Goto(&end); 3355 m.Bind(&blockb); 3356 m.Goto(&end); 3357 m.Bind(&end); 3358 Node* phi = m.Phi(kMachAnyTagged, k2, k1); 3359 m.Store(kMachAnyTagged, m.PointerConstant(&buffer), m.Int32Constant(0), phi); 3360 m.Return(m.Int32Constant(magic)); 3361 3362 CHECK_EQ(magic, m.Call()); 3363 CHECK(rexpected->SameValue(buffer)); 3364 } 3365 3366 3367 TEST(RunDoubleRefDiamond) { 3368 RawMachineAssemblerTester<int32_t> m; 3369 3370 const int magic = 99648; 3371 double dbuffer = 0.1; 3372 double dconstant = 99.99; 3373 Handle<String> rexpected = 3374 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX"); 3375 String* rbuffer; 3376 3377 MLabel blocka, blockb, end; 3378 Node* d1 = m.Float64Constant(dconstant); 3379 Node* d2 = m.Float64Constant(0 - dconstant); 3380 Node* r1 = m.StringConstant("AX"); 3381 Node* r2 = m.StringConstant("BX"); 3382 m.Branch(m.Int32Constant(0), &blocka, &blockb); 3383 m.Bind(&blocka); 3384 m.Goto(&end); 3385 m.Bind(&blockb); 3386 m.Goto(&end); 3387 m.Bind(&end); 3388 Node* dphi = m.Phi(kMachFloat64, d2, d1); 3389 Node* rphi = m.Phi(kMachAnyTagged, r2, r1); 3390 m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi); 3391 m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0), 3392 rphi); 3393 m.Return(m.Int32Constant(magic)); 3394 3395 CHECK_EQ(magic, m.Call()); 3396 CHECK_EQ(dconstant, dbuffer); 3397 CHECK(rexpected->SameValue(rbuffer)); 3398 } 3399 3400 3401 TEST(RunDoubleRefDoubleDiamond) { 3402 RawMachineAssemblerTester<int32_t> m; 3403 3404 const int magic = 99649; 3405 double dbuffer = 0.1; 3406 double dconstant = 99.997; 3407 Handle<String> rexpected = 3408 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD"); 3409 String* rbuffer; 3410 3411 MLabel blocka, blockb, mid, blockd, blocke, end; 3412 Node* d1 = m.Float64Constant(dconstant); 3413 Node* d2 = m.Float64Constant(0 - dconstant); 3414 Node* r1 = m.StringConstant("AD"); 3415 Node* r2 = m.StringConstant("BD"); 3416 m.Branch(m.Int32Constant(0), &blocka, &blockb); 3417 m.Bind(&blocka); 3418 m.Goto(&mid); 3419 m.Bind(&blockb); 3420 m.Goto(&mid); 3421 m.Bind(&mid); 3422 Node* dphi1 = m.Phi(kMachFloat64, d2, d1); 3423 Node* rphi1 = m.Phi(kMachAnyTagged, r2, r1); 3424 m.Branch(m.Int32Constant(0), &blockd, &blocke); 3425 3426 m.Bind(&blockd); 3427 m.Goto(&end); 3428 m.Bind(&blocke); 3429 m.Goto(&end); 3430 m.Bind(&end); 3431 Node* dphi2 = m.Phi(kMachFloat64, d1, dphi1); 3432 Node* rphi2 = m.Phi(kMachAnyTagged, r1, rphi1); 3433 3434 m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi2); 3435 m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0), 3436 rphi2); 3437 m.Return(m.Int32Constant(magic)); 3438 3439 CHECK_EQ(magic, m.Call()); 3440 CHECK_EQ(dconstant, dbuffer); 3441 CHECK(rexpected->SameValue(rbuffer)); 3442 } 3443 3444 3445 TEST(RunDoubleLoopPhi) { 3446 RawMachineAssemblerTester<int32_t> m; 3447 MLabel header, body, end; 3448 3449 int magic = 99773; 3450 double buffer = 0.99; 3451 double dconstant = 777.1; 3452 3453 Node* zero = m.Int32Constant(0); 3454 Node* dk = m.Float64Constant(dconstant); 3455 3456 m.Goto(&header); 3457 m.Bind(&header); 3458 Node* phi = m.Phi(kMachFloat64, dk, dk); 3459 phi->ReplaceInput(1, phi); 3460 m.Branch(zero, &body, &end); 3461 m.Bind(&body); 3462 m.Goto(&header); 3463 m.Bind(&end); 3464 m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi); 3465 m.Return(m.Int32Constant(magic)); 3466 3467 CHECK_EQ(magic, m.Call()); 3468 } 3469 3470 3471 TEST(RunCountToTenAccRaw) { 3472 RawMachineAssemblerTester<int32_t> m; 3473 3474 Node* zero = m.Int32Constant(0); 3475 Node* ten = m.Int32Constant(10); 3476 Node* one = m.Int32Constant(1); 3477 3478 MLabel header, body, body_cont, end; 3479 3480 m.Goto(&header); 3481 3482 m.Bind(&header); 3483 Node* i = m.Phi(kMachInt32, zero, zero); 3484 Node* j = m.Phi(kMachInt32, zero, zero); 3485 m.Goto(&body); 3486 3487 m.Bind(&body); 3488 Node* next_i = m.Int32Add(i, one); 3489 Node* next_j = m.Int32Add(j, one); 3490 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont); 3491 3492 m.Bind(&body_cont); 3493 i->ReplaceInput(1, next_i); 3494 j->ReplaceInput(1, next_j); 3495 m.Goto(&header); 3496 3497 m.Bind(&end); 3498 m.Return(ten); 3499 3500 CHECK_EQ(10, m.Call()); 3501 } 3502 3503 3504 TEST(RunCountToTenAccRaw2) { 3505 RawMachineAssemblerTester<int32_t> m; 3506 3507 Node* zero = m.Int32Constant(0); 3508 Node* ten = m.Int32Constant(10); 3509 Node* one = m.Int32Constant(1); 3510 3511 MLabel header, body, body_cont, end; 3512 3513 m.Goto(&header); 3514 3515 m.Bind(&header); 3516 Node* i = m.Phi(kMachInt32, zero, zero); 3517 Node* j = m.Phi(kMachInt32, zero, zero); 3518 Node* k = m.Phi(kMachInt32, zero, zero); 3519 m.Goto(&body); 3520 3521 m.Bind(&body); 3522 Node* next_i = m.Int32Add(i, one); 3523 Node* next_j = m.Int32Add(j, one); 3524 Node* next_k = m.Int32Add(j, one); 3525 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont); 3526 3527 m.Bind(&body_cont); 3528 i->ReplaceInput(1, next_i); 3529 j->ReplaceInput(1, next_j); 3530 k->ReplaceInput(1, next_k); 3531 m.Goto(&header); 3532 3533 m.Bind(&end); 3534 m.Return(ten); 3535 3536 CHECK_EQ(10, m.Call()); 3537 } 3538 3539 3540 TEST(RunAddTree) { 3541 RawMachineAssemblerTester<int32_t> m; 3542 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18}; 3543 3544 Node* base = m.PointerConstant(inputs); 3545 Node* n0 = m.Load(kMachInt32, base, m.Int32Constant(0 * sizeof(int32_t))); 3546 Node* n1 = m.Load(kMachInt32, base, m.Int32Constant(1 * sizeof(int32_t))); 3547 Node* n2 = m.Load(kMachInt32, base, m.Int32Constant(2 * sizeof(int32_t))); 3548 Node* n3 = m.Load(kMachInt32, base, m.Int32Constant(3 * sizeof(int32_t))); 3549 Node* n4 = m.Load(kMachInt32, base, m.Int32Constant(4 * sizeof(int32_t))); 3550 Node* n5 = m.Load(kMachInt32, base, m.Int32Constant(5 * sizeof(int32_t))); 3551 Node* n6 = m.Load(kMachInt32, base, m.Int32Constant(6 * sizeof(int32_t))); 3552 Node* n7 = m.Load(kMachInt32, base, m.Int32Constant(7 * sizeof(int32_t))); 3553 3554 Node* i1 = m.Int32Add(n0, n1); 3555 Node* i2 = m.Int32Add(n2, n3); 3556 Node* i3 = m.Int32Add(n4, n5); 3557 Node* i4 = m.Int32Add(n6, n7); 3558 3559 Node* i5 = m.Int32Add(i1, i2); 3560 Node* i6 = m.Int32Add(i3, i4); 3561 3562 Node* i7 = m.Int32Add(i5, i6); 3563 3564 m.Return(i7); 3565 3566 CHECK_EQ(116, m.Call()); 3567 } 3568 3569 3570 static const int kFloat64CompareHelperTestCases = 15; 3571 static const int kFloat64CompareHelperNodeType = 4; 3572 3573 static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m, 3574 int test_case, int node_type, double x, 3575 double y) { 3576 static double buffer[2]; 3577 buffer[0] = x; 3578 buffer[1] = y; 3579 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases); 3580 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType); 3581 CHECK(x < y); 3582 bool load_a = node_type / 2 == 1; 3583 bool load_b = node_type % 2 == 1; 3584 Node* a = load_a ? m->Load(kMachFloat64, m->PointerConstant(&buffer[0])) 3585 : m->Float64Constant(x); 3586 Node* b = load_b ? m->Load(kMachFloat64, m->PointerConstant(&buffer[1])) 3587 : m->Float64Constant(y); 3588 Node* cmp = NULL; 3589 bool expected = false; 3590 switch (test_case) { 3591 // Equal tests. 3592 case 0: 3593 cmp = m->Float64Equal(a, b); 3594 expected = false; 3595 break; 3596 case 1: 3597 cmp = m->Float64Equal(a, a); 3598 expected = true; 3599 break; 3600 // LessThan tests. 3601 case 2: 3602 cmp = m->Float64LessThan(a, b); 3603 expected = true; 3604 break; 3605 case 3: 3606 cmp = m->Float64LessThan(b, a); 3607 expected = false; 3608 break; 3609 case 4: 3610 cmp = m->Float64LessThan(a, a); 3611 expected = false; 3612 break; 3613 // LessThanOrEqual tests. 3614 case 5: 3615 cmp = m->Float64LessThanOrEqual(a, b); 3616 expected = true; 3617 break; 3618 case 6: 3619 cmp = m->Float64LessThanOrEqual(b, a); 3620 expected = false; 3621 break; 3622 case 7: 3623 cmp = m->Float64LessThanOrEqual(a, a); 3624 expected = true; 3625 break; 3626 // NotEqual tests. 3627 case 8: 3628 cmp = m->Float64NotEqual(a, b); 3629 expected = true; 3630 break; 3631 case 9: 3632 cmp = m->Float64NotEqual(b, a); 3633 expected = true; 3634 break; 3635 case 10: 3636 cmp = m->Float64NotEqual(a, a); 3637 expected = false; 3638 break; 3639 // GreaterThan tests. 3640 case 11: 3641 cmp = m->Float64GreaterThan(a, a); 3642 expected = false; 3643 break; 3644 case 12: 3645 cmp = m->Float64GreaterThan(a, b); 3646 expected = false; 3647 break; 3648 // GreaterThanOrEqual tests. 3649 case 13: 3650 cmp = m->Float64GreaterThanOrEqual(a, a); 3651 expected = true; 3652 break; 3653 case 14: 3654 cmp = m->Float64GreaterThanOrEqual(b, a); 3655 expected = true; 3656 break; 3657 default: 3658 UNREACHABLE(); 3659 } 3660 m->Return(cmp); 3661 return expected; 3662 } 3663 3664 3665 TEST(RunFloat64Compare) { 3666 double inf = V8_INFINITY; 3667 // All pairs (a1, a2) are of the form a1 < a2. 3668 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22, 3669 -inf, 0.22, 0.22, inf, -inf, inf}; 3670 3671 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) { 3672 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType; 3673 node_type++) { 3674 for (size_t input = 0; input < arraysize(inputs); input += 2) { 3675 RawMachineAssemblerTester<int32_t> m; 3676 int expected = Float64CompareHelper(&m, test, node_type, inputs[input], 3677 inputs[input + 1]); 3678 CHECK_EQ(expected, m.Call()); 3679 } 3680 } 3681 } 3682 } 3683 3684 3685 TEST(RunFloat64UnorderedCompare) { 3686 RawMachineAssemblerTester<int32_t> m; 3687 3688 const Operator* operators[] = {m.machine()->Float64Equal(), 3689 m.machine()->Float64LessThan(), 3690 m.machine()->Float64LessThanOrEqual()}; 3691 3692 double nan = v8::base::OS::nan_value(); 3693 3694 FOR_FLOAT64_INPUTS(i) { 3695 for (size_t o = 0; o < arraysize(operators); ++o) { 3696 for (int j = 0; j < 2; j++) { 3697 RawMachineAssemblerTester<int32_t> m; 3698 Node* a = m.Float64Constant(*i); 3699 Node* b = m.Float64Constant(nan); 3700 if (j == 1) std::swap(a, b); 3701 m.Return(m.NewNode(operators[o], a, b)); 3702 CHECK_EQ(0, m.Call()); 3703 } 3704 } 3705 } 3706 } 3707 3708 3709 TEST(RunFloat64Equal) { 3710 double input_a = 0.0; 3711 double input_b = 0.0; 3712 3713 RawMachineAssemblerTester<int32_t> m; 3714 Node* a = m.LoadFromPointer(&input_a, kMachFloat64); 3715 Node* b = m.LoadFromPointer(&input_b, kMachFloat64); 3716 m.Return(m.Float64Equal(a, b)); 3717 3718 CompareWrapper cmp(IrOpcode::kFloat64Equal); 3719 FOR_FLOAT64_INPUTS(pl) { 3720 FOR_FLOAT64_INPUTS(pr) { 3721 input_a = *pl; 3722 input_b = *pr; 3723 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0; 3724 CHECK_EQ(expected, m.Call()); 3725 } 3726 } 3727 } 3728 3729 3730 TEST(RunFloat64LessThan) { 3731 double input_a = 0.0; 3732 double input_b = 0.0; 3733 3734 RawMachineAssemblerTester<int32_t> m; 3735 Node* a = m.LoadFromPointer(&input_a, kMachFloat64); 3736 Node* b = m.LoadFromPointer(&input_b, kMachFloat64); 3737 m.Return(m.Float64LessThan(a, b)); 3738 3739 CompareWrapper cmp(IrOpcode::kFloat64LessThan); 3740 FOR_FLOAT64_INPUTS(pl) { 3741 FOR_FLOAT64_INPUTS(pr) { 3742 input_a = *pl; 3743 input_b = *pr; 3744 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0; 3745 CHECK_EQ(expected, m.Call()); 3746 } 3747 } 3748 } 3749 3750 3751 template <typename IntType, MachineType kRepresentation> 3752 static void LoadStoreTruncation() { 3753 IntType input; 3754 3755 RawMachineAssemblerTester<int32_t> m; 3756 Node* a = m.LoadFromPointer(&input, kRepresentation); 3757 Node* ap1 = m.Int32Add(a, m.Int32Constant(1)); 3758 m.StoreToPointer(&input, kRepresentation, ap1); 3759 m.Return(ap1); 3760 3761 const IntType max = std::numeric_limits<IntType>::max(); 3762 const IntType min = std::numeric_limits<IntType>::min(); 3763 3764 // Test upper bound. 3765 input = max; 3766 CHECK_EQ(max + 1, m.Call()); 3767 CHECK_EQ(min, input); 3768 3769 // Test lower bound. 3770 input = min; 3771 CHECK_EQ(static_cast<IntType>(max + 2), m.Call()); 3772 CHECK_EQ(min + 1, input); 3773 3774 // Test all one byte values that are not one byte bounds. 3775 for (int i = -127; i < 127; i++) { 3776 input = i; 3777 int expected = i >= 0 ? i + 1 : max + (i - min) + 2; 3778 CHECK_EQ(static_cast<IntType>(expected), m.Call()); 3779 CHECK_EQ(static_cast<IntType>(i + 1), input); 3780 } 3781 } 3782 3783 3784 TEST(RunLoadStoreTruncation) { 3785 LoadStoreTruncation<int8_t, kMachInt8>(); 3786 LoadStoreTruncation<int16_t, kMachInt16>(); 3787 } 3788 3789 3790 static void IntPtrCompare(intptr_t left, intptr_t right) { 3791 for (int test = 0; test < 7; test++) { 3792 RawMachineAssemblerTester<bool> m(kMachPtr, kMachPtr); 3793 Node* p0 = m.Parameter(0); 3794 Node* p1 = m.Parameter(1); 3795 Node* res = NULL; 3796 bool expected = false; 3797 switch (test) { 3798 case 0: 3799 res = m.IntPtrLessThan(p0, p1); 3800 expected = true; 3801 break; 3802 case 1: 3803 res = m.IntPtrLessThanOrEqual(p0, p1); 3804 expected = true; 3805 break; 3806 case 2: 3807 res = m.IntPtrEqual(p0, p1); 3808 expected = false; 3809 break; 3810 case 3: 3811 res = m.IntPtrGreaterThanOrEqual(p0, p1); 3812 expected = false; 3813 break; 3814 case 4: 3815 res = m.IntPtrGreaterThan(p0, p1); 3816 expected = false; 3817 break; 3818 case 5: 3819 res = m.IntPtrEqual(p0, p0); 3820 expected = true; 3821 break; 3822 case 6: 3823 res = m.IntPtrNotEqual(p0, p1); 3824 expected = true; 3825 break; 3826 default: 3827 UNREACHABLE(); 3828 break; 3829 } 3830 m.Return(res); 3831 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left), 3832 reinterpret_cast<int32_t*>(right))); 3833 } 3834 } 3835 3836 3837 TEST(RunIntPtrCompare) { 3838 intptr_t min = std::numeric_limits<intptr_t>::min(); 3839 intptr_t max = std::numeric_limits<intptr_t>::max(); 3840 // An ascending chain of intptr_t 3841 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max}; 3842 for (size_t i = 0; i < arraysize(inputs) - 1; i++) { 3843 IntPtrCompare(inputs[i], inputs[i + 1]); 3844 } 3845 } 3846 3847 3848 TEST(RunTestIntPtrArithmetic) { 3849 static const int kInputSize = 10; 3850 int32_t inputs[kInputSize]; 3851 int32_t outputs[kInputSize]; 3852 for (int i = 0; i < kInputSize; i++) { 3853 inputs[i] = i; 3854 outputs[i] = -1; 3855 } 3856 RawMachineAssemblerTester<int32_t*> m; 3857 Node* input = m.PointerConstant(&inputs[0]); 3858 Node* output = m.PointerConstant(&outputs[kInputSize - 1]); 3859 Node* elem_size = m.ConvertInt32ToIntPtr(m.Int32Constant(sizeof(inputs[0]))); 3860 for (int i = 0; i < kInputSize; i++) { 3861 m.Store(kMachInt32, output, m.Load(kMachInt32, input)); 3862 input = m.IntPtrAdd(input, elem_size); 3863 output = m.IntPtrSub(output, elem_size); 3864 } 3865 m.Return(input); 3866 CHECK_EQ(&inputs[kInputSize], m.Call()); 3867 for (int i = 0; i < kInputSize; i++) { 3868 CHECK_EQ(i, inputs[i]); 3869 CHECK_EQ(kInputSize - i - 1, outputs[i]); 3870 } 3871 } 3872 3873 3874 TEST(RunSpillLotsOfThings) { 3875 static const int kInputSize = 1000; 3876 RawMachineAssemblerTester<void> m; 3877 Node* accs[kInputSize]; 3878 int32_t outputs[kInputSize]; 3879 Node* one = m.Int32Constant(1); 3880 Node* acc = one; 3881 for (int i = 0; i < kInputSize; i++) { 3882 acc = m.Int32Add(acc, one); 3883 accs[i] = acc; 3884 } 3885 for (int i = 0; i < kInputSize; i++) { 3886 m.StoreToPointer(&outputs[i], kMachInt32, accs[i]); 3887 } 3888 m.Return(one); 3889 m.Call(); 3890 for (int i = 0; i < kInputSize; i++) { 3891 CHECK_EQ(outputs[i], i + 2); 3892 } 3893 } 3894 3895 3896 TEST(RunSpillConstantsAndParameters) { 3897 static const int kInputSize = 1000; 3898 static const int32_t kBase = 987; 3899 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); 3900 int32_t outputs[kInputSize]; 3901 Node* csts[kInputSize]; 3902 Node* accs[kInputSize]; 3903 Node* acc = m.Int32Constant(0); 3904 for (int i = 0; i < kInputSize; i++) { 3905 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i)); 3906 } 3907 for (int i = 0; i < kInputSize; i++) { 3908 acc = m.Int32Add(acc, csts[i]); 3909 accs[i] = acc; 3910 } 3911 for (int i = 0; i < kInputSize; i++) { 3912 m.StoreToPointer(&outputs[i], kMachInt32, accs[i]); 3913 } 3914 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1)))); 3915 FOR_INT32_INPUTS(i) { 3916 FOR_INT32_INPUTS(j) { 3917 int32_t expected = *i + *j; 3918 for (int k = 0; k < kInputSize; k++) { 3919 expected += kBase + k; 3920 } 3921 CHECK_EQ(expected, m.Call(*i, *j)); 3922 expected = 0; 3923 for (int k = 0; k < kInputSize; k++) { 3924 expected += kBase + k; 3925 CHECK_EQ(expected, outputs[k]); 3926 } 3927 } 3928 } 3929 } 3930 3931 3932 TEST(RunNewSpaceConstantsInPhi) { 3933 RawMachineAssemblerTester<Object*> m(kMachInt32); 3934 3935 Isolate* isolate = CcTest::i_isolate(); 3936 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2); 3937 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3); 3938 Node* true_node = m.HeapConstant(true_val); 3939 Node* false_node = m.HeapConstant(false_val); 3940 3941 MLabel blocka, blockb, end; 3942 m.Branch(m.Parameter(0), &blocka, &blockb); 3943 m.Bind(&blocka); 3944 m.Goto(&end); 3945 m.Bind(&blockb); 3946 m.Goto(&end); 3947 3948 m.Bind(&end); 3949 Node* phi = m.Phi(kMachAnyTagged, true_node, false_node); 3950 m.Return(phi); 3951 3952 CHECK_EQ(*false_val, m.Call(0)); 3953 CHECK_EQ(*true_val, m.Call(1)); 3954 } 3955 3956 3957 TEST(RunInt32AddWithOverflowP) { 3958 int32_t actual_val = -1; 3959 RawMachineAssemblerTester<int32_t> m; 3960 Int32BinopTester bt(&m); 3961 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); 3962 Node* val = m.Projection(0, add); 3963 Node* ovf = m.Projection(1, add); 3964 m.StoreToPointer(&actual_val, kMachInt32, val); 3965 bt.AddReturn(ovf); 3966 FOR_INT32_INPUTS(i) { 3967 FOR_INT32_INPUTS(j) { 3968 int32_t expected_val; 3969 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 3970 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 3971 CHECK_EQ(expected_val, actual_val); 3972 } 3973 } 3974 } 3975 3976 3977 TEST(RunInt32AddWithOverflowImm) { 3978 int32_t actual_val = -1, expected_val = 0; 3979 FOR_INT32_INPUTS(i) { 3980 { 3981 RawMachineAssemblerTester<int32_t> m(kMachInt32); 3982 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0)); 3983 Node* val = m.Projection(0, add); 3984 Node* ovf = m.Projection(1, add); 3985 m.StoreToPointer(&actual_val, kMachInt32, val); 3986 m.Return(ovf); 3987 FOR_INT32_INPUTS(j) { 3988 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 3989 CHECK_EQ(expected_ovf, m.Call(*j)); 3990 CHECK_EQ(expected_val, actual_val); 3991 } 3992 } 3993 { 3994 RawMachineAssemblerTester<int32_t> m(kMachInt32); 3995 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i)); 3996 Node* val = m.Projection(0, add); 3997 Node* ovf = m.Projection(1, add); 3998 m.StoreToPointer(&actual_val, kMachInt32, val); 3999 m.Return(ovf); 4000 FOR_INT32_INPUTS(j) { 4001 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4002 CHECK_EQ(expected_ovf, m.Call(*j)); 4003 CHECK_EQ(expected_val, actual_val); 4004 } 4005 } 4006 FOR_INT32_INPUTS(j) { 4007 RawMachineAssemblerTester<int32_t> m; 4008 Node* add = 4009 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); 4010 Node* val = m.Projection(0, add); 4011 Node* ovf = m.Projection(1, add); 4012 m.StoreToPointer(&actual_val, kMachInt32, val); 4013 m.Return(ovf); 4014 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4015 CHECK_EQ(expected_ovf, m.Call()); 4016 CHECK_EQ(expected_val, actual_val); 4017 } 4018 } 4019 } 4020 4021 4022 TEST(RunInt32AddWithOverflowInBranchP) { 4023 int constant = 911777; 4024 MLabel blocka, blockb; 4025 RawMachineAssemblerTester<int32_t> m; 4026 Int32BinopTester bt(&m); 4027 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); 4028 Node* ovf = m.Projection(1, add); 4029 m.Branch(ovf, &blocka, &blockb); 4030 m.Bind(&blocka); 4031 bt.AddReturn(m.Int32Constant(constant)); 4032 m.Bind(&blockb); 4033 Node* val = m.Projection(0, add); 4034 bt.AddReturn(val); 4035 FOR_INT32_INPUTS(i) { 4036 FOR_INT32_INPUTS(j) { 4037 int32_t expected; 4038 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant; 4039 CHECK_EQ(expected, bt.call(*i, *j)); 4040 } 4041 } 4042 } 4043 4044 4045 TEST(RunInt32SubWithOverflowP) { 4046 int32_t actual_val = -1; 4047 RawMachineAssemblerTester<int32_t> m; 4048 Int32BinopTester bt(&m); 4049 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1); 4050 Node* val = m.Projection(0, add); 4051 Node* ovf = m.Projection(1, add); 4052 m.StoreToPointer(&actual_val, kMachInt32, val); 4053 bt.AddReturn(ovf); 4054 FOR_INT32_INPUTS(i) { 4055 FOR_INT32_INPUTS(j) { 4056 int32_t expected_val; 4057 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 4058 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 4059 CHECK_EQ(expected_val, actual_val); 4060 } 4061 } 4062 } 4063 4064 4065 TEST(RunInt32SubWithOverflowImm) { 4066 int32_t actual_val = -1, expected_val = 0; 4067 FOR_INT32_INPUTS(i) { 4068 { 4069 RawMachineAssemblerTester<int32_t> m(kMachInt32); 4070 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0)); 4071 Node* val = m.Projection(0, add); 4072 Node* ovf = m.Projection(1, add); 4073 m.StoreToPointer(&actual_val, kMachInt32, val); 4074 m.Return(ovf); 4075 FOR_INT32_INPUTS(j) { 4076 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 4077 CHECK_EQ(expected_ovf, m.Call(*j)); 4078 CHECK_EQ(expected_val, actual_val); 4079 } 4080 } 4081 { 4082 RawMachineAssemblerTester<int32_t> m(kMachInt32); 4083 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i)); 4084 Node* val = m.Projection(0, add); 4085 Node* ovf = m.Projection(1, add); 4086 m.StoreToPointer(&actual_val, kMachInt32, val); 4087 m.Return(ovf); 4088 FOR_INT32_INPUTS(j) { 4089 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val); 4090 CHECK_EQ(expected_ovf, m.Call(*j)); 4091 CHECK_EQ(expected_val, actual_val); 4092 } 4093 } 4094 FOR_INT32_INPUTS(j) { 4095 RawMachineAssemblerTester<int32_t> m; 4096 Node* add = 4097 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); 4098 Node* val = m.Projection(0, add); 4099 Node* ovf = m.Projection(1, add); 4100 m.StoreToPointer(&actual_val, kMachInt32, val); 4101 m.Return(ovf); 4102 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 4103 CHECK_EQ(expected_ovf, m.Call()); 4104 CHECK_EQ(expected_val, actual_val); 4105 } 4106 } 4107 } 4108 4109 4110 TEST(RunInt32SubWithOverflowInBranchP) { 4111 int constant = 911999; 4112 MLabel blocka, blockb; 4113 RawMachineAssemblerTester<int32_t> m; 4114 Int32BinopTester bt(&m); 4115 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1); 4116 Node* ovf = m.Projection(1, sub); 4117 m.Branch(ovf, &blocka, &blockb); 4118 m.Bind(&blocka); 4119 bt.AddReturn(m.Int32Constant(constant)); 4120 m.Bind(&blockb); 4121 Node* val = m.Projection(0, sub); 4122 bt.AddReturn(val); 4123 FOR_INT32_INPUTS(i) { 4124 FOR_INT32_INPUTS(j) { 4125 int32_t expected; 4126 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant; 4127 CHECK_EQ(expected, bt.call(*i, *j)); 4128 } 4129 } 4130 } 4131 4132 4133 TEST(RunChangeInt32ToInt64P) { 4134 if (kPointerSize < 8) return; 4135 int64_t actual = -1; 4136 RawMachineAssemblerTester<int32_t> m(kMachInt32); 4137 m.StoreToPointer(&actual, kMachInt64, m.ChangeInt32ToInt64(m.Parameter(0))); 4138 m.Return(m.Int32Constant(0)); 4139 FOR_INT32_INPUTS(i) { 4140 int64_t expected = *i; 4141 CHECK_EQ(0, m.Call(*i)); 4142 CHECK_EQ(expected, actual); 4143 } 4144 } 4145 4146 4147 TEST(RunChangeUint32ToUint64P) { 4148 if (kPointerSize < 8) return; 4149 int64_t actual = -1; 4150 RawMachineAssemblerTester<int32_t> m(kMachUint32); 4151 m.StoreToPointer(&actual, kMachUint64, 4152 m.ChangeUint32ToUint64(m.Parameter(0))); 4153 m.Return(m.Int32Constant(0)); 4154 FOR_UINT32_INPUTS(i) { 4155 int64_t expected = static_cast<uint64_t>(*i); 4156 CHECK_EQ(0, m.Call(*i)); 4157 CHECK_EQ(expected, actual); 4158 } 4159 } 4160 4161 4162 TEST(RunTruncateInt64ToInt32P) { 4163 if (kPointerSize < 8) return; 4164 int64_t expected = -1; 4165 RawMachineAssemblerTester<int32_t> m; 4166 m.Return(m.TruncateInt64ToInt32(m.LoadFromPointer(&expected, kMachInt64))); 4167 FOR_UINT32_INPUTS(i) { 4168 FOR_UINT32_INPUTS(j) { 4169 expected = (static_cast<uint64_t>(*j) << 32) | *i; 4170 CHECK_UINT32_EQ(expected, m.Call()); 4171 } 4172 } 4173 } 4174 4175 4176 TEST(RunTruncateFloat64ToInt32P) { 4177 struct { 4178 double from; 4179 double raw; 4180 } kValues[] = {{0, 0}, 4181 {0.5, 0}, 4182 {-0.5, 0}, 4183 {1.5, 1}, 4184 {-1.5, -1}, 4185 {5.5, 5}, 4186 {-5.0, -5}, 4187 {v8::base::OS::nan_value(), 0}, 4188 {std::numeric_limits<double>::infinity(), 0}, 4189 {-v8::base::OS::nan_value(), 0}, 4190 {-std::numeric_limits<double>::infinity(), 0}, 4191 {4.94065645841e-324, 0}, 4192 {-4.94065645841e-324, 0}, 4193 {0.9999999999999999, 0}, 4194 {-0.9999999999999999, 0}, 4195 {4294967296.0, 0}, 4196 {-4294967296.0, 0}, 4197 {9223372036854775000.0, 4294966272.0}, 4198 {-9223372036854775000.0, -4294966272.0}, 4199 {4.5036e+15, 372629504}, 4200 {-4.5036e+15, -372629504}, 4201 {287524199.5377777, 0x11234567}, 4202 {-287524199.5377777, -0x11234567}, 4203 {2300193596.302222, 2300193596.0}, 4204 {-2300193596.302222, -2300193596.0}, 4205 {4600387192.604444, 305419896}, 4206 {-4600387192.604444, -305419896}, 4207 {4823855600872397.0, 1737075661}, 4208 {-4823855600872397.0, -1737075661}, 4209 {4503603922337791.0, -1}, 4210 {-4503603922337791.0, 1}, 4211 {4503601774854143.0, 2147483647}, 4212 {-4503601774854143.0, -2147483647}, 4213 {9007207844675582.0, -2}, 4214 {-9007207844675582.0, 2}, 4215 {2.4178527921507624e+24, -536870912}, 4216 {-2.4178527921507624e+24, 536870912}, 4217 {2.417853945072267e+24, -536870912}, 4218 {-2.417853945072267e+24, 536870912}, 4219 {4.8357055843015248e+24, -1073741824}, 4220 {-4.8357055843015248e+24, 1073741824}, 4221 {4.8357078901445341e+24, -1073741824}, 4222 {-4.8357078901445341e+24, 1073741824}, 4223 {2147483647.0, 2147483647.0}, 4224 {-2147483648.0, -2147483648.0}, 4225 {9.6714111686030497e+24, -2147483648.0}, 4226 {-9.6714111686030497e+24, -2147483648.0}, 4227 {9.6714157802890681e+24, -2147483648.0}, 4228 {-9.6714157802890681e+24, -2147483648.0}, 4229 {1.9342813113834065e+25, 2147483648.0}, 4230 {-1.9342813113834065e+25, 2147483648.0}, 4231 {3.868562622766813e+25, 0}, 4232 {-3.868562622766813e+25, 0}, 4233 {1.7976931348623157e+308, 0}, 4234 {-1.7976931348623157e+308, 0}}; 4235 double input = -1.0; 4236 RawMachineAssemblerTester<int32_t> m; 4237 m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64))); 4238 for (size_t i = 0; i < arraysize(kValues); ++i) { 4239 input = kValues[i].from; 4240 uint64_t expected = static_cast<int64_t>(kValues[i].raw); 4241 CHECK_EQ(static_cast<int>(expected), m.Call()); 4242 } 4243 } 4244 4245 #endif // V8_TURBOFAN_TARGET 4246