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