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.
9 #include "src/base/bits.h"
10 #include "src/codegen.h"
11 #include "test/cctest/cctest.h"
12 #include "test/cctest/compiler/codegen-tester.h"
13 #include "test/cctest/compiler/value-helper.h"
15 #if V8_TURBOFAN_TARGET
17 using namespace v8::base;
18 using namespace v8::internal;
19 using namespace v8::internal::compiler;
21 typedef RawMachineAssembler::Label MLabel;
24 RawMachineAssemblerTester<int32_t> m;
25 Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1));
27 CHECK_EQ(1, m.Call());
31 static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
34 return m->Parameter(0);
36 return m->Parameter(1);
38 return m->Int32Constant(0);
40 return m->Int32Constant(1);
42 return m->Int32Constant(-1);
44 return m->Int32Constant(0xff);
46 return m->Int32Constant(0x01234567);
48 return m->Load(kMachInt32, m->PointerConstant(NULL));
55 TEST(CodeGenInt32Binop) {
56 RawMachineAssemblerTester<void> m;
58 const Operator* kOps[] = {
59 m.machine()->Word32And(), m.machine()->Word32Or(),
60 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
61 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
62 m.machine()->Word32Equal(), m.machine()->Int32Add(),
63 m.machine()->Int32Sub(), m.machine()->Int32Mul(),
64 m.machine()->Int32MulHigh(), m.machine()->Int32Div(),
65 m.machine()->Uint32Div(), m.machine()->Int32Mod(),
66 m.machine()->Uint32Mod(), m.machine()->Uint32MulHigh(),
67 m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
68 m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
70 for (size_t i = 0; i < arraysize(kOps); ++i) {
71 for (int j = 0; j < 8; j++) {
72 for (int k = 0; k < 8; k++) {
73 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
74 Node* a = Int32Input(&m, j);
75 Node* b = Int32Input(&m, k);
76 m.Return(m.NewNode(kOps[i], a, b));
85 RawMachineAssemblerTester<int32_t> m;
91 m.Return(m.Int32Constant(constant));
93 CHECK_EQ(constant, m.Call());
97 TEST(RunGotoMultiple) {
98 RawMachineAssemblerTester<int32_t> m;
99 int constant = 9999977;
102 for (size_t i = 0; i < arraysize(labels); i++) {
106 m.Return(m.Int32Constant(constant));
108 CHECK_EQ(constant, m.Call());
113 RawMachineAssemblerTester<int32_t> m;
114 int constant = 999777;
116 MLabel blocka, blockb;
117 m.Branch(m.Int32Constant(0), &blocka, &blockb);
119 m.Return(m.Int32Constant(0 - constant));
121 m.Return(m.Int32Constant(constant));
123 CHECK_EQ(constant, m.Call());
128 RawMachineAssemblerTester<int32_t> m;
130 int constant = 995666;
132 MLabel blocka, blockb, end;
133 m.Branch(m.Int32Constant(0), &blocka, &blockb);
139 m.Return(m.Int32Constant(constant));
141 CHECK_EQ(constant, m.Call());
146 RawMachineAssemblerTester<int32_t> m;
147 int constant = 999555;
149 MLabel header, body, exit;
152 m.Branch(m.Int32Constant(0), &body, &exit);
156 m.Return(m.Int32Constant(constant));
158 CHECK_EQ(constant, m.Call());
162 template <typename R>
163 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
164 MachineType type, Node* true_node,
166 MLabel blocka, blockb;
167 MLabel* end = m->Exit();
168 m->Branch(cond_node, &blocka, &blockb);
175 Node* phi = m->Phi(type, true_node, false_node);
180 TEST(RunDiamondPhiConst) {
181 RawMachineAssemblerTester<int32_t> m(kMachInt32);
182 int false_val = 0xFF666;
183 int true_val = 0x00DDD;
184 Node* true_node = m.Int32Constant(true_val);
185 Node* false_node = m.Int32Constant(false_val);
186 BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, true_node, false_node);
187 CHECK_EQ(false_val, m.Call(0));
188 CHECK_EQ(true_val, m.Call(1));
192 TEST(RunDiamondPhiNumber) {
193 RawMachineAssemblerTester<Object*> m(kMachInt32);
194 double false_val = -11.1;
195 double true_val = 200.1;
196 Node* true_node = m.NumberConstant(true_val);
197 Node* false_node = m.NumberConstant(false_val);
198 BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node);
199 m.CheckNumber(false_val, m.Call(0));
200 m.CheckNumber(true_val, m.Call(1));
204 TEST(RunDiamondPhiString) {
205 RawMachineAssemblerTester<Object*> m(kMachInt32);
206 const char* false_val = "false";
207 const char* true_val = "true";
208 Node* true_node = m.StringConstant(true_val);
209 Node* false_node = m.StringConstant(false_val);
210 BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node);
211 m.CheckString(false_val, m.Call(0));
212 m.CheckString(true_val, m.Call(1));
216 TEST(RunDiamondPhiParam) {
217 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
218 BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, m.Parameter(1),
220 int32_t c1 = 0x260cb75a;
221 int32_t c2 = 0xcd3e9c8b;
222 int result = m.Call(0, c1, c2);
223 CHECK_EQ(c2, result);
224 result = m.Call(1, c1, c2);
225 CHECK_EQ(c1, result);
229 TEST(RunLoopPhiConst) {
230 RawMachineAssemblerTester<int32_t> m;
231 int true_val = 0x44000;
232 int false_val = 0x00888;
234 Node* cond_node = m.Int32Constant(0);
235 Node* true_node = m.Int32Constant(true_val);
236 Node* false_node = m.Int32Constant(false_val);
238 // x = false_val; while(false) { x = true_val; } return x;
240 MLabel* end = m.Exit();
244 Node* phi = m.Phi(kMachInt32, false_node, true_node);
245 m.Branch(cond_node, &body, end);
251 CHECK_EQ(false_val, m.Call());
255 TEST(RunLoopPhiParam) {
256 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
258 MLabel blocka, blockb;
259 MLabel* end = m.Exit();
264 Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2));
265 Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0));
266 m.Branch(cond, &blockb, end);
274 int32_t c1 = 0xa81903b4;
275 int32_t c2 = 0x5a1207da;
276 int result = m.Call(0, c1, c2);
277 CHECK_EQ(c1, result);
278 result = m.Call(1, c1, c2);
279 CHECK_EQ(c2, result);
283 TEST(RunLoopPhiInduction) {
284 RawMachineAssemblerTester<int32_t> m;
286 int false_val = 0x10777;
288 // x = false_val; while(false) { x++; } return x;
290 MLabel* end = m.Exit();
291 Node* false_node = m.Int32Constant(false_val);
296 Node* phi = m.Phi(kMachInt32, false_node, false_node);
297 m.Branch(m.Int32Constant(0), &body, end);
300 Node* add = m.Int32Add(phi, m.Int32Constant(1));
301 phi->ReplaceInput(1, add);
307 CHECK_EQ(false_val, m.Call());
311 TEST(RunLoopIncrement) {
312 RawMachineAssemblerTester<int32_t> m;
313 Int32BinopTester bt(&m);
315 // x = 0; while(x ^ param) { x++; } return x;
317 MLabel* end = m.Exit();
318 Node* zero = m.Int32Constant(0);
323 Node* phi = m.Phi(kMachInt32, zero, zero);
324 m.Branch(m.WordXor(phi, bt.param0), &body, end);
327 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
333 CHECK_EQ(11, bt.call(11, 0));
334 CHECK_EQ(110, bt.call(110, 0));
335 CHECK_EQ(176, bt.call(176, 0));
339 TEST(RunLoopIncrement2) {
340 RawMachineAssemblerTester<int32_t> m;
341 Int32BinopTester bt(&m);
343 // x = 0; while(x < param) { x++; } return x;
345 MLabel* end = m.Exit();
346 Node* zero = m.Int32Constant(0);
351 Node* phi = m.Phi(kMachInt32, zero, zero);
352 m.Branch(m.Int32LessThan(phi, bt.param0), &body, end);
355 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
361 CHECK_EQ(11, bt.call(11, 0));
362 CHECK_EQ(110, bt.call(110, 0));
363 CHECK_EQ(176, bt.call(176, 0));
364 CHECK_EQ(0, bt.call(-200, 0));
368 TEST(RunLoopIncrement3) {
369 RawMachineAssemblerTester<int32_t> m;
370 Int32BinopTester bt(&m);
372 // x = 0; while(x < param) { x++; } return x;
374 MLabel* end = m.Exit();
375 Node* zero = m.Int32Constant(0);
380 Node* phi = m.Phi(kMachInt32, zero, zero);
381 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end);
384 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
390 CHECK_EQ(11, bt.call(11, 0));
391 CHECK_EQ(110, bt.call(110, 0));
392 CHECK_EQ(176, bt.call(176, 0));
393 CHECK_EQ(200, bt.call(200, 0));
397 TEST(RunLoopDecrement) {
398 RawMachineAssemblerTester<int32_t> m;
399 Int32BinopTester bt(&m);
401 // x = param; while(x) { x--; } return x;
403 MLabel* end = m.Exit();
408 Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0));
409 m.Branch(phi, &body, end);
412 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
418 CHECK_EQ(0, bt.call(11, 0));
419 CHECK_EQ(0, bt.call(110, 0));
420 CHECK_EQ(0, bt.call(197, 0));
424 TEST(RunLoopIncrementFloat64) {
425 RawMachineAssemblerTester<int32_t> m;
427 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
429 MLabel* end = m.Exit();
430 Node* minus_3 = m.Float64Constant(-3.0);
431 Node* ten = m.Float64Constant(10.0);
436 Node* phi = m.Phi(kMachFloat64, minus_3, ten);
437 m.Branch(m.Float64LessThan(phi, ten), &body, end);
440 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
444 m.Return(m.ChangeFloat64ToInt32(phi));
446 CHECK_EQ(10, m.Call());
451 RawMachineAssemblerTester<int32_t> m;
453 int constant = 11223344;
455 MLabel block0, block1, def, end;
456 MLabel* case_labels[] = {&block0, &block1};
457 int32_t case_values[] = {0, 1};
458 m.Switch(m.Int32Constant(0), &def, case_values, case_labels,
459 arraysize(case_labels));
467 m.Return(m.Int32Constant(constant));
469 CHECK_EQ(constant, m.Call());
474 RawMachineAssemblerTester<int32_t> m(kMachInt32);
476 MLabel blocka, blockb, blockc;
477 MLabel* case_labels[] = {&blocka, &blockb};
478 int32_t case_values[] = {std::numeric_limits<int32_t>::min(),
479 std::numeric_limits<int32_t>::max()};
480 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
481 arraysize(case_labels));
483 m.Return(m.Int32Constant(-1));
485 m.Return(m.Int32Constant(1));
487 m.Return(m.Int32Constant(0));
489 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max()));
490 CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min()));
491 for (int i = -100; i < 100; i += 25) {
492 CHECK_EQ(0, m.Call(i));
498 RawMachineAssemblerTester<int32_t> m(kMachInt32);
500 MLabel blocka, blockb, blockc;
501 MLabel* case_labels[] = {&blocka, &blockb};
502 int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0,
503 std::numeric_limits<int32_t>::min() + 1};
504 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
505 arraysize(case_labels));
507 m.Return(m.Int32Constant(0));
509 m.Return(m.Int32Constant(1));
511 m.Return(m.Int32Constant(2));
513 CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0));
514 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1));
515 for (int i = -100; i < 100; i += 25) {
516 CHECK_EQ(2, m.Call(i));
522 RawMachineAssemblerTester<int32_t> m(kMachInt32);
524 const size_t kNumCases = 512;
525 const size_t kNumValues = kNumCases + 1;
526 int32_t values[kNumValues];
527 m.main_isolate()->random_number_generator()->NextBytes(values,
530 int32_t case_values[kNumCases];
531 MLabel* case_labels[kNumCases];
532 Node* results[kNumValues];
533 for (size_t i = 0; i < kNumCases; ++i) {
534 case_values[i] = static_cast<int32_t>(i);
535 case_labels[i] = new (m.main_zone()->New(sizeof(MLabel))) MLabel;
537 m.Switch(m.Parameter(0), &def, case_values, case_labels,
538 arraysize(case_labels));
539 for (size_t i = 0; i < kNumCases; ++i) {
540 m.Bind(case_labels[i]);
541 results[i] = m.Int32Constant(values[i]);
545 results[kNumCases] = m.Int32Constant(values[kNumCases]);
548 const int num_results = static_cast<int>(arraysize(results));
550 m.NewNode(m.common()->Phi(kMachInt32, num_results), num_results, results);
553 for (size_t i = 0; i < kNumValues; ++i) {
554 CHECK_EQ(values[i], m.Call(static_cast<int>(i)));
560 RawMachineAssemblerTester<int32_t> m;
562 int32_t p1 = 0; // loads directly from this location.
563 m.Return(m.LoadFromPointer(&p1, kMachInt32));
565 FOR_INT32_INPUTS(i) {
567 CHECK_EQ(p1, m.Call());
572 TEST(RunLoadInt32Offset) {
573 int32_t p1 = 0; // loads directly from this location.
575 int32_t offsets[] = {-2000000, -100, -101, 1, 3,
576 7, 120, 2000, 2000000000, 0xff};
578 for (size_t i = 0; i < arraysize(offsets); i++) {
579 RawMachineAssemblerTester<int32_t> m;
580 int32_t offset = offsets[i];
581 byte* pointer = reinterpret_cast<byte*>(&p1) - offset;
582 // generate load [#base + #index]
583 m.Return(m.LoadFromPointer(pointer, kMachInt32, offset));
585 FOR_INT32_INPUTS(j) {
587 CHECK_EQ(p1, m.Call());
593 TEST(RunLoadStoreFloat64Offset) {
594 double p1 = 0; // loads directly from this location.
595 double p2 = 0; // and stores directly into this location.
597 FOR_INT32_INPUTS(i) {
598 int32_t magic = 0x2342aabb + *i * 3;
599 RawMachineAssemblerTester<int32_t> m;
601 byte* from = reinterpret_cast<byte*>(&p1) - offset;
602 byte* to = reinterpret_cast<byte*>(&p2) - offset;
603 // generate load [#base + #index]
605 m.Load(kMachFloat64, m.PointerConstant(from), m.Int32Constant(offset));
606 m.Store(kMachFloat64, m.PointerConstant(to), m.Int32Constant(offset), load);
607 m.Return(m.Int32Constant(magic));
609 FOR_FLOAT64_INPUTS(j) {
612 CHECK_EQ(magic, m.Call());
613 CheckDoubleEq(p1, p2);
620 RawMachineAssemblerTester<int32_t> m;
621 Int32BinopTester bt(&m);
623 bt.AddReturn(m.Int32Add(bt.param0, bt.param1));
625 FOR_INT32_INPUTS(i) {
626 FOR_INT32_INPUTS(j) {
627 // Use uint32_t because signed overflow is UB in C.
628 int expected = static_cast<int32_t>(*i + *j);
629 CHECK_EQ(expected, bt.call(*i, *j));
635 TEST(RunInt32AddAndWord32EqualP) {
637 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
638 m.Return(m.Int32Add(m.Parameter(0),
639 m.Word32Equal(m.Parameter(1), m.Parameter(2))));
640 FOR_INT32_INPUTS(i) {
641 FOR_INT32_INPUTS(j) {
642 FOR_INT32_INPUTS(k) {
643 // Use uint32_t because signed overflow is UB in C.
644 int32_t const expected =
645 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
646 CHECK_EQ(expected, m.Call(*i, *j, *k));
652 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
653 m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
655 FOR_INT32_INPUTS(i) {
656 FOR_INT32_INPUTS(j) {
657 FOR_INT32_INPUTS(k) {
658 // Use uint32_t because signed overflow is UB in C.
659 int32_t const expected =
660 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
661 CHECK_EQ(expected, m.Call(*i, *j, *k));
669 TEST(RunInt32AddAndWord32EqualImm) {
671 FOR_INT32_INPUTS(i) {
672 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
673 m.Return(m.Int32Add(m.Int32Constant(*i),
674 m.Word32Equal(m.Parameter(0), m.Parameter(1))));
675 FOR_INT32_INPUTS(j) {
676 FOR_INT32_INPUTS(k) {
677 // Use uint32_t because signed overflow is UB in C.
678 int32_t const expected =
679 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
680 CHECK_EQ(expected, m.Call(*j, *k));
686 FOR_INT32_INPUTS(i) {
687 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
688 m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
690 FOR_INT32_INPUTS(j) {
691 FOR_INT32_INPUTS(k) {
692 // Use uint32_t because signed overflow is UB in C.
693 int32_t const expected =
694 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
695 CHECK_EQ(expected, m.Call(*j, *k));
703 TEST(RunInt32AddAndWord32NotEqualP) {
705 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
706 m.Return(m.Int32Add(m.Parameter(0),
707 m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
708 FOR_INT32_INPUTS(i) {
709 FOR_INT32_INPUTS(j) {
710 FOR_INT32_INPUTS(k) {
711 // Use uint32_t because signed overflow is UB in C.
712 int32_t const expected =
713 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
714 CHECK_EQ(expected, m.Call(*i, *j, *k));
720 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
721 m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
723 FOR_INT32_INPUTS(i) {
724 FOR_INT32_INPUTS(j) {
725 FOR_INT32_INPUTS(k) {
726 // Use uint32_t because signed overflow is UB in C.
727 int32_t const expected =
728 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
729 CHECK_EQ(expected, m.Call(*i, *j, *k));
737 TEST(RunInt32AddAndWord32NotEqualImm) {
739 FOR_INT32_INPUTS(i) {
740 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
741 m.Return(m.Int32Add(m.Int32Constant(*i),
742 m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
743 FOR_INT32_INPUTS(j) {
744 FOR_INT32_INPUTS(k) {
745 // Use uint32_t because signed overflow is UB in C.
746 int32_t const expected =
747 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
748 CHECK_EQ(expected, m.Call(*j, *k));
754 FOR_INT32_INPUTS(i) {
755 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
756 m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
758 FOR_INT32_INPUTS(j) {
759 FOR_INT32_INPUTS(k) {
760 // Use uint32_t because signed overflow is UB in C.
761 int32_t const expected =
762 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
763 CHECK_EQ(expected, m.Call(*j, *k));
771 TEST(RunInt32AddAndWord32SarP) {
773 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
774 m.Return(m.Int32Add(m.Parameter(0),
775 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
776 FOR_UINT32_INPUTS(i) {
777 FOR_INT32_INPUTS(j) {
778 FOR_UINT32_SHIFTS(shift) {
779 // Use uint32_t because signed overflow is UB in C.
780 int32_t expected = *i + (*j >> shift);
781 CHECK_EQ(expected, m.Call(*i, *j, shift));
787 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
788 m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
790 FOR_INT32_INPUTS(i) {
791 FOR_UINT32_SHIFTS(shift) {
792 FOR_UINT32_INPUTS(k) {
793 // Use uint32_t because signed overflow is UB in C.
794 int32_t expected = (*i >> shift) + *k;
795 CHECK_EQ(expected, m.Call(*i, shift, *k));
803 TEST(RunInt32AddAndWord32ShlP) {
805 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
806 m.Return(m.Int32Add(m.Parameter(0),
807 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
808 FOR_UINT32_INPUTS(i) {
809 FOR_INT32_INPUTS(j) {
810 FOR_UINT32_SHIFTS(shift) {
811 // Use uint32_t because signed overflow is UB in C.
812 int32_t expected = *i + (*j << shift);
813 CHECK_EQ(expected, m.Call(*i, *j, shift));
819 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
820 m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
822 FOR_INT32_INPUTS(i) {
823 FOR_UINT32_SHIFTS(shift) {
824 FOR_UINT32_INPUTS(k) {
825 // Use uint32_t because signed overflow is UB in C.
826 int32_t expected = (*i << shift) + *k;
827 CHECK_EQ(expected, m.Call(*i, shift, *k));
835 TEST(RunInt32AddAndWord32ShrP) {
837 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
838 m.Return(m.Int32Add(m.Parameter(0),
839 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
840 FOR_UINT32_INPUTS(i) {
841 FOR_UINT32_INPUTS(j) {
842 FOR_UINT32_SHIFTS(shift) {
843 // Use uint32_t because signed overflow is UB in C.
844 int32_t expected = *i + (*j >> shift);
845 CHECK_EQ(expected, m.Call(*i, *j, shift));
851 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
852 m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
854 FOR_UINT32_INPUTS(i) {
855 FOR_UINT32_SHIFTS(shift) {
856 FOR_UINT32_INPUTS(k) {
857 // Use uint32_t because signed overflow is UB in C.
858 int32_t expected = (*i >> shift) + *k;
859 CHECK_EQ(expected, m.Call(*i, shift, *k));
867 TEST(RunInt32AddInBranch) {
868 static const int32_t constant = 987654321;
870 RawMachineAssemblerTester<int32_t> m;
871 Int32BinopTester bt(&m);
872 MLabel blocka, blockb;
874 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
877 bt.AddReturn(m.Int32Constant(constant));
879 bt.AddReturn(m.Int32Constant(0 - constant));
880 FOR_UINT32_INPUTS(i) {
881 FOR_UINT32_INPUTS(j) {
882 int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
883 CHECK_EQ(expected, bt.call(*i, *j));
888 RawMachineAssemblerTester<int32_t> m;
889 Int32BinopTester bt(&m);
890 MLabel blocka, blockb;
892 m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
895 bt.AddReturn(m.Int32Constant(constant));
897 bt.AddReturn(m.Int32Constant(0 - constant));
898 FOR_UINT32_INPUTS(i) {
899 FOR_UINT32_INPUTS(j) {
900 int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
901 CHECK_EQ(expected, bt.call(*i, *j));
906 FOR_UINT32_INPUTS(i) {
907 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
908 MLabel blocka, blockb;
909 m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
913 m.Return(m.Int32Constant(constant));
915 m.Return(m.Int32Constant(0 - constant));
916 FOR_UINT32_INPUTS(j) {
917 uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
918 CHECK_EQ(expected, m.Call(*j));
923 FOR_UINT32_INPUTS(i) {
924 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
925 MLabel blocka, blockb;
926 m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
930 m.Return(m.Int32Constant(constant));
932 m.Return(m.Int32Constant(0 - constant));
933 FOR_UINT32_INPUTS(j) {
934 uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
935 CHECK_EQ(expected, m.Call(*j));
940 RawMachineAssemblerTester<void> m;
941 const Operator* shops[] = {m.machine()->Word32Sar(),
942 m.machine()->Word32Shl(),
943 m.machine()->Word32Shr()};
944 for (size_t n = 0; n < arraysize(shops); n++) {
945 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
947 MLabel blocka, blockb;
948 m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
949 m.NewNode(shops[n], m.Parameter(1),
954 m.Return(m.Int32Constant(constant));
956 m.Return(m.Int32Constant(0 - constant));
957 FOR_UINT32_INPUTS(i) {
958 FOR_INT32_INPUTS(j) {
959 FOR_UINT32_SHIFTS(shift) {
961 switch (shops[n]->opcode()) {
964 case IrOpcode::kWord32Sar:
967 case IrOpcode::kWord32Shl:
970 case IrOpcode::kWord32Shr:
971 right = static_cast<uint32_t>(*j) >> shift;
974 int32_t expected = ((*i + right) == 0) ? constant : 0 - constant;
975 CHECK_EQ(expected, m.Call(*i, *j, shift));
984 TEST(RunInt32AddInComparison) {
986 RawMachineAssemblerTester<int32_t> m;
987 Uint32BinopTester bt(&m);
989 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)));
990 FOR_UINT32_INPUTS(i) {
991 FOR_UINT32_INPUTS(j) {
992 uint32_t expected = (*i + *j) == 0;
993 CHECK_EQ(expected, bt.call(*i, *j));
998 RawMachineAssemblerTester<int32_t> m;
999 Uint32BinopTester bt(&m);
1001 m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1)));
1002 FOR_UINT32_INPUTS(i) {
1003 FOR_UINT32_INPUTS(j) {
1004 uint32_t expected = (*i + *j) == 0;
1005 CHECK_EQ(expected, bt.call(*i, *j));
1010 FOR_UINT32_INPUTS(i) {
1011 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1012 m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1013 m.Int32Constant(0)));
1014 FOR_UINT32_INPUTS(j) {
1015 uint32_t expected = (*i + *j) == 0;
1016 CHECK_EQ(expected, m.Call(*j));
1021 FOR_UINT32_INPUTS(i) {
1022 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1023 m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
1024 m.Int32Constant(0)));
1025 FOR_UINT32_INPUTS(j) {
1026 uint32_t expected = (*j + *i) == 0;
1027 CHECK_EQ(expected, m.Call(*j));
1032 RawMachineAssemblerTester<void> m;
1033 const Operator* shops[] = {m.machine()->Word32Sar(),
1034 m.machine()->Word32Shl(),
1035 m.machine()->Word32Shr()};
1036 for (size_t n = 0; n < arraysize(shops); n++) {
1037 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
1039 m.Return(m.Word32Equal(
1040 m.Int32Add(m.Parameter(0),
1041 m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
1042 m.Int32Constant(0)));
1043 FOR_UINT32_INPUTS(i) {
1044 FOR_INT32_INPUTS(j) {
1045 FOR_UINT32_SHIFTS(shift) {
1047 switch (shops[n]->opcode()) {
1050 case IrOpcode::kWord32Sar:
1051 right = *j >> shift;
1053 case IrOpcode::kWord32Shl:
1054 right = *j << shift;
1056 case IrOpcode::kWord32Shr:
1057 right = static_cast<uint32_t>(*j) >> shift;
1060 int32_t expected = (*i + right) == 0;
1061 CHECK_EQ(expected, m.Call(*i, *j, shift));
1070 TEST(RunInt32SubP) {
1071 RawMachineAssemblerTester<int32_t> m;
1072 Uint32BinopTester bt(&m);
1074 m.Return(m.Int32Sub(bt.param0, bt.param1));
1076 FOR_UINT32_INPUTS(i) {
1077 FOR_UINT32_INPUTS(j) {
1078 uint32_t expected = static_cast<int32_t>(*i - *j);
1079 CHECK_EQ(expected, bt.call(*i, *j));
1085 TEST(RunInt32SubImm) {
1087 FOR_UINT32_INPUTS(i) {
1088 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1089 m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
1090 FOR_UINT32_INPUTS(j) {
1091 uint32_t expected = *i - *j;
1092 CHECK_EQ(expected, m.Call(*j));
1097 FOR_UINT32_INPUTS(i) {
1098 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1099 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
1100 FOR_UINT32_INPUTS(j) {
1101 uint32_t expected = *j - *i;
1102 CHECK_EQ(expected, m.Call(*j));
1109 TEST(RunInt32SubAndWord32SarP) {
1111 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
1112 m.Return(m.Int32Sub(m.Parameter(0),
1113 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1114 FOR_UINT32_INPUTS(i) {
1115 FOR_INT32_INPUTS(j) {
1116 FOR_UINT32_SHIFTS(shift) {
1117 int32_t expected = *i - (*j >> shift);
1118 CHECK_EQ(expected, m.Call(*i, *j, shift));
1124 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
1125 m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1127 FOR_INT32_INPUTS(i) {
1128 FOR_UINT32_SHIFTS(shift) {
1129 FOR_UINT32_INPUTS(k) {
1130 int32_t expected = (*i >> shift) - *k;
1131 CHECK_EQ(expected, m.Call(*i, shift, *k));
1139 TEST(RunInt32SubAndWord32ShlP) {
1141 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
1142 m.Return(m.Int32Sub(m.Parameter(0),
1143 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1144 FOR_UINT32_INPUTS(i) {
1145 FOR_INT32_INPUTS(j) {
1146 FOR_UINT32_SHIFTS(shift) {
1147 int32_t expected = *i - (*j << shift);
1148 CHECK_EQ(expected, m.Call(*i, *j, shift));
1154 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32);
1155 m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1157 FOR_INT32_INPUTS(i) {
1158 FOR_UINT32_SHIFTS(shift) {
1159 FOR_UINT32_INPUTS(k) {
1160 // Use uint32_t because signed overflow is UB in C.
1161 int32_t expected = (*i << shift) - *k;
1162 CHECK_EQ(expected, m.Call(*i, shift, *k));
1170 TEST(RunInt32SubAndWord32ShrP) {
1172 RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32,
1174 m.Return(m.Int32Sub(m.Parameter(0),
1175 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1176 FOR_UINT32_INPUTS(i) {
1177 FOR_UINT32_INPUTS(j) {
1178 FOR_UINT32_SHIFTS(shift) {
1179 // Use uint32_t because signed overflow is UB in C.
1180 uint32_t expected = *i - (*j >> shift);
1181 CHECK_EQ(expected, m.Call(*i, *j, shift));
1187 RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32,
1189 m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1191 FOR_UINT32_INPUTS(i) {
1192 FOR_UINT32_SHIFTS(shift) {
1193 FOR_UINT32_INPUTS(k) {
1194 // Use uint32_t because signed overflow is UB in C.
1195 uint32_t expected = (*i >> shift) - *k;
1196 CHECK_EQ(expected, m.Call(*i, shift, *k));
1204 TEST(RunInt32SubInBranch) {
1205 static const int constant = 987654321;
1207 RawMachineAssemblerTester<int32_t> m;
1208 Int32BinopTester bt(&m);
1209 MLabel blocka, blockb;
1211 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1214 bt.AddReturn(m.Int32Constant(constant));
1216 bt.AddReturn(m.Int32Constant(0 - constant));
1217 FOR_UINT32_INPUTS(i) {
1218 FOR_UINT32_INPUTS(j) {
1219 int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
1220 CHECK_EQ(expected, bt.call(*i, *j));
1225 RawMachineAssemblerTester<int32_t> m;
1226 Int32BinopTester bt(&m);
1227 MLabel blocka, blockb;
1229 m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1232 bt.AddReturn(m.Int32Constant(constant));
1234 bt.AddReturn(m.Int32Constant(0 - constant));
1235 FOR_UINT32_INPUTS(i) {
1236 FOR_UINT32_INPUTS(j) {
1237 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1238 CHECK_EQ(expected, bt.call(*i, *j));
1243 FOR_UINT32_INPUTS(i) {
1244 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1245 MLabel blocka, blockb;
1246 m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1247 m.Int32Constant(0)),
1250 m.Return(m.Int32Constant(constant));
1252 m.Return(m.Int32Constant(0 - constant));
1253 FOR_UINT32_INPUTS(j) {
1254 uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
1255 CHECK_EQ(expected, m.Call(*j));
1260 FOR_UINT32_INPUTS(i) {
1261 RawMachineAssemblerTester<int32_t> m(kMachUint32);
1262 MLabel blocka, blockb;
1263 m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1264 m.Int32Constant(0)),
1267 m.Return(m.Int32Constant(constant));
1269 m.Return(m.Int32Constant(0 - constant));
1270 FOR_UINT32_INPUTS(j) {
1271 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1272 CHECK_EQ(expected, m.Call(*j));
1277 RawMachineAssemblerTester<void> m;
1278 const Operator* shops[] = {m.machine()->Word32Sar(),
1279 m.machine()->Word32Shl(),
1280 m.machine()->Word32Shr()};
1281 for (size_t n = 0; n < arraysize(shops); n++) {
1282 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
1284 MLabel blocka, blockb;
1285 m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
1286 m.NewNode(shops[n], m.Parameter(1),
1288 m.Int32Constant(0)),
1291 m.Return(m.Int32Constant(constant));
1293 m.Return(m.Int32Constant(0 - constant));
1294 FOR_UINT32_INPUTS(i) {
1295 FOR_INT32_INPUTS(j) {
1296 FOR_UINT32_SHIFTS(shift) {
1298 switch (shops[n]->opcode()) {
1301 case IrOpcode::kWord32Sar:
1302 right = *j >> shift;
1304 case IrOpcode::kWord32Shl:
1305 right = *j << shift;
1307 case IrOpcode::kWord32Shr:
1308 right = static_cast<uint32_t>(*j) >> shift;
1311 int32_t expected = ((*i - right) == 0) ? constant : 0 - constant;
1312 CHECK_EQ(expected, m.Call(*i, *j, shift));
1321 TEST(RunInt32SubInComparison) {
1323 RawMachineAssemblerTester<int32_t> m;
1324 Uint32BinopTester bt(&m);
1326 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)));
1327 FOR_UINT32_INPUTS(i) {
1328 FOR_UINT32_INPUTS(j) {
1329 uint32_t expected = (*i - *j) == 0;
1330 CHECK_EQ(expected, bt.call(*i, *j));
1335 RawMachineAssemblerTester<int32_t> m;
1336 Uint32BinopTester bt(&m);
1338 m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1)));
1339 FOR_UINT32_INPUTS(i) {
1340 FOR_UINT32_INPUTS(j) {
1341 uint32_t expected = (*i - *j) == 0;
1342 CHECK_EQ(expected, bt.call(*i, *j));
1347 FOR_UINT32_INPUTS(i) {
1348 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1349 m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1350 m.Int32Constant(0)));
1351 FOR_UINT32_INPUTS(j) {
1352 uint32_t expected = (*i - *j) == 0;
1353 CHECK_EQ(expected, m.Call(*j));
1358 FOR_UINT32_INPUTS(i) {
1359 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1360 m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
1361 m.Int32Constant(0)));
1362 FOR_UINT32_INPUTS(j) {
1363 uint32_t expected = (*j - *i) == 0;
1364 CHECK_EQ(expected, m.Call(*j));
1369 RawMachineAssemblerTester<void> m;
1370 const Operator* shops[] = {m.machine()->Word32Sar(),
1371 m.machine()->Word32Shl(),
1372 m.machine()->Word32Shr()};
1373 for (size_t n = 0; n < arraysize(shops); n++) {
1374 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
1376 m.Return(m.Word32Equal(
1377 m.Int32Sub(m.Parameter(0),
1378 m.NewNode(shops[n], m.Parameter(1), m.Parameter(2))),
1379 m.Int32Constant(0)));
1380 FOR_UINT32_INPUTS(i) {
1381 FOR_INT32_INPUTS(j) {
1382 FOR_UINT32_SHIFTS(shift) {
1384 switch (shops[n]->opcode()) {
1387 case IrOpcode::kWord32Sar:
1388 right = *j >> shift;
1390 case IrOpcode::kWord32Shl:
1391 right = *j << shift;
1393 case IrOpcode::kWord32Shr:
1394 right = static_cast<uint32_t>(*j) >> shift;
1397 int32_t expected = (*i - right) == 0;
1398 CHECK_EQ(expected, m.Call(*i, *j, shift));
1407 TEST(RunInt32MulP) {
1409 RawMachineAssemblerTester<int32_t> m;
1410 Int32BinopTester bt(&m);
1411 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
1412 FOR_INT32_INPUTS(i) {
1413 FOR_INT32_INPUTS(j) {
1414 int expected = static_cast<int32_t>(*i * *j);
1415 CHECK_EQ(expected, bt.call(*i, *j));
1420 RawMachineAssemblerTester<int32_t> m;
1421 Uint32BinopTester bt(&m);
1422 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
1423 FOR_UINT32_INPUTS(i) {
1424 FOR_UINT32_INPUTS(j) {
1425 uint32_t expected = *i * *j;
1426 CHECK_EQ(expected, bt.call(*i, *j));
1433 TEST(RunInt32MulHighP) {
1434 RawMachineAssemblerTester<int32_t> m;
1435 Int32BinopTester bt(&m);
1436 bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
1437 FOR_INT32_INPUTS(i) {
1438 FOR_INT32_INPUTS(j) {
1439 int32_t expected = static_cast<int32_t>(
1440 (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
1441 CHECK_EQ(expected, bt.call(*i, *j));
1447 TEST(RunInt32MulImm) {
1449 FOR_UINT32_INPUTS(i) {
1450 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1451 m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
1452 FOR_UINT32_INPUTS(j) {
1453 uint32_t expected = *i * *j;
1454 CHECK_EQ(expected, m.Call(*j));
1459 FOR_UINT32_INPUTS(i) {
1460 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1461 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
1462 FOR_UINT32_INPUTS(j) {
1463 uint32_t expected = *j * *i;
1464 CHECK_EQ(expected, m.Call(*j));
1471 TEST(RunInt32MulAndInt32AddP) {
1473 FOR_INT32_INPUTS(i) {
1474 FOR_INT32_INPUTS(j) {
1475 RawMachineAssemblerTester<int32_t> m(kMachInt32);
1478 m.Return(m.Int32Add(m.Int32Constant(p0),
1479 m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
1480 FOR_INT32_INPUTS(k) {
1482 int expected = p0 + static_cast<int32_t>(p1 * p2);
1483 CHECK_EQ(expected, m.Call(p2));
1489 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
1491 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1492 FOR_INT32_INPUTS(i) {
1493 FOR_INT32_INPUTS(j) {
1494 FOR_INT32_INPUTS(k) {
1498 int expected = p0 + static_cast<int32_t>(p1 * p2);
1499 CHECK_EQ(expected, m.Call(p0, p1, p2));
1505 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
1507 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
1508 FOR_INT32_INPUTS(i) {
1509 FOR_INT32_INPUTS(j) {
1510 FOR_INT32_INPUTS(k) {
1514 int expected = static_cast<int32_t>(p0 * p1) + p2;
1515 CHECK_EQ(expected, m.Call(p0, p1, p2));
1521 FOR_INT32_INPUTS(i) {
1522 RawMachineAssemblerTester<int32_t> m;
1523 Int32BinopTester bt(&m);
1525 m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
1526 FOR_INT32_INPUTS(j) {
1527 FOR_INT32_INPUTS(k) {
1530 int expected = *i + static_cast<int32_t>(p0 * p1);
1531 CHECK_EQ(expected, bt.call(p0, p1));
1539 TEST(RunInt32MulAndInt32SubP) {
1541 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachInt32);
1543 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1544 FOR_UINT32_INPUTS(i) {
1545 FOR_INT32_INPUTS(j) {
1546 FOR_INT32_INPUTS(k) {
1550 // Use uint32_t because signed overflow is UB in C.
1551 int expected = p0 - static_cast<uint32_t>(p1 * p2);
1552 CHECK_EQ(expected, m.Call(p0, p1, p2));
1558 FOR_UINT32_INPUTS(i) {
1559 RawMachineAssemblerTester<int32_t> m;
1560 Int32BinopTester bt(&m);
1562 m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
1563 FOR_INT32_INPUTS(j) {
1564 FOR_INT32_INPUTS(k) {
1567 // Use uint32_t because signed overflow is UB in C.
1568 int expected = *i - static_cast<uint32_t>(p0 * p1);
1569 CHECK_EQ(expected, bt.call(p0, p1));
1577 TEST(RunUint32MulHighP) {
1578 RawMachineAssemblerTester<int32_t> m;
1579 Int32BinopTester bt(&m);
1580 bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
1581 FOR_UINT32_INPUTS(i) {
1582 FOR_UINT32_INPUTS(j) {
1583 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
1584 (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
1585 CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
1591 TEST(RunInt32DivP) {
1593 RawMachineAssemblerTester<int32_t> m;
1594 Int32BinopTester bt(&m);
1595 bt.AddReturn(m.Int32Div(bt.param0, bt.param1));
1596 FOR_INT32_INPUTS(i) {
1597 FOR_INT32_INPUTS(j) {
1600 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
1601 int expected = static_cast<int32_t>(p0 / p1);
1602 CHECK_EQ(expected, bt.call(p0, p1));
1608 RawMachineAssemblerTester<int32_t> m;
1609 Int32BinopTester bt(&m);
1610 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1)));
1611 FOR_INT32_INPUTS(i) {
1612 FOR_INT32_INPUTS(j) {
1615 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
1616 int expected = static_cast<int32_t>(p0 + (p0 / p1));
1617 CHECK_EQ(expected, bt.call(p0, p1));
1625 TEST(RunUint32DivP) {
1627 RawMachineAssemblerTester<int32_t> m;
1628 Int32BinopTester bt(&m);
1629 bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
1630 FOR_UINT32_INPUTS(i) {
1631 FOR_UINT32_INPUTS(j) {
1635 int32_t expected = bit_cast<int32_t>(p0 / p1);
1636 CHECK_EQ(expected, bt.call(p0, p1));
1642 RawMachineAssemblerTester<int32_t> m;
1643 Int32BinopTester bt(&m);
1644 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
1645 FOR_UINT32_INPUTS(i) {
1646 FOR_UINT32_INPUTS(j) {
1650 int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1));
1651 CHECK_EQ(expected, bt.call(p0, p1));
1659 TEST(RunInt32ModP) {
1661 RawMachineAssemblerTester<int32_t> m;
1662 Int32BinopTester bt(&m);
1663 bt.AddReturn(m.Int32Mod(bt.param0, bt.param1));
1664 FOR_INT32_INPUTS(i) {
1665 FOR_INT32_INPUTS(j) {
1668 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
1669 int expected = static_cast<int32_t>(p0 % p1);
1670 CHECK_EQ(expected, bt.call(p0, p1));
1676 RawMachineAssemblerTester<int32_t> m;
1677 Int32BinopTester bt(&m);
1678 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1)));
1679 FOR_INT32_INPUTS(i) {
1680 FOR_INT32_INPUTS(j) {
1683 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
1684 int expected = static_cast<int32_t>(p0 + (p0 % p1));
1685 CHECK_EQ(expected, bt.call(p0, p1));
1693 TEST(RunUint32ModP) {
1695 RawMachineAssemblerTester<int32_t> m;
1696 Uint32BinopTester bt(&m);
1697 bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
1698 FOR_UINT32_INPUTS(i) {
1699 FOR_UINT32_INPUTS(j) {
1703 uint32_t expected = static_cast<uint32_t>(p0 % p1);
1704 CHECK_EQ(expected, bt.call(p0, p1));
1710 RawMachineAssemblerTester<int32_t> m;
1711 Uint32BinopTester bt(&m);
1712 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
1713 FOR_UINT32_INPUTS(i) {
1714 FOR_UINT32_INPUTS(j) {
1718 uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1));
1719 CHECK_EQ(expected, bt.call(p0, p1));
1727 TEST(RunWord32AndP) {
1729 RawMachineAssemblerTester<int32_t> m;
1730 Int32BinopTester bt(&m);
1731 bt.AddReturn(m.Word32And(bt.param0, bt.param1));
1732 FOR_UINT32_INPUTS(i) {
1733 FOR_UINT32_INPUTS(j) {
1734 int32_t expected = *i & *j;
1735 CHECK_EQ(expected, bt.call(*i, *j));
1740 RawMachineAssemblerTester<int32_t> m;
1741 Int32BinopTester bt(&m);
1742 bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
1743 FOR_UINT32_INPUTS(i) {
1744 FOR_UINT32_INPUTS(j) {
1745 int32_t expected = *i & ~(*j);
1746 CHECK_EQ(expected, bt.call(*i, *j));
1751 RawMachineAssemblerTester<int32_t> m;
1752 Int32BinopTester bt(&m);
1753 bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
1754 FOR_UINT32_INPUTS(i) {
1755 FOR_UINT32_INPUTS(j) {
1756 int32_t expected = ~(*i) & *j;
1757 CHECK_EQ(expected, bt.call(*i, *j));
1764 TEST(RunWord32AndAndWord32ShlP) {
1766 RawMachineAssemblerTester<int32_t> m;
1767 Uint32BinopTester bt(&m);
1769 m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
1770 FOR_UINT32_INPUTS(i) {
1771 FOR_UINT32_INPUTS(j) {
1772 uint32_t expected = *i << (*j & 0x1f);
1773 CHECK_EQ(expected, bt.call(*i, *j));
1778 RawMachineAssemblerTester<int32_t> m;
1779 Uint32BinopTester bt(&m);
1781 m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
1782 FOR_UINT32_INPUTS(i) {
1783 FOR_UINT32_INPUTS(j) {
1784 uint32_t expected = *i << (0x1f & *j);
1785 CHECK_EQ(expected, bt.call(*i, *j));
1792 TEST(RunWord32AndAndWord32ShrP) {
1794 RawMachineAssemblerTester<int32_t> m;
1795 Uint32BinopTester bt(&m);
1797 m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
1798 FOR_UINT32_INPUTS(i) {
1799 FOR_UINT32_INPUTS(j) {
1800 uint32_t expected = *i >> (*j & 0x1f);
1801 CHECK_EQ(expected, bt.call(*i, *j));
1806 RawMachineAssemblerTester<int32_t> m;
1807 Uint32BinopTester bt(&m);
1809 m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
1810 FOR_UINT32_INPUTS(i) {
1811 FOR_UINT32_INPUTS(j) {
1812 uint32_t expected = *i >> (0x1f & *j);
1813 CHECK_EQ(expected, bt.call(*i, *j));
1820 TEST(RunWord32AndAndWord32SarP) {
1822 RawMachineAssemblerTester<int32_t> m;
1823 Int32BinopTester bt(&m);
1825 m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
1826 FOR_INT32_INPUTS(i) {
1827 FOR_INT32_INPUTS(j) {
1828 int32_t expected = *i >> (*j & 0x1f);
1829 CHECK_EQ(expected, bt.call(*i, *j));
1834 RawMachineAssemblerTester<int32_t> m;
1835 Int32BinopTester bt(&m);
1837 m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
1838 FOR_INT32_INPUTS(i) {
1839 FOR_INT32_INPUTS(j) {
1840 int32_t expected = *i >> (0x1f & *j);
1841 CHECK_EQ(expected, bt.call(*i, *j));
1848 TEST(RunWord32AndImm) {
1850 FOR_UINT32_INPUTS(i) {
1851 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1852 m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
1853 FOR_UINT32_INPUTS(j) {
1854 uint32_t expected = *i & *j;
1855 CHECK_EQ(expected, m.Call(*j));
1860 FOR_UINT32_INPUTS(i) {
1861 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
1862 m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
1863 FOR_UINT32_INPUTS(j) {
1864 uint32_t expected = *i & ~(*j);
1865 CHECK_EQ(expected, m.Call(*j));
1872 TEST(RunWord32AndInBranch) {
1873 static const int constant = 987654321;
1875 RawMachineAssemblerTester<int32_t> m;
1876 Int32BinopTester bt(&m);
1877 MLabel blocka, blockb;
1879 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
1882 bt.AddReturn(m.Int32Constant(constant));
1884 bt.AddReturn(m.Int32Constant(0 - constant));
1885 FOR_UINT32_INPUTS(i) {
1886 FOR_UINT32_INPUTS(j) {
1887 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
1888 CHECK_EQ(expected, bt.call(*i, *j));
1893 RawMachineAssemblerTester<int32_t> m;
1894 Int32BinopTester bt(&m);
1895 MLabel blocka, blockb;
1897 m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
1900 bt.AddReturn(m.Int32Constant(constant));
1902 bt.AddReturn(m.Int32Constant(0 - constant));
1903 FOR_UINT32_INPUTS(i) {
1904 FOR_UINT32_INPUTS(j) {
1905 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
1906 CHECK_EQ(expected, bt.call(*i, *j));
1911 FOR_UINT32_INPUTS(i) {
1912 RawMachineAssemblerTester<int32_t> m(kMachUint32);
1913 MLabel blocka, blockb;
1914 m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
1915 m.Int32Constant(0)),
1918 m.Return(m.Int32Constant(constant));
1920 m.Return(m.Int32Constant(0 - constant));
1921 FOR_UINT32_INPUTS(j) {
1922 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
1923 CHECK_EQ(expected, m.Call(*j));
1928 FOR_UINT32_INPUTS(i) {
1929 RawMachineAssemblerTester<int32_t> m(kMachUint32);
1930 MLabel blocka, blockb;
1932 m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
1933 m.Int32Constant(0)),
1936 m.Return(m.Int32Constant(constant));
1938 m.Return(m.Int32Constant(0 - constant));
1939 FOR_UINT32_INPUTS(j) {
1940 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
1941 CHECK_EQ(expected, m.Call(*j));
1946 RawMachineAssemblerTester<void> m;
1947 const Operator* shops[] = {m.machine()->Word32Sar(),
1948 m.machine()->Word32Shl(),
1949 m.machine()->Word32Shr()};
1950 for (size_t n = 0; n < arraysize(shops); n++) {
1951 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
1953 MLabel blocka, blockb;
1954 m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
1955 m.NewNode(shops[n], m.Parameter(1),
1957 m.Int32Constant(0)),
1960 m.Return(m.Int32Constant(constant));
1962 m.Return(m.Int32Constant(0 - constant));
1963 FOR_UINT32_INPUTS(i) {
1964 FOR_INT32_INPUTS(j) {
1965 FOR_UINT32_SHIFTS(shift) {
1967 switch (shops[n]->opcode()) {
1970 case IrOpcode::kWord32Sar:
1971 right = *j >> shift;
1973 case IrOpcode::kWord32Shl:
1974 right = *j << shift;
1976 case IrOpcode::kWord32Shr:
1977 right = static_cast<uint32_t>(*j) >> shift;
1980 int32_t expected = ((*i & right) == 0) ? constant : 0 - constant;
1981 CHECK_EQ(expected, m.Call(*i, *j, shift));
1990 TEST(RunWord32AndInComparison) {
1992 RawMachineAssemblerTester<int32_t> m;
1993 Uint32BinopTester bt(&m);
1995 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)));
1996 FOR_UINT32_INPUTS(i) {
1997 FOR_UINT32_INPUTS(j) {
1998 uint32_t expected = (*i & *j) == 0;
1999 CHECK_EQ(expected, bt.call(*i, *j));
2004 RawMachineAssemblerTester<int32_t> m;
2005 Uint32BinopTester bt(&m);
2007 m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1)));
2008 FOR_UINT32_INPUTS(i) {
2009 FOR_UINT32_INPUTS(j) {
2010 uint32_t expected = (*i & *j) == 0;
2011 CHECK_EQ(expected, bt.call(*i, *j));
2016 FOR_UINT32_INPUTS(i) {
2017 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2018 m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2019 m.Int32Constant(0)));
2020 FOR_UINT32_INPUTS(j) {
2021 uint32_t expected = (*i & *j) == 0;
2022 CHECK_EQ(expected, m.Call(*j));
2027 FOR_UINT32_INPUTS(i) {
2028 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2029 m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
2030 m.Int32Constant(0)));
2031 FOR_UINT32_INPUTS(j) {
2032 uint32_t expected = (*j & *i) == 0;
2033 CHECK_EQ(expected, m.Call(*j));
2040 TEST(RunWord32OrP) {
2042 RawMachineAssemblerTester<int32_t> m;
2043 Uint32BinopTester bt(&m);
2044 bt.AddReturn(m.Word32Or(bt.param0, bt.param1));
2045 FOR_UINT32_INPUTS(i) {
2046 FOR_UINT32_INPUTS(j) {
2047 uint32_t expected = *i | *j;
2048 CHECK_EQ(expected, bt.call(*i, *j));
2053 RawMachineAssemblerTester<int32_t> m;
2054 Uint32BinopTester bt(&m);
2055 bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1)));
2056 FOR_UINT32_INPUTS(i) {
2057 FOR_UINT32_INPUTS(j) {
2058 uint32_t expected = *i | ~(*j);
2059 CHECK_EQ(expected, bt.call(*i, *j));
2064 RawMachineAssemblerTester<int32_t> m;
2065 Uint32BinopTester bt(&m);
2066 bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1));
2067 FOR_UINT32_INPUTS(i) {
2068 FOR_UINT32_INPUTS(j) {
2069 uint32_t expected = ~(*i) | *j;
2070 CHECK_EQ(expected, bt.call(*i, *j));
2077 TEST(RunWord32OrImm) {
2079 FOR_UINT32_INPUTS(i) {
2080 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2081 m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
2082 FOR_UINT32_INPUTS(j) {
2083 uint32_t expected = *i | *j;
2084 CHECK_EQ(expected, m.Call(*j));
2089 FOR_UINT32_INPUTS(i) {
2090 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2091 m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2092 FOR_UINT32_INPUTS(j) {
2093 uint32_t expected = *i | ~(*j);
2094 CHECK_EQ(expected, m.Call(*j));
2101 TEST(RunWord32OrInBranch) {
2102 static const int constant = 987654321;
2104 RawMachineAssemblerTester<int32_t> m;
2105 Int32BinopTester bt(&m);
2106 MLabel blocka, blockb;
2108 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2111 bt.AddReturn(m.Int32Constant(constant));
2113 bt.AddReturn(m.Int32Constant(0 - constant));
2114 FOR_INT32_INPUTS(i) {
2115 FOR_INT32_INPUTS(j) {
2116 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2117 CHECK_EQ(expected, bt.call(*i, *j));
2122 RawMachineAssemblerTester<int32_t> m;
2123 Int32BinopTester bt(&m);
2124 MLabel blocka, blockb;
2126 m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2129 bt.AddReturn(m.Int32Constant(constant));
2131 bt.AddReturn(m.Int32Constant(0 - constant));
2132 FOR_INT32_INPUTS(i) {
2133 FOR_INT32_INPUTS(j) {
2134 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2135 CHECK_EQ(expected, bt.call(*i, *j));
2140 FOR_INT32_INPUTS(i) {
2141 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2142 MLabel blocka, blockb;
2143 m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2144 m.Int32Constant(0)),
2147 m.Return(m.Int32Constant(constant));
2149 m.Return(m.Int32Constant(0 - constant));
2150 FOR_INT32_INPUTS(j) {
2151 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2152 CHECK_EQ(expected, m.Call(*j));
2157 FOR_INT32_INPUTS(i) {
2158 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2159 MLabel blocka, blockb;
2160 m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2161 m.Int32Constant(0)),
2164 m.Return(m.Int32Constant(constant));
2166 m.Return(m.Int32Constant(0 - constant));
2167 FOR_INT32_INPUTS(j) {
2168 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2169 CHECK_EQ(expected, m.Call(*j));
2174 RawMachineAssemblerTester<void> m;
2175 const Operator* shops[] = {m.machine()->Word32Sar(),
2176 m.machine()->Word32Shl(),
2177 m.machine()->Word32Shr()};
2178 for (size_t n = 0; n < arraysize(shops); n++) {
2179 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
2181 MLabel blocka, blockb;
2182 m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
2183 m.NewNode(shops[n], m.Parameter(1),
2185 m.Int32Constant(0)),
2188 m.Return(m.Int32Constant(constant));
2190 m.Return(m.Int32Constant(0 - constant));
2191 FOR_UINT32_INPUTS(i) {
2192 FOR_INT32_INPUTS(j) {
2193 FOR_UINT32_SHIFTS(shift) {
2195 switch (shops[n]->opcode()) {
2198 case IrOpcode::kWord32Sar:
2199 right = *j >> shift;
2201 case IrOpcode::kWord32Shl:
2202 right = *j << shift;
2204 case IrOpcode::kWord32Shr:
2205 right = static_cast<uint32_t>(*j) >> shift;
2208 int32_t expected = ((*i | right) == 0) ? constant : 0 - constant;
2209 CHECK_EQ(expected, m.Call(*i, *j, shift));
2218 TEST(RunWord32OrInComparison) {
2220 RawMachineAssemblerTester<int32_t> m;
2221 Int32BinopTester bt(&m);
2223 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
2224 FOR_UINT32_INPUTS(i) {
2225 FOR_UINT32_INPUTS(j) {
2226 int32_t expected = (*i | *j) == 0;
2227 CHECK_EQ(expected, bt.call(*i, *j));
2232 RawMachineAssemblerTester<int32_t> m;
2233 Int32BinopTester bt(&m);
2235 m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
2236 FOR_UINT32_INPUTS(i) {
2237 FOR_UINT32_INPUTS(j) {
2238 int32_t expected = (*i | *j) == 0;
2239 CHECK_EQ(expected, bt.call(*i, *j));
2244 FOR_UINT32_INPUTS(i) {
2245 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2246 m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2247 m.Int32Constant(0)));
2248 FOR_UINT32_INPUTS(j) {
2249 uint32_t expected = (*i | *j) == 0;
2250 CHECK_EQ(expected, m.Call(*j));
2255 FOR_UINT32_INPUTS(i) {
2256 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2257 m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
2258 m.Int32Constant(0)));
2259 FOR_UINT32_INPUTS(j) {
2260 uint32_t expected = (*j | *i) == 0;
2261 CHECK_EQ(expected, m.Call(*j));
2268 TEST(RunWord32XorP) {
2270 FOR_UINT32_INPUTS(i) {
2271 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2272 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
2273 FOR_UINT32_INPUTS(j) {
2274 uint32_t expected = *i ^ *j;
2275 CHECK_EQ(expected, m.Call(*j));
2280 RawMachineAssemblerTester<int32_t> m;
2281 Uint32BinopTester bt(&m);
2282 bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
2283 FOR_UINT32_INPUTS(i) {
2284 FOR_UINT32_INPUTS(j) {
2285 uint32_t expected = *i ^ *j;
2286 CHECK_EQ(expected, bt.call(*i, *j));
2291 RawMachineAssemblerTester<int32_t> m;
2292 Int32BinopTester bt(&m);
2293 bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1)));
2294 FOR_INT32_INPUTS(i) {
2295 FOR_INT32_INPUTS(j) {
2296 int32_t expected = *i ^ ~(*j);
2297 CHECK_EQ(expected, bt.call(*i, *j));
2302 RawMachineAssemblerTester<int32_t> m;
2303 Int32BinopTester bt(&m);
2304 bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1));
2305 FOR_INT32_INPUTS(i) {
2306 FOR_INT32_INPUTS(j) {
2307 int32_t expected = ~(*i) ^ *j;
2308 CHECK_EQ(expected, bt.call(*i, *j));
2313 FOR_UINT32_INPUTS(i) {
2314 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2315 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2316 FOR_UINT32_INPUTS(j) {
2317 uint32_t expected = *i ^ ~(*j);
2318 CHECK_EQ(expected, m.Call(*j));
2325 TEST(RunWord32XorInBranch) {
2326 static const uint32_t constant = 987654321;
2328 RawMachineAssemblerTester<int32_t> m;
2329 Uint32BinopTester bt(&m);
2330 MLabel blocka, blockb;
2332 m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2335 bt.AddReturn(m.Int32Constant(constant));
2337 bt.AddReturn(m.Int32Constant(0 - constant));
2338 FOR_UINT32_INPUTS(i) {
2339 FOR_UINT32_INPUTS(j) {
2340 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
2341 CHECK_EQ(expected, bt.call(*i, *j));
2346 RawMachineAssemblerTester<int32_t> m;
2347 Uint32BinopTester bt(&m);
2348 MLabel blocka, blockb;
2350 m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2353 bt.AddReturn(m.Int32Constant(constant));
2355 bt.AddReturn(m.Int32Constant(0 - constant));
2356 FOR_UINT32_INPUTS(i) {
2357 FOR_UINT32_INPUTS(j) {
2358 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
2359 CHECK_EQ(expected, bt.call(*i, *j));
2364 FOR_UINT32_INPUTS(i) {
2365 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2366 MLabel blocka, blockb;
2367 m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
2368 m.Int32Constant(0)),
2371 m.Return(m.Int32Constant(constant));
2373 m.Return(m.Int32Constant(0 - constant));
2374 FOR_UINT32_INPUTS(j) {
2375 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
2376 CHECK_EQ(expected, m.Call(*j));
2381 FOR_UINT32_INPUTS(i) {
2382 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2383 MLabel blocka, blockb;
2385 m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
2386 m.Int32Constant(0)),
2389 m.Return(m.Int32Constant(constant));
2391 m.Return(m.Int32Constant(0 - constant));
2392 FOR_UINT32_INPUTS(j) {
2393 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
2394 CHECK_EQ(expected, m.Call(*j));
2399 RawMachineAssemblerTester<void> m;
2400 const Operator* shops[] = {m.machine()->Word32Sar(),
2401 m.machine()->Word32Shl(),
2402 m.machine()->Word32Shr()};
2403 for (size_t n = 0; n < arraysize(shops); n++) {
2404 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32,
2406 MLabel blocka, blockb;
2407 m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
2408 m.NewNode(shops[n], m.Parameter(1),
2410 m.Int32Constant(0)),
2413 m.Return(m.Int32Constant(constant));
2415 m.Return(m.Int32Constant(0 - constant));
2416 FOR_UINT32_INPUTS(i) {
2417 FOR_INT32_INPUTS(j) {
2418 FOR_UINT32_SHIFTS(shift) {
2420 switch (shops[n]->opcode()) {
2423 case IrOpcode::kWord32Sar:
2424 right = *j >> shift;
2426 case IrOpcode::kWord32Shl:
2427 right = *j << shift;
2429 case IrOpcode::kWord32Shr:
2430 right = static_cast<uint32_t>(*j) >> shift;
2433 int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant;
2434 CHECK_EQ(expected, m.Call(*i, *j, shift));
2443 TEST(RunWord32ShlP) {
2445 FOR_UINT32_SHIFTS(shift) {
2446 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2447 m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
2448 FOR_UINT32_INPUTS(j) {
2449 uint32_t expected = *j << shift;
2450 CHECK_EQ(expected, m.Call(*j));
2455 RawMachineAssemblerTester<int32_t> m;
2456 Uint32BinopTester bt(&m);
2457 bt.AddReturn(m.Word32Shl(bt.param0, bt.param1));
2458 FOR_UINT32_INPUTS(i) {
2459 FOR_UINT32_SHIFTS(shift) {
2460 uint32_t expected = *i << shift;
2461 CHECK_EQ(expected, bt.call(*i, shift));
2468 TEST(RunWord32ShlInComparison) {
2470 RawMachineAssemblerTester<int32_t> m;
2471 Uint32BinopTester bt(&m);
2473 m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0)));
2474 FOR_UINT32_INPUTS(i) {
2475 FOR_UINT32_SHIFTS(shift) {
2476 uint32_t expected = 0 == (*i << shift);
2477 CHECK_EQ(expected, bt.call(*i, shift));
2482 RawMachineAssemblerTester<int32_t> m;
2483 Uint32BinopTester bt(&m);
2485 m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1)));
2486 FOR_UINT32_INPUTS(i) {
2487 FOR_UINT32_SHIFTS(shift) {
2488 uint32_t expected = 0 == (*i << shift);
2489 CHECK_EQ(expected, bt.call(*i, shift));
2494 FOR_UINT32_SHIFTS(shift) {
2495 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2497 m.Word32Equal(m.Int32Constant(0),
2498 m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))));
2499 FOR_UINT32_INPUTS(i) {
2500 uint32_t expected = 0 == (*i << shift);
2501 CHECK_EQ(expected, m.Call(*i));
2506 FOR_UINT32_SHIFTS(shift) {
2507 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2509 m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)),
2510 m.Int32Constant(0)));
2511 FOR_UINT32_INPUTS(i) {
2512 uint32_t expected = 0 == (*i << shift);
2513 CHECK_EQ(expected, m.Call(*i));
2520 TEST(RunWord32ShrP) {
2522 FOR_UINT32_SHIFTS(shift) {
2523 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2524 m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
2525 FOR_UINT32_INPUTS(j) {
2526 uint32_t expected = *j >> shift;
2527 CHECK_EQ(expected, m.Call(*j));
2532 RawMachineAssemblerTester<int32_t> m;
2533 Uint32BinopTester bt(&m);
2534 bt.AddReturn(m.Word32Shr(bt.param0, bt.param1));
2535 FOR_UINT32_INPUTS(i) {
2536 FOR_UINT32_SHIFTS(shift) {
2537 uint32_t expected = *i >> shift;
2538 CHECK_EQ(expected, bt.call(*i, shift));
2541 CHECK_EQ(0x00010000u, bt.call(0x80000000, 15));
2546 TEST(RunWord32ShrInComparison) {
2548 RawMachineAssemblerTester<int32_t> m;
2549 Uint32BinopTester bt(&m);
2551 m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0)));
2552 FOR_UINT32_INPUTS(i) {
2553 FOR_UINT32_SHIFTS(shift) {
2554 uint32_t expected = 0 == (*i >> shift);
2555 CHECK_EQ(expected, bt.call(*i, shift));
2560 RawMachineAssemblerTester<int32_t> m;
2561 Uint32BinopTester bt(&m);
2563 m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1)));
2564 FOR_UINT32_INPUTS(i) {
2565 FOR_UINT32_SHIFTS(shift) {
2566 uint32_t expected = 0 == (*i >> shift);
2567 CHECK_EQ(expected, bt.call(*i, shift));
2572 FOR_UINT32_SHIFTS(shift) {
2573 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2575 m.Word32Equal(m.Int32Constant(0),
2576 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
2577 FOR_UINT32_INPUTS(i) {
2578 uint32_t expected = 0 == (*i >> shift);
2579 CHECK_EQ(expected, m.Call(*i));
2584 FOR_UINT32_SHIFTS(shift) {
2585 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2587 m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
2588 m.Int32Constant(0)));
2589 FOR_UINT32_INPUTS(i) {
2590 uint32_t expected = 0 == (*i >> shift);
2591 CHECK_EQ(expected, m.Call(*i));
2598 TEST(RunWord32SarP) {
2600 FOR_INT32_SHIFTS(shift) {
2601 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2602 m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
2603 FOR_INT32_INPUTS(j) {
2604 int32_t expected = *j >> shift;
2605 CHECK_EQ(expected, m.Call(*j));
2610 RawMachineAssemblerTester<int32_t> m;
2611 Int32BinopTester bt(&m);
2612 bt.AddReturn(m.Word32Sar(bt.param0, bt.param1));
2613 FOR_INT32_INPUTS(i) {
2614 FOR_INT32_SHIFTS(shift) {
2615 int32_t expected = *i >> shift;
2616 CHECK_EQ(expected, bt.call(*i, shift));
2619 CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15));
2624 TEST(RunWord32SarInComparison) {
2626 RawMachineAssemblerTester<int32_t> m;
2627 Int32BinopTester bt(&m);
2629 m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0)));
2630 FOR_INT32_INPUTS(i) {
2631 FOR_INT32_SHIFTS(shift) {
2632 int32_t expected = 0 == (*i >> shift);
2633 CHECK_EQ(expected, bt.call(*i, shift));
2638 RawMachineAssemblerTester<int32_t> m;
2639 Int32BinopTester bt(&m);
2641 m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1)));
2642 FOR_INT32_INPUTS(i) {
2643 FOR_INT32_SHIFTS(shift) {
2644 int32_t expected = 0 == (*i >> shift);
2645 CHECK_EQ(expected, bt.call(*i, shift));
2650 FOR_INT32_SHIFTS(shift) {
2651 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2653 m.Word32Equal(m.Int32Constant(0),
2654 m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))));
2655 FOR_INT32_INPUTS(i) {
2656 int32_t expected = 0 == (*i >> shift);
2657 CHECK_EQ(expected, m.Call(*i));
2662 FOR_INT32_SHIFTS(shift) {
2663 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2665 m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)),
2666 m.Int32Constant(0)));
2667 FOR_INT32_INPUTS(i) {
2668 int32_t expected = 0 == (*i >> shift);
2669 CHECK_EQ(expected, m.Call(*i));
2676 TEST(RunWord32RorP) {
2678 FOR_UINT32_SHIFTS(shift) {
2679 RawMachineAssemblerTester<int32_t> m(kMachUint32);
2680 m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)));
2681 FOR_UINT32_INPUTS(j) {
2682 int32_t expected = bits::RotateRight32(*j, shift);
2683 CHECK_EQ(expected, m.Call(*j));
2688 RawMachineAssemblerTester<int32_t> m;
2689 Uint32BinopTester bt(&m);
2690 bt.AddReturn(m.Word32Ror(bt.param0, bt.param1));
2691 FOR_UINT32_INPUTS(i) {
2692 FOR_UINT32_SHIFTS(shift) {
2693 uint32_t expected = bits::RotateRight32(*i, shift);
2694 CHECK_EQ(expected, bt.call(*i, shift));
2701 TEST(RunWord32RorInComparison) {
2703 RawMachineAssemblerTester<int32_t> m;
2704 Uint32BinopTester bt(&m);
2706 m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0)));
2707 FOR_UINT32_INPUTS(i) {
2708 FOR_UINT32_SHIFTS(shift) {
2709 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
2710 CHECK_EQ(expected, bt.call(*i, shift));
2715 RawMachineAssemblerTester<int32_t> m;
2716 Uint32BinopTester bt(&m);
2718 m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1)));
2719 FOR_UINT32_INPUTS(i) {
2720 FOR_UINT32_SHIFTS(shift) {
2721 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
2722 CHECK_EQ(expected, bt.call(*i, shift));
2727 FOR_UINT32_SHIFTS(shift) {
2728 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2730 m.Word32Equal(m.Int32Constant(0),
2731 m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))));
2732 FOR_UINT32_INPUTS(i) {
2733 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
2734 CHECK_EQ(expected, m.Call(*i));
2739 FOR_UINT32_SHIFTS(shift) {
2740 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
2742 m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)),
2743 m.Int32Constant(0)));
2744 FOR_UINT32_INPUTS(i) {
2745 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
2746 CHECK_EQ(expected, m.Call(*i));
2753 TEST(RunWord32NotP) {
2754 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2755 m.Return(m.Word32Not(m.Parameter(0)));
2756 FOR_INT32_INPUTS(i) {
2757 int expected = ~(*i);
2758 CHECK_EQ(expected, m.Call(*i));
2763 TEST(RunInt32NegP) {
2764 RawMachineAssemblerTester<int32_t> m(kMachInt32);
2765 m.Return(m.Int32Neg(m.Parameter(0)));
2766 FOR_INT32_INPUTS(i) {
2768 CHECK_EQ(expected, m.Call(*i));
2773 TEST(RunWord32EqualAndWord32SarP) {
2775 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachUint32);
2776 m.Return(m.Word32Equal(m.Parameter(0),
2777 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
2778 FOR_INT32_INPUTS(i) {
2779 FOR_INT32_INPUTS(j) {
2780 FOR_UINT32_SHIFTS(shift) {
2781 int32_t expected = (*i == (*j >> shift));
2782 CHECK_EQ(expected, m.Call(*i, *j, shift));
2788 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachInt32);
2789 m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
2791 FOR_INT32_INPUTS(i) {
2792 FOR_UINT32_SHIFTS(shift) {
2793 FOR_INT32_INPUTS(k) {
2794 int32_t expected = ((*i >> shift) == *k);
2795 CHECK_EQ(expected, m.Call(*i, shift, *k));
2803 TEST(RunWord32EqualAndWord32ShlP) {
2805 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
2806 m.Return(m.Word32Equal(m.Parameter(0),
2807 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
2808 FOR_UINT32_INPUTS(i) {
2809 FOR_UINT32_INPUTS(j) {
2810 FOR_UINT32_SHIFTS(shift) {
2811 int32_t expected = (*i == (*j << shift));
2812 CHECK_EQ(expected, m.Call(*i, *j, shift));
2818 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
2819 m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
2821 FOR_UINT32_INPUTS(i) {
2822 FOR_UINT32_SHIFTS(shift) {
2823 FOR_UINT32_INPUTS(k) {
2824 int32_t expected = ((*i << shift) == *k);
2825 CHECK_EQ(expected, m.Call(*i, shift, *k));
2833 TEST(RunWord32EqualAndWord32ShrP) {
2835 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
2836 m.Return(m.Word32Equal(m.Parameter(0),
2837 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
2838 FOR_UINT32_INPUTS(i) {
2839 FOR_UINT32_INPUTS(j) {
2840 FOR_UINT32_SHIFTS(shift) {
2841 int32_t expected = (*i == (*j >> shift));
2842 CHECK_EQ(expected, m.Call(*i, *j, shift));
2848 RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32);
2849 m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
2851 FOR_UINT32_INPUTS(i) {
2852 FOR_UINT32_SHIFTS(shift) {
2853 FOR_UINT32_INPUTS(k) {
2854 int32_t expected = ((*i >> shift) == *k);
2855 CHECK_EQ(expected, m.Call(*i, shift, *k));
2863 TEST(RunDeadNodes) {
2864 for (int i = 0; true; i++) {
2865 RawMachineAssemblerTester<int32_t> m(i == 5 ? kMachInt32 : kMachNone);
2866 int constant = 0x55 + i;
2869 m.Int32Constant(44);
2872 m.StringConstant("unused");
2875 m.NumberConstant(11.1);
2878 m.PointerConstant(&constant);
2881 m.LoadFromPointer(&constant, kMachInt32);
2889 m.Return(m.Int32Constant(constant));
2891 CHECK_EQ(constant, m.Call());
2893 CHECK_EQ(constant, m.Call(0));
2899 TEST(RunDeadInt32Binops) {
2900 RawMachineAssemblerTester<int32_t> m;
2902 const Operator* kOps[] = {
2903 m.machine()->Word32And(), m.machine()->Word32Or(),
2904 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
2905 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
2906 m.machine()->Word32Ror(), m.machine()->Word32Equal(),
2907 m.machine()->Int32Add(), m.machine()->Int32Sub(),
2908 m.machine()->Int32Mul(), m.machine()->Int32MulHigh(),
2909 m.machine()->Int32Div(), m.machine()->Uint32Div(),
2910 m.machine()->Int32Mod(), m.machine()->Uint32Mod(),
2911 m.machine()->Uint32MulHigh(), m.machine()->Int32LessThan(),
2912 m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
2913 m.machine()->Uint32LessThanOrEqual()};
2915 for (size_t i = 0; i < arraysize(kOps); ++i) {
2916 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
2917 int32_t constant = static_cast<int32_t>(0x55555 + i);
2918 m.NewNode(kOps[i], m.Parameter(0), m.Parameter(1));
2919 m.Return(m.Int32Constant(constant));
2921 CHECK_EQ(constant, m.Call(1, 1));
2926 template <typename Type>
2927 static void RunLoadImmIndex(MachineType rep) {
2928 const int kNumElems = 3;
2929 Type buffer[kNumElems];
2931 // initialize the buffer with raw data.
2932 byte* raw = reinterpret_cast<byte*>(buffer);
2933 for (size_t i = 0; i < sizeof(buffer); i++) {
2934 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
2937 // Test with various large and small offsets.
2938 for (int offset = -1; offset <= 200000; offset *= -5) {
2939 for (int i = 0; i < kNumElems; i++) {
2940 RawMachineAssemblerTester<Type> m;
2941 Node* base = m.PointerConstant(buffer - offset);
2942 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
2943 m.Return(m.Load(rep, base, index));
2945 Type expected = buffer[i];
2946 Type actual = m.Call();
2947 CHECK(expected == actual);
2953 TEST(RunLoadImmIndex) {
2954 RunLoadImmIndex<int8_t>(kMachInt8);
2955 RunLoadImmIndex<uint8_t>(kMachUint8);
2956 RunLoadImmIndex<int16_t>(kMachInt16);
2957 RunLoadImmIndex<uint16_t>(kMachUint16);
2958 RunLoadImmIndex<int32_t>(kMachInt32);
2959 RunLoadImmIndex<uint32_t>(kMachUint32);
2960 RunLoadImmIndex<int32_t*>(kMachAnyTagged);
2962 // TODO(titzer): test kRepBit loads
2963 // TODO(titzer): test kMachFloat64 loads
2964 // TODO(titzer): test various indexing modes.
2968 template <typename CType>
2969 static void RunLoadStore(MachineType rep) {
2970 const int kNumElems = 4;
2971 CType buffer[kNumElems];
2973 for (int32_t x = 0; x < kNumElems; x++) {
2974 int32_t y = kNumElems - x - 1;
2975 // initialize the buffer with raw data.
2976 byte* raw = reinterpret_cast<byte*>(buffer);
2977 for (size_t i = 0; i < sizeof(buffer); i++) {
2978 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
2981 RawMachineAssemblerTester<int32_t> m;
2982 int32_t OK = 0x29000 + x;
2983 Node* base = m.PointerConstant(buffer);
2984 Node* index0 = m.Int32Constant(x * sizeof(buffer[0]));
2985 Node* load = m.Load(rep, base, index0);
2986 Node* index1 = m.Int32Constant(y * sizeof(buffer[0]));
2987 m.Store(rep, base, index1, load);
2988 m.Return(m.Int32Constant(OK));
2990 CHECK(buffer[x] != buffer[y]);
2991 CHECK_EQ(OK, m.Call());
2992 CHECK(buffer[x] == buffer[y]);
2997 TEST(RunLoadStore) {
2998 RunLoadStore<int8_t>(kMachInt8);
2999 RunLoadStore<uint8_t>(kMachUint8);
3000 RunLoadStore<int16_t>(kMachInt16);
3001 RunLoadStore<uint16_t>(kMachUint16);
3002 RunLoadStore<int32_t>(kMachInt32);
3003 RunLoadStore<uint32_t>(kMachUint32);
3004 RunLoadStore<void*>(kMachAnyTagged);
3005 RunLoadStore<float>(kMachFloat32);
3006 RunLoadStore<double>(kMachFloat64);
3010 TEST(RunFloat64Binop) {
3011 RawMachineAssemblerTester<int32_t> m;
3014 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3015 m.machine()->Float64Mul(), m.machine()->Float64Div(),
3016 m.machine()->Float64Mod(), NULL};
3018 double inf = V8_INFINITY;
3019 const Operator* inputs[] = {
3020 m.common()->Float64Constant(0), m.common()->Float64Constant(1),
3021 m.common()->Float64Constant(1), m.common()->Float64Constant(0),
3022 m.common()->Float64Constant(0), m.common()->Float64Constant(-1),
3023 m.common()->Float64Constant(-1), m.common()->Float64Constant(0),
3024 m.common()->Float64Constant(0.22), m.common()->Float64Constant(-1.22),
3025 m.common()->Float64Constant(-1.22), m.common()->Float64Constant(0.22),
3026 m.common()->Float64Constant(inf), m.common()->Float64Constant(0.22),
3027 m.common()->Float64Constant(inf), m.common()->Float64Constant(-inf),
3030 for (int i = 0; ops[i] != NULL; i++) {
3031 for (int j = 0; inputs[j] != NULL; j += 2) {
3032 RawMachineAssemblerTester<int32_t> m;
3033 Node* a = m.NewNode(inputs[j]);
3034 Node* b = m.NewNode(inputs[j + 1]);
3035 Node* binop = m.NewNode(ops[i], a, b);
3036 Node* base = m.PointerConstant(&result);
3037 Node* zero = m.Int32Constant(0);
3038 m.Store(kMachFloat64, base, zero, binop);
3039 m.Return(m.Int32Constant(i + j));
3040 CHECK_EQ(i + j, m.Call());
3046 TEST(RunDeadFloat64Binops) {
3047 RawMachineAssemblerTester<int32_t> m;
3049 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3050 m.machine()->Float64Mul(), m.machine()->Float64Div(),
3051 m.machine()->Float64Mod(), NULL};
3053 for (int i = 0; ops[i] != NULL; i++) {
3054 RawMachineAssemblerTester<int32_t> m;
3055 int constant = 0x53355 + i;
3056 m.NewNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
3057 m.Return(m.Int32Constant(constant));
3058 CHECK_EQ(constant, m.Call());
3063 TEST(RunFloat64AddP) {
3064 RawMachineAssemblerTester<int32_t> m;
3065 Float64BinopTester bt(&m);
3067 bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
3069 FOR_FLOAT64_INPUTS(pl) {
3070 FOR_FLOAT64_INPUTS(pr) {
3071 double expected = *pl + *pr;
3072 CheckDoubleEq(expected, bt.call(*pl, *pr));
3078 TEST(RunFloat64SubP) {
3079 RawMachineAssemblerTester<int32_t> m;
3080 Float64BinopTester bt(&m);
3082 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
3084 FOR_FLOAT64_INPUTS(pl) {
3085 FOR_FLOAT64_INPUTS(pr) {
3086 double expected = *pl - *pr;
3087 CheckDoubleEq(expected, bt.call(*pl, *pr));
3093 TEST(RunFloat64SubImm1) {
3095 double output = 0.0;
3097 FOR_FLOAT64_INPUTS(i) {
3098 RawMachineAssemblerTester<int32_t> m;
3099 Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
3100 Node* t1 = m.Float64Sub(m.Float64Constant(*i), t0);
3101 m.StoreToPointer(&output, kMachFloat64, t1);
3102 m.Return(m.Int32Constant(0));
3103 FOR_FLOAT64_INPUTS(j) {
3105 double expected = *i - input;
3106 CHECK_EQ(0, m.Call());
3107 CheckDoubleEq(expected, output);
3113 TEST(RunFloat64SubImm2) {
3115 double output = 0.0;
3117 FOR_FLOAT64_INPUTS(i) {
3118 RawMachineAssemblerTester<int32_t> m;
3119 Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
3120 Node* t1 = m.Float64Sub(t0, m.Float64Constant(*i));
3121 m.StoreToPointer(&output, kMachFloat64, t1);
3122 m.Return(m.Int32Constant(0));
3123 FOR_FLOAT64_INPUTS(j) {
3125 double expected = input - *i;
3126 CHECK_EQ(0, m.Call());
3127 CheckDoubleEq(expected, output);
3133 TEST(RunFloat64MulP) {
3134 RawMachineAssemblerTester<int32_t> m;
3135 Float64BinopTester bt(&m);
3137 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
3139 FOR_FLOAT64_INPUTS(pl) {
3140 FOR_FLOAT64_INPUTS(pr) {
3141 double expected = *pl * *pr;
3142 CheckDoubleEq(expected, bt.call(*pl, *pr));
3148 TEST(RunFloat64MulAndFloat64AddP) {
3149 double input_a = 0.0;
3150 double input_b = 0.0;
3151 double input_c = 0.0;
3152 double output = 0.0;
3155 RawMachineAssemblerTester<int32_t> m;
3156 Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
3157 Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
3158 Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
3159 m.StoreToPointer(&output, kMachFloat64,
3160 m.Float64Add(m.Float64Mul(a, b), c));
3161 m.Return(m.Int32Constant(0));
3162 FOR_FLOAT64_INPUTS(i) {
3163 FOR_FLOAT64_INPUTS(j) {
3164 FOR_FLOAT64_INPUTS(k) {
3168 volatile double temp = input_a * input_b;
3169 volatile double expected = temp + input_c;
3170 CHECK_EQ(0, m.Call());
3171 CheckDoubleEq(expected, output);
3177 RawMachineAssemblerTester<int32_t> m;
3178 Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
3179 Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
3180 Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
3181 m.StoreToPointer(&output, kMachFloat64,
3182 m.Float64Add(a, m.Float64Mul(b, c)));
3183 m.Return(m.Int32Constant(0));
3184 FOR_FLOAT64_INPUTS(i) {
3185 FOR_FLOAT64_INPUTS(j) {
3186 FOR_FLOAT64_INPUTS(k) {
3190 volatile double temp = input_b * input_c;
3191 volatile double expected = input_a + temp;
3192 CHECK_EQ(0, m.Call());
3193 CheckDoubleEq(expected, output);
3201 TEST(RunFloat64MulAndFloat64SubP) {
3202 double input_a = 0.0;
3203 double input_b = 0.0;
3204 double input_c = 0.0;
3205 double output = 0.0;
3207 RawMachineAssemblerTester<int32_t> m;
3208 Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
3209 Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
3210 Node* c = m.LoadFromPointer(&input_c, kMachFloat64);
3211 m.StoreToPointer(&output, kMachFloat64, m.Float64Sub(a, m.Float64Mul(b, c)));
3212 m.Return(m.Int32Constant(0));
3214 FOR_FLOAT64_INPUTS(i) {
3215 FOR_FLOAT64_INPUTS(j) {
3216 FOR_FLOAT64_INPUTS(k) {
3220 volatile double temp = input_b * input_c;
3221 volatile double expected = input_a - temp;
3222 CHECK_EQ(0, m.Call());
3223 CheckDoubleEq(expected, output);
3230 TEST(RunFloat64MulImm) {
3232 double output = 0.0;
3235 FOR_FLOAT64_INPUTS(i) {
3236 RawMachineAssemblerTester<int32_t> m;
3237 Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
3238 Node* t1 = m.Float64Mul(m.Float64Constant(*i), t0);
3239 m.StoreToPointer(&output, kMachFloat64, t1);
3240 m.Return(m.Int32Constant(0));
3241 FOR_FLOAT64_INPUTS(j) {
3243 double expected = *i * input;
3244 CHECK_EQ(0, m.Call());
3245 CheckDoubleEq(expected, output);
3250 FOR_FLOAT64_INPUTS(i) {
3251 RawMachineAssemblerTester<int32_t> m;
3252 Node* t0 = m.LoadFromPointer(&input, kMachFloat64);
3253 Node* t1 = m.Float64Mul(t0, m.Float64Constant(*i));
3254 m.StoreToPointer(&output, kMachFloat64, t1);
3255 m.Return(m.Int32Constant(0));
3256 FOR_FLOAT64_INPUTS(j) {
3258 double expected = input * *i;
3259 CHECK_EQ(0, m.Call());
3260 CheckDoubleEq(expected, output);
3267 TEST(RunFloat64DivP) {
3268 RawMachineAssemblerTester<int32_t> m;
3269 Float64BinopTester bt(&m);
3271 bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
3273 FOR_FLOAT64_INPUTS(pl) {
3274 FOR_FLOAT64_INPUTS(pr) {
3275 double expected = *pl / *pr;
3276 CheckDoubleEq(expected, bt.call(*pl, *pr));
3282 TEST(RunFloat64ModP) {
3283 RawMachineAssemblerTester<int32_t> m;
3284 Float64BinopTester bt(&m);
3286 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
3288 FOR_FLOAT64_INPUTS(i) {
3289 FOR_FLOAT64_INPUTS(j) {
3290 double expected = modulo(*i, *j);
3291 double found = bt.call(*i, *j);
3292 CheckDoubleEq(expected, found);
3298 TEST(RunChangeInt32ToFloat64_A) {
3299 RawMachineAssemblerTester<int32_t> m;
3300 int32_t magic = 0x986234;
3303 Node* convert = m.ChangeInt32ToFloat64(m.Int32Constant(magic));
3304 m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(0),
3306 m.Return(m.Int32Constant(magic));
3308 CHECK_EQ(magic, m.Call());
3309 CHECK_EQ(static_cast<double>(magic), result);
3313 TEST(RunChangeInt32ToFloat64_B) {
3314 RawMachineAssemblerTester<int32_t> m(kMachInt32);
3317 Node* convert = m.ChangeInt32ToFloat64(m.Parameter(0));
3318 m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0),
3320 m.Return(m.Parameter(0));
3322 FOR_INT32_INPUTS(i) {
3323 int32_t expect = *i;
3324 CHECK_EQ(expect, m.Call(expect));
3325 CHECK_EQ(static_cast<double>(expect), output);
3330 TEST(RunChangeUint32ToFloat64_B) {
3331 RawMachineAssemblerTester<uint32_t> m(kMachUint32);
3334 Node* convert = m.ChangeUint32ToFloat64(m.Parameter(0));
3335 m.Store(kMachFloat64, m.PointerConstant(&output), m.Int32Constant(0),
3337 m.Return(m.Parameter(0));
3339 FOR_UINT32_INPUTS(i) {
3340 uint32_t expect = *i;
3341 CHECK_EQ(expect, m.Call(expect));
3342 CHECK_EQ(static_cast<double>(expect), output);
3347 TEST(RunChangeUint32ToFloat64_spilled) {
3348 RawMachineAssemblerTester<int32_t> m;
3349 const int kNumInputs = 32;
3350 int32_t magic = 0x786234;
3351 uint32_t input[kNumInputs];
3352 double result[kNumInputs];
3353 Node* input_node[kNumInputs];
3355 for (int i = 0; i < kNumInputs; i++) {
3357 m.Load(kMachUint32, m.PointerConstant(&input), m.Int32Constant(i * 4));
3360 for (int i = 0; i < kNumInputs; i++) {
3361 m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
3362 m.ChangeUint32ToFloat64(input_node[i]));
3365 m.Return(m.Int32Constant(magic));
3367 for (int i = 0; i < kNumInputs; i++) {
3371 CHECK_EQ(magic, m.Call());
3373 for (int i = 0; i < kNumInputs; i++) {
3374 CHECK_EQ(result[i], static_cast<double>(100 + i));
3379 TEST(RunChangeFloat64ToInt32_A) {
3380 RawMachineAssemblerTester<int32_t> m;
3381 int32_t magic = 0x786234;
3382 double input = 11.1;
3385 m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(0),
3386 m.ChangeFloat64ToInt32(m.Float64Constant(input)));
3387 m.Return(m.Int32Constant(magic));
3389 CHECK_EQ(magic, m.Call());
3390 CHECK_EQ(static_cast<int32_t>(input), result);
3394 TEST(RunChangeFloat64ToInt32_B) {
3395 RawMachineAssemblerTester<int32_t> m;
3400 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0));
3401 Node* convert = m.ChangeFloat64ToInt32(load);
3402 m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert);
3406 FOR_INT32_INPUTS(i) {
3408 int32_t expect = *i;
3409 CHECK_EQ(expect, m.Call());
3410 CHECK_EQ(expect, output);
3414 // Check various powers of 2.
3415 for (int32_t n = 1; n < 31; ++n) {
3418 int32_t expect = static_cast<int32_t>(input);
3419 CHECK_EQ(expect, m.Call());
3420 CHECK_EQ(expect, output);
3425 int32_t expect = static_cast<int32_t>(input);
3426 CHECK_EQ(expect, m.Call());
3427 CHECK_EQ(expect, output);
3430 // Note we don't check fractional inputs, because these Convert operators
3431 // really should be Change operators.
3435 TEST(RunChangeFloat64ToUint32_B) {
3436 RawMachineAssemblerTester<int32_t> m;
3441 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(0));
3442 Node* convert = m.ChangeFloat64ToUint32(load);
3443 m.Store(kMachInt32, m.PointerConstant(&output), m.Int32Constant(0), convert);
3447 FOR_UINT32_INPUTS(i) {
3449 // TODO(titzer): add a CheckEqualsHelper overload for uint32_t.
3450 int32_t expect = static_cast<int32_t>(*i);
3451 CHECK_EQ(expect, m.Call());
3452 CHECK_EQ(expect, output);
3456 // Check various powers of 2.
3457 for (int32_t n = 1; n < 31; ++n) {
3460 int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
3461 CHECK_EQ(expect, m.Call());
3462 CHECK_EQ(expect, output);
3467 int32_t expect = static_cast<int32_t>(static_cast<uint32_t>(input));
3468 CHECK_EQ(expect, m.Call());
3469 CHECK_EQ(expect, output);
3472 // Note we don't check fractional inputs, because these Convert operators
3473 // really should be Change operators.
3477 TEST(RunChangeFloat64ToInt32_spilled) {
3478 RawMachineAssemblerTester<int32_t> m;
3479 const int kNumInputs = 32;
3480 int32_t magic = 0x786234;
3481 double input[kNumInputs];
3482 int32_t result[kNumInputs];
3483 Node* input_node[kNumInputs];
3485 for (int i = 0; i < kNumInputs; i++) {
3487 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
3490 for (int i = 0; i < kNumInputs; i++) {
3491 m.Store(kMachInt32, m.PointerConstant(&result), m.Int32Constant(i * 4),
3492 m.ChangeFloat64ToInt32(input_node[i]));
3495 m.Return(m.Int32Constant(magic));
3497 for (int i = 0; i < kNumInputs; i++) {
3498 input[i] = 100.9 + i;
3501 CHECK_EQ(magic, m.Call());
3503 for (int i = 0; i < kNumInputs; i++) {
3504 CHECK_EQ(result[i], 100 + i);
3509 TEST(RunChangeFloat64ToUint32_spilled) {
3510 RawMachineAssemblerTester<uint32_t> m;
3511 const int kNumInputs = 32;
3512 uint32_t magic = 0x786234;
3513 double input[kNumInputs];
3514 uint32_t result[kNumInputs];
3515 Node* input_node[kNumInputs];
3517 for (int i = 0; i < kNumInputs; i++) {
3519 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
3522 for (int i = 0; i < kNumInputs; i++) {
3523 m.Store(kMachUint32, m.PointerConstant(&result), m.Int32Constant(i * 4),
3524 m.ChangeFloat64ToUint32(input_node[i]));
3527 m.Return(m.Int32Constant(magic));
3529 for (int i = 0; i < kNumInputs; i++) {
3531 input[i] = 100 + i + 2147483648u;
3537 CHECK_EQ(magic, m.Call());
3539 for (int i = 0; i < kNumInputs; i++) {
3541 CHECK_EQ(result[i], static_cast<uint32_t>(100 + i + 2147483648u));
3543 CHECK_EQ(result[i], static_cast<uint32_t>(100 + i));
3549 TEST(RunTruncateFloat64ToFloat32_spilled) {
3550 RawMachineAssemblerTester<uint32_t> m;
3551 const int kNumInputs = 32;
3552 uint32_t magic = 0x786234;
3553 double input[kNumInputs];
3554 float result[kNumInputs];
3555 Node* input_node[kNumInputs];
3557 for (int i = 0; i < kNumInputs; i++) {
3559 m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
3562 for (int i = 0; i < kNumInputs; i++) {
3563 m.Store(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4),
3564 m.TruncateFloat64ToFloat32(input_node[i]));
3567 m.Return(m.Int32Constant(magic));
3569 for (int i = 0; i < kNumInputs; i++) {
3573 CHECK_EQ(magic, m.Call());
3575 for (int i = 0; i < kNumInputs; i++) {
3576 CHECK_EQ(result[i], DoubleToFloat32(input[i]));
3581 TEST(RunDeadChangeFloat64ToInt32) {
3582 RawMachineAssemblerTester<int32_t> m;
3583 const int magic = 0x88abcda4;
3584 m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
3585 m.Return(m.Int32Constant(magic));
3586 CHECK_EQ(magic, m.Call());
3590 TEST(RunDeadChangeInt32ToFloat64) {
3591 RawMachineAssemblerTester<int32_t> m;
3592 const int magic = 0x8834abcd;
3593 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
3594 m.Return(m.Int32Constant(magic));
3595 CHECK_EQ(magic, m.Call());
3599 TEST(RunLoopPhiInduction2) {
3600 RawMachineAssemblerTester<int32_t> m;
3602 int false_val = 0x10777;
3604 // x = false_val; while(false) { x++; } return x;
3605 MLabel header, body, end;
3606 Node* false_node = m.Int32Constant(false_val);
3609 Node* phi = m.Phi(kMachInt32, false_node, false_node);
3610 m.Branch(m.Int32Constant(0), &body, &end);
3612 Node* add = m.Int32Add(phi, m.Int32Constant(1));
3613 phi->ReplaceInput(1, add);
3618 CHECK_EQ(false_val, m.Call());
3622 TEST(RunDoubleDiamond) {
3623 RawMachineAssemblerTester<int32_t> m;
3625 const int magic = 99645;
3626 double buffer = 0.1;
3627 double constant = 99.99;
3629 MLabel blocka, blockb, end;
3630 Node* k1 = m.Float64Constant(constant);
3631 Node* k2 = m.Float64Constant(0 - constant);
3632 m.Branch(m.Int32Constant(0), &blocka, &blockb);
3638 Node* phi = m.Phi(kMachFloat64, k2, k1);
3639 m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
3640 m.Return(m.Int32Constant(magic));
3642 CHECK_EQ(magic, m.Call());
3643 CHECK_EQ(constant, buffer);
3647 TEST(RunRefDiamond) {
3648 RawMachineAssemblerTester<int32_t> m;
3650 const int magic = 99644;
3651 Handle<String> rexpected =
3652 CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
3655 MLabel blocka, blockb, end;
3656 Node* k1 = m.StringConstant("A");
3657 Node* k2 = m.StringConstant("B");
3658 m.Branch(m.Int32Constant(0), &blocka, &blockb);
3664 Node* phi = m.Phi(kMachAnyTagged, k2, k1);
3665 m.Store(kMachAnyTagged, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
3666 m.Return(m.Int32Constant(magic));
3668 CHECK_EQ(magic, m.Call());
3669 CHECK(rexpected->SameValue(buffer));
3673 TEST(RunDoubleRefDiamond) {
3674 RawMachineAssemblerTester<int32_t> m;
3676 const int magic = 99648;
3677 double dbuffer = 0.1;
3678 double dconstant = 99.99;
3679 Handle<String> rexpected =
3680 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
3683 MLabel blocka, blockb, end;
3684 Node* d1 = m.Float64Constant(dconstant);
3685 Node* d2 = m.Float64Constant(0 - dconstant);
3686 Node* r1 = m.StringConstant("AX");
3687 Node* r2 = m.StringConstant("BX");
3688 m.Branch(m.Int32Constant(0), &blocka, &blockb);
3694 Node* dphi = m.Phi(kMachFloat64, d2, d1);
3695 Node* rphi = m.Phi(kMachAnyTagged, r2, r1);
3696 m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi);
3697 m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
3699 m.Return(m.Int32Constant(magic));
3701 CHECK_EQ(magic, m.Call());
3702 CHECK_EQ(dconstant, dbuffer);
3703 CHECK(rexpected->SameValue(rbuffer));
3707 TEST(RunDoubleRefDoubleDiamond) {
3708 RawMachineAssemblerTester<int32_t> m;
3710 const int magic = 99649;
3711 double dbuffer = 0.1;
3712 double dconstant = 99.997;
3713 Handle<String> rexpected =
3714 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
3717 MLabel blocka, blockb, mid, blockd, blocke, end;
3718 Node* d1 = m.Float64Constant(dconstant);
3719 Node* d2 = m.Float64Constant(0 - dconstant);
3720 Node* r1 = m.StringConstant("AD");
3721 Node* r2 = m.StringConstant("BD");
3722 m.Branch(m.Int32Constant(0), &blocka, &blockb);
3728 Node* dphi1 = m.Phi(kMachFloat64, d2, d1);
3729 Node* rphi1 = m.Phi(kMachAnyTagged, r2, r1);
3730 m.Branch(m.Int32Constant(0), &blockd, &blocke);
3737 Node* dphi2 = m.Phi(kMachFloat64, d1, dphi1);
3738 Node* rphi2 = m.Phi(kMachAnyTagged, r1, rphi1);
3740 m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi2);
3741 m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0),
3743 m.Return(m.Int32Constant(magic));
3745 CHECK_EQ(magic, m.Call());
3746 CHECK_EQ(dconstant, dbuffer);
3747 CHECK(rexpected->SameValue(rbuffer));
3751 TEST(RunDoubleLoopPhi) {
3752 RawMachineAssemblerTester<int32_t> m;
3753 MLabel header, body, end;
3756 double buffer = 0.99;
3757 double dconstant = 777.1;
3759 Node* zero = m.Int32Constant(0);
3760 Node* dk = m.Float64Constant(dconstant);
3764 Node* phi = m.Phi(kMachFloat64, dk, dk);
3765 phi->ReplaceInput(1, phi);
3766 m.Branch(zero, &body, &end);
3770 m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi);
3771 m.Return(m.Int32Constant(magic));
3773 CHECK_EQ(magic, m.Call());
3777 TEST(RunCountToTenAccRaw) {
3778 RawMachineAssemblerTester<int32_t> m;
3780 Node* zero = m.Int32Constant(0);
3781 Node* ten = m.Int32Constant(10);
3782 Node* one = m.Int32Constant(1);
3784 MLabel header, body, body_cont, end;
3789 Node* i = m.Phi(kMachInt32, zero, zero);
3790 Node* j = m.Phi(kMachInt32, zero, zero);
3794 Node* next_i = m.Int32Add(i, one);
3795 Node* next_j = m.Int32Add(j, one);
3796 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
3799 i->ReplaceInput(1, next_i);
3800 j->ReplaceInput(1, next_j);
3806 CHECK_EQ(10, m.Call());
3810 TEST(RunCountToTenAccRaw2) {
3811 RawMachineAssemblerTester<int32_t> m;
3813 Node* zero = m.Int32Constant(0);
3814 Node* ten = m.Int32Constant(10);
3815 Node* one = m.Int32Constant(1);
3817 MLabel header, body, body_cont, end;
3822 Node* i = m.Phi(kMachInt32, zero, zero);
3823 Node* j = m.Phi(kMachInt32, zero, zero);
3824 Node* k = m.Phi(kMachInt32, zero, zero);
3828 Node* next_i = m.Int32Add(i, one);
3829 Node* next_j = m.Int32Add(j, one);
3830 Node* next_k = m.Int32Add(j, one);
3831 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
3834 i->ReplaceInput(1, next_i);
3835 j->ReplaceInput(1, next_j);
3836 k->ReplaceInput(1, next_k);
3842 CHECK_EQ(10, m.Call());
3847 RawMachineAssemblerTester<int32_t> m;
3848 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
3850 Node* base = m.PointerConstant(inputs);
3851 Node* n0 = m.Load(kMachInt32, base, m.Int32Constant(0 * sizeof(int32_t)));
3852 Node* n1 = m.Load(kMachInt32, base, m.Int32Constant(1 * sizeof(int32_t)));
3853 Node* n2 = m.Load(kMachInt32, base, m.Int32Constant(2 * sizeof(int32_t)));
3854 Node* n3 = m.Load(kMachInt32, base, m.Int32Constant(3 * sizeof(int32_t)));
3855 Node* n4 = m.Load(kMachInt32, base, m.Int32Constant(4 * sizeof(int32_t)));
3856 Node* n5 = m.Load(kMachInt32, base, m.Int32Constant(5 * sizeof(int32_t)));
3857 Node* n6 = m.Load(kMachInt32, base, m.Int32Constant(6 * sizeof(int32_t)));
3858 Node* n7 = m.Load(kMachInt32, base, m.Int32Constant(7 * sizeof(int32_t)));
3860 Node* i1 = m.Int32Add(n0, n1);
3861 Node* i2 = m.Int32Add(n2, n3);
3862 Node* i3 = m.Int32Add(n4, n5);
3863 Node* i4 = m.Int32Add(n6, n7);
3865 Node* i5 = m.Int32Add(i1, i2);
3866 Node* i6 = m.Int32Add(i3, i4);
3868 Node* i7 = m.Int32Add(i5, i6);
3872 CHECK_EQ(116, m.Call());
3876 static const int kFloat64CompareHelperTestCases = 15;
3877 static const int kFloat64CompareHelperNodeType = 4;
3879 static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
3880 int test_case, int node_type, double x,
3882 static double buffer[2];
3885 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
3886 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
3888 bool load_a = node_type / 2 == 1;
3889 bool load_b = node_type % 2 == 1;
3890 Node* a = load_a ? m->Load(kMachFloat64, m->PointerConstant(&buffer[0]))
3891 : m->Float64Constant(x);
3892 Node* b = load_b ? m->Load(kMachFloat64, m->PointerConstant(&buffer[1]))
3893 : m->Float64Constant(y);
3895 bool expected = false;
3896 switch (test_case) {
3899 cmp = m->Float64Equal(a, b);
3903 cmp = m->Float64Equal(a, a);
3908 cmp = m->Float64LessThan(a, b);
3912 cmp = m->Float64LessThan(b, a);
3916 cmp = m->Float64LessThan(a, a);
3919 // LessThanOrEqual tests.
3921 cmp = m->Float64LessThanOrEqual(a, b);
3925 cmp = m->Float64LessThanOrEqual(b, a);
3929 cmp = m->Float64LessThanOrEqual(a, a);
3934 cmp = m->Float64NotEqual(a, b);
3938 cmp = m->Float64NotEqual(b, a);
3942 cmp = m->Float64NotEqual(a, a);
3945 // GreaterThan tests.
3947 cmp = m->Float64GreaterThan(a, a);
3951 cmp = m->Float64GreaterThan(a, b);
3954 // GreaterThanOrEqual tests.
3956 cmp = m->Float64GreaterThanOrEqual(a, a);
3960 cmp = m->Float64GreaterThanOrEqual(b, a);
3971 TEST(RunFloat64Compare) {
3972 double inf = V8_INFINITY;
3973 // All pairs (a1, a2) are of the form a1 < a2.
3974 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22,
3975 -inf, 0.22, 0.22, inf, -inf, inf};
3977 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
3978 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
3980 for (size_t input = 0; input < arraysize(inputs); input += 2) {
3981 RawMachineAssemblerTester<int32_t> m;
3982 int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
3984 CHECK_EQ(expected, m.Call());
3991 TEST(RunFloat64UnorderedCompare) {
3992 RawMachineAssemblerTester<int32_t> m;
3994 const Operator* operators[] = {m.machine()->Float64Equal(),
3995 m.machine()->Float64LessThan(),
3996 m.machine()->Float64LessThanOrEqual()};
3998 double nan = std::numeric_limits<double>::quiet_NaN();
4000 FOR_FLOAT64_INPUTS(i) {
4001 for (size_t o = 0; o < arraysize(operators); ++o) {
4002 for (int j = 0; j < 2; j++) {
4003 RawMachineAssemblerTester<int32_t> m;
4004 Node* a = m.Float64Constant(*i);
4005 Node* b = m.Float64Constant(nan);
4006 if (j == 1) std::swap(a, b);
4007 m.Return(m.NewNode(operators[o], a, b));
4008 CHECK_EQ(0, m.Call());
4015 TEST(RunFloat64Equal) {
4016 double input_a = 0.0;
4017 double input_b = 0.0;
4019 RawMachineAssemblerTester<int32_t> m;
4020 Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
4021 Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
4022 m.Return(m.Float64Equal(a, b));
4024 CompareWrapper cmp(IrOpcode::kFloat64Equal);
4025 FOR_FLOAT64_INPUTS(pl) {
4026 FOR_FLOAT64_INPUTS(pr) {
4029 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4030 CHECK_EQ(expected, m.Call());
4036 TEST(RunFloat64LessThan) {
4037 double input_a = 0.0;
4038 double input_b = 0.0;
4040 RawMachineAssemblerTester<int32_t> m;
4041 Node* a = m.LoadFromPointer(&input_a, kMachFloat64);
4042 Node* b = m.LoadFromPointer(&input_b, kMachFloat64);
4043 m.Return(m.Float64LessThan(a, b));
4045 CompareWrapper cmp(IrOpcode::kFloat64LessThan);
4046 FOR_FLOAT64_INPUTS(pl) {
4047 FOR_FLOAT64_INPUTS(pr) {
4050 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4051 CHECK_EQ(expected, m.Call());
4057 template <typename IntType, MachineType kRepresentation>
4058 static void LoadStoreTruncation() {
4061 RawMachineAssemblerTester<int32_t> m;
4062 Node* a = m.LoadFromPointer(&input, kRepresentation);
4063 Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
4064 m.StoreToPointer(&input, kRepresentation, ap1);
4067 const IntType max = std::numeric_limits<IntType>::max();
4068 const IntType min = std::numeric_limits<IntType>::min();
4070 // Test upper bound.
4072 CHECK_EQ(max + 1, m.Call());
4073 CHECK_EQ(min, input);
4075 // Test lower bound.
4077 CHECK_EQ(static_cast<IntType>(max + 2), m.Call());
4078 CHECK_EQ(min + 1, input);
4080 // Test all one byte values that are not one byte bounds.
4081 for (int i = -127; i < 127; i++) {
4083 int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
4084 CHECK_EQ(static_cast<IntType>(expected), m.Call());
4085 CHECK_EQ(static_cast<IntType>(i + 1), input);
4090 TEST(RunLoadStoreTruncation) {
4091 LoadStoreTruncation<int8_t, kMachInt8>();
4092 LoadStoreTruncation<int16_t, kMachInt16>();
4096 static void IntPtrCompare(intptr_t left, intptr_t right) {
4097 for (int test = 0; test < 7; test++) {
4098 RawMachineAssemblerTester<bool> m(kMachPtr, kMachPtr);
4099 Node* p0 = m.Parameter(0);
4100 Node* p1 = m.Parameter(1);
4102 bool expected = false;
4105 res = m.IntPtrLessThan(p0, p1);
4109 res = m.IntPtrLessThanOrEqual(p0, p1);
4113 res = m.IntPtrEqual(p0, p1);
4117 res = m.IntPtrGreaterThanOrEqual(p0, p1);
4121 res = m.IntPtrGreaterThan(p0, p1);
4125 res = m.IntPtrEqual(p0, p0);
4129 res = m.IntPtrNotEqual(p0, p1);
4137 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
4138 reinterpret_cast<int32_t*>(right)));
4143 TEST(RunIntPtrCompare) {
4144 intptr_t min = std::numeric_limits<intptr_t>::min();
4145 intptr_t max = std::numeric_limits<intptr_t>::max();
4146 // An ascending chain of intptr_t
4147 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
4148 for (size_t i = 0; i < arraysize(inputs) - 1; i++) {
4149 IntPtrCompare(inputs[i], inputs[i + 1]);
4154 TEST(RunTestIntPtrArithmetic) {
4155 static const int kInputSize = 10;
4156 int32_t inputs[kInputSize];
4157 int32_t outputs[kInputSize];
4158 for (int i = 0; i < kInputSize; i++) {
4162 RawMachineAssemblerTester<int32_t*> m;
4163 Node* input = m.PointerConstant(&inputs[0]);
4164 Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
4165 Node* elem_size = m.ConvertInt32ToIntPtr(m.Int32Constant(sizeof(inputs[0])));
4166 for (int i = 0; i < kInputSize; i++) {
4167 m.Store(kMachInt32, output, m.Load(kMachInt32, input));
4168 input = m.IntPtrAdd(input, elem_size);
4169 output = m.IntPtrSub(output, elem_size);
4172 CHECK_EQ(&inputs[kInputSize], m.Call());
4173 for (int i = 0; i < kInputSize; i++) {
4174 CHECK_EQ(i, inputs[i]);
4175 CHECK_EQ(kInputSize - i - 1, outputs[i]);
4180 TEST(RunSpillLotsOfThings) {
4181 static const int kInputSize = 1000;
4182 RawMachineAssemblerTester<void> m;
4183 Node* accs[kInputSize];
4184 int32_t outputs[kInputSize];
4185 Node* one = m.Int32Constant(1);
4187 for (int i = 0; i < kInputSize; i++) {
4188 acc = m.Int32Add(acc, one);
4191 for (int i = 0; i < kInputSize; i++) {
4192 m.StoreToPointer(&outputs[i], kMachInt32, accs[i]);
4196 for (int i = 0; i < kInputSize; i++) {
4197 CHECK_EQ(outputs[i], i + 2);
4202 TEST(RunSpillConstantsAndParameters) {
4203 static const int kInputSize = 1000;
4204 static const int32_t kBase = 987;
4205 RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
4206 int32_t outputs[kInputSize];
4207 Node* csts[kInputSize];
4208 Node* accs[kInputSize];
4209 Node* acc = m.Int32Constant(0);
4210 for (int i = 0; i < kInputSize; i++) {
4211 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
4213 for (int i = 0; i < kInputSize; i++) {
4214 acc = m.Int32Add(acc, csts[i]);
4217 for (int i = 0; i < kInputSize; i++) {
4218 m.StoreToPointer(&outputs[i], kMachInt32, accs[i]);
4220 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
4221 FOR_INT32_INPUTS(i) {
4222 FOR_INT32_INPUTS(j) {
4223 int32_t expected = *i + *j;
4224 for (int k = 0; k < kInputSize; k++) {
4225 expected += kBase + k;
4227 CHECK_EQ(expected, m.Call(*i, *j));
4229 for (int k = 0; k < kInputSize; k++) {
4230 expected += kBase + k;
4231 CHECK_EQ(expected, outputs[k]);
4238 TEST(RunNewSpaceConstantsInPhi) {
4239 RawMachineAssemblerTester<Object*> m(kMachInt32);
4241 Isolate* isolate = CcTest::i_isolate();
4242 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
4243 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
4244 Node* true_node = m.HeapConstant(true_val);
4245 Node* false_node = m.HeapConstant(false_val);
4247 MLabel blocka, blockb, end;
4248 m.Branch(m.Parameter(0), &blocka, &blockb);
4255 Node* phi = m.Phi(kMachAnyTagged, true_node, false_node);
4258 CHECK_EQ(*false_val, m.Call(0));
4259 CHECK_EQ(*true_val, m.Call(1));
4263 TEST(RunInt32AddWithOverflowP) {
4264 int32_t actual_val = -1;
4265 RawMachineAssemblerTester<int32_t> m;
4266 Int32BinopTester bt(&m);
4267 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
4268 Node* val = m.Projection(0, add);
4269 Node* ovf = m.Projection(1, add);
4270 m.StoreToPointer(&actual_val, kMachInt32, val);
4272 FOR_INT32_INPUTS(i) {
4273 FOR_INT32_INPUTS(j) {
4274 int32_t expected_val;
4275 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4276 CHECK_EQ(expected_ovf, bt.call(*i, *j));
4277 CHECK_EQ(expected_val, actual_val);
4283 TEST(RunInt32AddWithOverflowImm) {
4284 int32_t actual_val = -1, expected_val = 0;
4285 FOR_INT32_INPUTS(i) {
4287 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4288 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
4289 Node* val = m.Projection(0, add);
4290 Node* ovf = m.Projection(1, add);
4291 m.StoreToPointer(&actual_val, kMachInt32, val);
4293 FOR_INT32_INPUTS(j) {
4294 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4295 CHECK_EQ(expected_ovf, m.Call(*j));
4296 CHECK_EQ(expected_val, actual_val);
4300 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4301 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
4302 Node* val = m.Projection(0, add);
4303 Node* ovf = m.Projection(1, add);
4304 m.StoreToPointer(&actual_val, kMachInt32, val);
4306 FOR_INT32_INPUTS(j) {
4307 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4308 CHECK_EQ(expected_ovf, m.Call(*j));
4309 CHECK_EQ(expected_val, actual_val);
4312 FOR_INT32_INPUTS(j) {
4313 RawMachineAssemblerTester<int32_t> m;
4315 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
4316 Node* val = m.Projection(0, add);
4317 Node* ovf = m.Projection(1, add);
4318 m.StoreToPointer(&actual_val, kMachInt32, val);
4320 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4321 CHECK_EQ(expected_ovf, m.Call());
4322 CHECK_EQ(expected_val, actual_val);
4328 TEST(RunInt32AddWithOverflowInBranchP) {
4329 int constant = 911777;
4330 MLabel blocka, blockb;
4331 RawMachineAssemblerTester<int32_t> m;
4332 Int32BinopTester bt(&m);
4333 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
4334 Node* ovf = m.Projection(1, add);
4335 m.Branch(ovf, &blocka, &blockb);
4337 bt.AddReturn(m.Int32Constant(constant));
4339 Node* val = m.Projection(0, add);
4341 FOR_INT32_INPUTS(i) {
4342 FOR_INT32_INPUTS(j) {
4344 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant;
4345 CHECK_EQ(expected, bt.call(*i, *j));
4351 TEST(RunInt32SubWithOverflowP) {
4352 int32_t actual_val = -1;
4353 RawMachineAssemblerTester<int32_t> m;
4354 Int32BinopTester bt(&m);
4355 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
4356 Node* val = m.Projection(0, add);
4357 Node* ovf = m.Projection(1, add);
4358 m.StoreToPointer(&actual_val, kMachInt32, val);
4360 FOR_INT32_INPUTS(i) {
4361 FOR_INT32_INPUTS(j) {
4362 int32_t expected_val;
4363 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
4364 CHECK_EQ(expected_ovf, bt.call(*i, *j));
4365 CHECK_EQ(expected_val, actual_val);
4371 TEST(RunInt32SubWithOverflowImm) {
4372 int32_t actual_val = -1, expected_val = 0;
4373 FOR_INT32_INPUTS(i) {
4375 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4376 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
4377 Node* val = m.Projection(0, add);
4378 Node* ovf = m.Projection(1, add);
4379 m.StoreToPointer(&actual_val, kMachInt32, val);
4381 FOR_INT32_INPUTS(j) {
4382 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
4383 CHECK_EQ(expected_ovf, m.Call(*j));
4384 CHECK_EQ(expected_val, actual_val);
4388 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4389 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
4390 Node* val = m.Projection(0, add);
4391 Node* ovf = m.Projection(1, add);
4392 m.StoreToPointer(&actual_val, kMachInt32, val);
4394 FOR_INT32_INPUTS(j) {
4395 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
4396 CHECK_EQ(expected_ovf, m.Call(*j));
4397 CHECK_EQ(expected_val, actual_val);
4400 FOR_INT32_INPUTS(j) {
4401 RawMachineAssemblerTester<int32_t> m;
4403 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
4404 Node* val = m.Projection(0, add);
4405 Node* ovf = m.Projection(1, add);
4406 m.StoreToPointer(&actual_val, kMachInt32, val);
4408 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
4409 CHECK_EQ(expected_ovf, m.Call());
4410 CHECK_EQ(expected_val, actual_val);
4416 TEST(RunInt32SubWithOverflowInBranchP) {
4417 int constant = 911999;
4418 MLabel blocka, blockb;
4419 RawMachineAssemblerTester<int32_t> m;
4420 Int32BinopTester bt(&m);
4421 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
4422 Node* ovf = m.Projection(1, sub);
4423 m.Branch(ovf, &blocka, &blockb);
4425 bt.AddReturn(m.Int32Constant(constant));
4427 Node* val = m.Projection(0, sub);
4429 FOR_INT32_INPUTS(i) {
4430 FOR_INT32_INPUTS(j) {
4432 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant;
4433 CHECK_EQ(expected, bt.call(*i, *j));
4439 TEST(RunWord64EqualInBranchP) {
4441 MLabel blocka, blockb;
4442 RawMachineAssemblerTester<int64_t> m;
4443 if (!m.machine()->Is64()) return;
4444 Node* value = m.LoadFromPointer(&input, kMachInt64);
4445 m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
4447 m.Return(m.Int32Constant(1));
4449 m.Return(m.Int32Constant(2));
4450 input = V8_INT64_C(0);
4451 CHECK_EQ(1, m.Call());
4452 input = V8_INT64_C(1);
4453 CHECK_EQ(2, m.Call());
4454 input = V8_INT64_C(0x100000000);
4455 CHECK_EQ(2, m.Call());
4459 TEST(RunChangeInt32ToInt64P) {
4460 if (kPointerSize < 8) return;
4461 int64_t actual = -1;
4462 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4463 m.StoreToPointer(&actual, kMachInt64, m.ChangeInt32ToInt64(m.Parameter(0)));
4464 m.Return(m.Int32Constant(0));
4465 FOR_INT32_INPUTS(i) {
4466 int64_t expected = *i;
4467 CHECK_EQ(0, m.Call(*i));
4468 CHECK_EQ(expected, actual);
4473 TEST(RunChangeUint32ToUint64P) {
4474 if (kPointerSize < 8) return;
4475 int64_t actual = -1;
4476 RawMachineAssemblerTester<int32_t> m(kMachUint32);
4477 m.StoreToPointer(&actual, kMachUint64,
4478 m.ChangeUint32ToUint64(m.Parameter(0)));
4479 m.Return(m.Int32Constant(0));
4480 FOR_UINT32_INPUTS(i) {
4481 int64_t expected = static_cast<uint64_t>(*i);
4482 CHECK_EQ(0, m.Call(*i));
4483 CHECK_EQ(expected, actual);
4488 TEST(RunTruncateInt64ToInt32P) {
4489 if (kPointerSize < 8) return;
4490 int64_t expected = -1;
4491 RawMachineAssemblerTester<int32_t> m;
4492 m.Return(m.TruncateInt64ToInt32(m.LoadFromPointer(&expected, kMachInt64)));
4493 FOR_UINT32_INPUTS(i) {
4494 FOR_UINT32_INPUTS(j) {
4495 expected = (static_cast<uint64_t>(*j) << 32) | *i;
4496 CHECK_EQ(static_cast<int32_t>(expected), m.Call());
4502 TEST(RunTruncateFloat64ToInt32P) {
4506 } kValues[] = {{0, 0},
4513 {std::numeric_limits<double>::quiet_NaN(), 0},
4514 {std::numeric_limits<double>::infinity(), 0},
4515 {-std::numeric_limits<double>::quiet_NaN(), 0},
4516 {-std::numeric_limits<double>::infinity(), 0},
4517 {4.94065645841e-324, 0},
4518 {-4.94065645841e-324, 0},
4519 {0.9999999999999999, 0},
4520 {-0.9999999999999999, 0},
4523 {9223372036854775000.0, 4294966272.0},
4524 {-9223372036854775000.0, -4294966272.0},
4525 {4.5036e+15, 372629504},
4526 {-4.5036e+15, -372629504},
4527 {287524199.5377777, 0x11234567},
4528 {-287524199.5377777, -0x11234567},
4529 {2300193596.302222, 2300193596.0},
4530 {-2300193596.302222, -2300193596.0},
4531 {4600387192.604444, 305419896},
4532 {-4600387192.604444, -305419896},
4533 {4823855600872397.0, 1737075661},
4534 {-4823855600872397.0, -1737075661},
4535 {4503603922337791.0, -1},
4536 {-4503603922337791.0, 1},
4537 {4503601774854143.0, 2147483647},
4538 {-4503601774854143.0, -2147483647},
4539 {9007207844675582.0, -2},
4540 {-9007207844675582.0, 2},
4541 {2.4178527921507624e+24, -536870912},
4542 {-2.4178527921507624e+24, 536870912},
4543 {2.417853945072267e+24, -536870912},
4544 {-2.417853945072267e+24, 536870912},
4545 {4.8357055843015248e+24, -1073741824},
4546 {-4.8357055843015248e+24, 1073741824},
4547 {4.8357078901445341e+24, -1073741824},
4548 {-4.8357078901445341e+24, 1073741824},
4549 {2147483647.0, 2147483647.0},
4550 {-2147483648.0, -2147483648.0},
4551 {9.6714111686030497e+24, -2147483648.0},
4552 {-9.6714111686030497e+24, -2147483648.0},
4553 {9.6714157802890681e+24, -2147483648.0},
4554 {-9.6714157802890681e+24, -2147483648.0},
4555 {1.9342813113834065e+25, 2147483648.0},
4556 {-1.9342813113834065e+25, 2147483648.0},
4557 {3.868562622766813e+25, 0},
4558 {-3.868562622766813e+25, 0},
4559 {1.7976931348623157e+308, 0},
4560 {-1.7976931348623157e+308, 0}};
4561 double input = -1.0;
4562 RawMachineAssemblerTester<int32_t> m;
4563 m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64)));
4564 for (size_t i = 0; i < arraysize(kValues); ++i) {
4565 input = kValues[i].from;
4566 uint64_t expected = static_cast<int64_t>(kValues[i].raw);
4567 CHECK_EQ(static_cast<int>(expected), m.Call());
4572 TEST(RunChangeFloat32ToFloat64) {
4573 double actual = 0.0f;
4574 float expected = 0.0;
4575 RawMachineAssemblerTester<int32_t> m;
4577 &actual, kMachFloat64,
4578 m.ChangeFloat32ToFloat64(m.LoadFromPointer(&expected, kMachFloat32)));
4579 m.Return(m.Int32Constant(0));
4580 FOR_FLOAT32_INPUTS(i) {
4582 CHECK_EQ(0, m.Call());
4583 CHECK_EQ(expected, actual);
4588 TEST(RunChangeFloat32ToFloat64_spilled) {
4589 RawMachineAssemblerTester<int32_t> m;
4590 const int kNumInputs = 32;
4591 int32_t magic = 0x786234;
4592 float input[kNumInputs];
4593 double result[kNumInputs];
4594 Node* input_node[kNumInputs];
4596 for (int i = 0; i < kNumInputs; i++) {
4598 m.Load(kMachFloat32, m.PointerConstant(&input), m.Int32Constant(i * 4));
4601 for (int i = 0; i < kNumInputs; i++) {
4602 m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
4603 m.ChangeFloat32ToFloat64(input_node[i]));
4606 m.Return(m.Int32Constant(magic));
4608 for (int i = 0; i < kNumInputs; i++) {
4609 input[i] = 100.9f + i;
4612 CHECK_EQ(magic, m.Call());
4614 for (int i = 0; i < kNumInputs; i++) {
4615 CHECK_EQ(result[i], static_cast<double>(input[i]));
4620 TEST(RunTruncateFloat64ToFloat32) {
4621 float actual = 0.0f;
4623 RawMachineAssemblerTester<int32_t> m;
4625 &actual, kMachFloat32,
4626 m.TruncateFloat64ToFloat32(m.LoadFromPointer(&input, kMachFloat64)));
4627 m.Return(m.Int32Constant(0));
4628 FOR_FLOAT64_INPUTS(i) {
4630 volatile double expected = DoubleToFloat32(input);
4631 CHECK_EQ(0, m.Call());
4632 CheckDoubleEq(expected, actual);
4637 TEST(RunFloat32Constant) {
4638 FOR_FLOAT32_INPUTS(i) {
4639 float expected = *i;
4641 RawMachineAssemblerTester<int32_t> m;
4642 m.StoreToPointer(&actual, kMachFloat32, m.Float32Constant(expected));
4643 m.Return(m.Int32Constant(0));
4644 CHECK_EQ(0, m.Call());
4645 CHECK_EQ(expected, actual);
4650 TEST(RunFloat64ExtractLowWord32) {
4652 RawMachineAssemblerTester<int32_t> m;
4653 m.Return(m.Float64ExtractLowWord32(m.LoadFromPointer(&input, kMachFloat64)));
4654 FOR_FLOAT64_INPUTS(i) {
4655 input = bit_cast<uint64_t>(*i);
4656 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(input));
4657 CHECK_EQ(expected, m.Call());
4662 TEST(RunFloat64ExtractHighWord32) {
4664 RawMachineAssemblerTester<int32_t> m;
4665 m.Return(m.Float64ExtractHighWord32(m.LoadFromPointer(&input, kMachFloat64)));
4666 FOR_FLOAT64_INPUTS(i) {
4667 input = bit_cast<uint64_t>(*i);
4668 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(input >> 32));
4669 CHECK_EQ(expected, m.Call());
4674 TEST(RunFloat64InsertLowWord32) {
4676 uint64_t result = 0;
4677 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4679 &result, kMachFloat64,
4680 m.Float64InsertLowWord32(m.LoadFromPointer(&input, kMachFloat64),
4682 m.Return(m.Int32Constant(0));
4683 FOR_FLOAT64_INPUTS(i) {
4684 FOR_INT32_INPUTS(j) {
4685 input = bit_cast<uint64_t>(*i);
4686 uint64_t expected = (input & ~(V8_UINT64_C(0xFFFFFFFF))) |
4687 (static_cast<uint64_t>(bit_cast<uint32_t>(*j)));
4688 CHECK_EQ(0, m.Call(*j));
4689 CHECK_EQ(expected, result);
4695 TEST(RunFloat64InsertHighWord32) {
4697 uint64_t result = 0;
4698 RawMachineAssemblerTester<int32_t> m(kMachInt32);
4700 &result, kMachFloat64,
4701 m.Float64InsertHighWord32(m.LoadFromPointer(&input, kMachFloat64),
4703 m.Return(m.Int32Constant(0));
4704 FOR_FLOAT64_INPUTS(i) {
4705 FOR_INT32_INPUTS(j) {
4706 input = bit_cast<uint64_t>(*i);
4707 uint64_t expected = (input & ~(V8_UINT64_C(0xFFFFFFFF) << 32)) |
4708 (static_cast<uint64_t>(bit_cast<uint32_t>(*j)) << 32);
4709 CHECK_EQ(0, m.Call(*j));
4710 CHECK_EQ(expected, result);
4716 static double two_30 = 1 << 30; // 2^30 is a smi boundary.
4717 static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary.
4718 static double kValues[] = {0.1,
4720 0.49999999999999994,
4723 1.0 - std::numeric_limits<double>::epsilon(),
4725 -0.49999999999999994,
4729 1.0 + std::numeric_limits<double>::epsilon(),
4733 -1 + std::numeric_limits<double>::epsilon(),
4734 -1 - std::numeric_limits<double>::epsilon(),
4738 std::numeric_limits<double>::min(),
4739 -std::numeric_limits<double>::min(),
4740 std::numeric_limits<double>::max(),
4741 -std::numeric_limits<double>::max(),
4742 std::numeric_limits<double>::infinity(),
4743 -std::numeric_limits<double>::infinity(),
4814 TEST(RunFloat64RoundDown1) {
4815 double input = -1.0;
4816 double result = 0.0;
4817 RawMachineAssemblerTester<int32_t> m;
4818 if (!m.machine()->HasFloat64RoundDown()) return;
4819 m.StoreToPointer(&result, kMachFloat64,
4820 m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64)));
4821 m.Return(m.Int32Constant(0));
4822 for (size_t i = 0; i < arraysize(kValues); ++i) {
4824 CHECK_EQ(0, m.Call());
4825 double expected = std::floor(kValues[i]);
4826 CHECK_EQ(expected, result);
4831 TEST(RunFloat64RoundDown2) {
4832 double input = -1.0;
4833 double result = 0.0;
4834 RawMachineAssemblerTester<int32_t> m;
4835 if (!m.machine()->HasFloat64RoundDown()) return;
4836 m.StoreToPointer(&result, kMachFloat64,
4837 m.Float64Sub(m.Float64Constant(-0.0),
4838 m.Float64RoundDown(m.Float64Sub(
4839 m.Float64Constant(-0.0),
4840 m.LoadFromPointer(&input, kMachFloat64)))));
4841 m.Return(m.Int32Constant(0));
4842 for (size_t i = 0; i < arraysize(kValues); ++i) {
4844 CHECK_EQ(0, m.Call());
4845 double expected = std::ceil(kValues[i]);
4846 CHECK_EQ(expected, result);
4851 TEST(RunFloat64RoundTruncate) {
4852 double input = -1.0;
4853 double result = 0.0;
4854 RawMachineAssemblerTester<int32_t> m;
4855 if (!m.machine()->HasFloat64RoundTruncate()) return;
4857 &result, kMachFloat64,
4858 m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
4859 m.Return(m.Int32Constant(0));
4860 for (size_t i = 0; i < arraysize(kValues); ++i) {
4862 CHECK_EQ(0, m.Call());
4863 double expected = trunc(kValues[i]);
4864 CHECK_EQ(expected, result);
4869 TEST(RunFloat64RoundTiesAway) {
4870 double input = -1.0;
4871 double result = 0.0;
4872 RawMachineAssemblerTester<int32_t> m;
4873 if (!m.machine()->HasFloat64RoundTiesAway()) return;
4875 &result, kMachFloat64,
4876 m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
4877 m.Return(m.Int32Constant(0));
4878 for (size_t i = 0; i < arraysize(kValues); ++i) {
4880 CHECK_EQ(0, m.Call());
4881 double expected = round(kValues[i]);
4882 CHECK_EQ(expected, result);
4886 #endif // V8_TURBOFAN_TARGET