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