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