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

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

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

Powered by Google App Engine
This is Rietveld 408576698