Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: test/cctest/compiler/test-run-machops.cc

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

Powered by Google App Engine
This is Rietveld 408576698