1// Copyright 2014 the V8 project authors. All rights reserved. Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
4
5#include <cmath>
6#include <functional>
7#include <limits>
8
9#include "src/base/bits.h"
10#include "src/base/utils/random-number-generator.h"
11#include "src/codegen.h"
12#include "test/cctest/cctest.h"
13#include "test/cctest/compiler/codegen-tester.h"
14#include "test/cctest/compiler/graph-builder-tester.h"
15#include "test/cctest/compiler/value-helper.h"
16
17using namespace v8::base;
18
19namespace v8 {
20namespace internal {
21namespace compiler {
22
23
24TEST(RunInt32Add) {
25  RawMachineAssemblerTester<int32_t> m;
26  Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1));
27  m.Return(add);
28  CHECK_EQ(1, m.Call());
29}
30
31
32TEST(RunWord32Ctz) {
33  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
34  if (!m.machine()->Word32Ctz().IsSupported()) {
35    // We can only test the operator if it exists on the testing platform.
36    return;
37  }
38  m.Return(m.AddNode(m.machine()->Word32Ctz().op(), m.Parameter(0)));
39
40  CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
41  CHECK_EQ(31, m.Call(uint32_t(0x80000000)));
42  CHECK_EQ(30, m.Call(uint32_t(0x40000000)));
43  CHECK_EQ(29, m.Call(uint32_t(0x20000000)));
44  CHECK_EQ(28, m.Call(uint32_t(0x10000000)));
45  CHECK_EQ(27, m.Call(uint32_t(0xa8000000)));
46  CHECK_EQ(26, m.Call(uint32_t(0xf4000000)));
47  CHECK_EQ(25, m.Call(uint32_t(0x62000000)));
48  CHECK_EQ(24, m.Call(uint32_t(0x91000000)));
49  CHECK_EQ(23, m.Call(uint32_t(0xcd800000)));
50  CHECK_EQ(22, m.Call(uint32_t(0x09400000)));
51  CHECK_EQ(21, m.Call(uint32_t(0xaf200000)));
52  CHECK_EQ(20, m.Call(uint32_t(0xac100000)));
53  CHECK_EQ(19, m.Call(uint32_t(0xe0b80000)));
54  CHECK_EQ(18, m.Call(uint32_t(0x9ce40000)));
55  CHECK_EQ(17, m.Call(uint32_t(0xc7920000)));
56  CHECK_EQ(16, m.Call(uint32_t(0xb8f10000)));
57  CHECK_EQ(15, m.Call(uint32_t(0x3b9f8000)));
58  CHECK_EQ(14, m.Call(uint32_t(0xdb4c4000)));
59  CHECK_EQ(13, m.Call(uint32_t(0xe9a32000)));
60  CHECK_EQ(12, m.Call(uint32_t(0xfca61000)));
61  CHECK_EQ(11, m.Call(uint32_t(0x6c8a7800)));
62  CHECK_EQ(10, m.Call(uint32_t(0x8ce5a400)));
63  CHECK_EQ(9, m.Call(uint32_t(0xcb7d0200)));
64  CHECK_EQ(8, m.Call(uint32_t(0xcb4dc100)));
65  CHECK_EQ(7, m.Call(uint32_t(0xdfbec580)));
66  CHECK_EQ(6, m.Call(uint32_t(0x27a9db40)));
67  CHECK_EQ(5, m.Call(uint32_t(0xde3bcb20)));
68  CHECK_EQ(4, m.Call(uint32_t(0xd7e8a610)));
69  CHECK_EQ(3, m.Call(uint32_t(0x9afdbc88)));
70  CHECK_EQ(2, m.Call(uint32_t(0x9afdbc84)));
71  CHECK_EQ(1, m.Call(uint32_t(0x9afdbc82)));
72  CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
73}
74
75
76TEST(RunWord32Clz) {
77  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
78  m.Return(m.Word32Clz(m.Parameter(0)));
79
80  CHECK_EQ(0, m.Call(uint32_t(0x80001000)));
81  CHECK_EQ(1, m.Call(uint32_t(0x40000500)));
82  CHECK_EQ(2, m.Call(uint32_t(0x20000300)));
83  CHECK_EQ(3, m.Call(uint32_t(0x10000003)));
84  CHECK_EQ(4, m.Call(uint32_t(0x08050000)));
85  CHECK_EQ(5, m.Call(uint32_t(0x04006000)));
86  CHECK_EQ(6, m.Call(uint32_t(0x02000000)));
87  CHECK_EQ(7, m.Call(uint32_t(0x010000a0)));
88  CHECK_EQ(8, m.Call(uint32_t(0x00800c00)));
89  CHECK_EQ(9, m.Call(uint32_t(0x00400000)));
90  CHECK_EQ(10, m.Call(uint32_t(0x0020000d)));
91  CHECK_EQ(11, m.Call(uint32_t(0x00100f00)));
92  CHECK_EQ(12, m.Call(uint32_t(0x00080000)));
93  CHECK_EQ(13, m.Call(uint32_t(0x00041000)));
94  CHECK_EQ(14, m.Call(uint32_t(0x00020020)));
95  CHECK_EQ(15, m.Call(uint32_t(0x00010300)));
96  CHECK_EQ(16, m.Call(uint32_t(0x00008040)));
97  CHECK_EQ(17, m.Call(uint32_t(0x00004005)));
98  CHECK_EQ(18, m.Call(uint32_t(0x00002050)));
99  CHECK_EQ(19, m.Call(uint32_t(0x00001700)));
100  CHECK_EQ(20, m.Call(uint32_t(0x00000870)));
101  CHECK_EQ(21, m.Call(uint32_t(0x00000405)));
102  CHECK_EQ(22, m.Call(uint32_t(0x00000203)));
103  CHECK_EQ(23, m.Call(uint32_t(0x00000101)));
104  CHECK_EQ(24, m.Call(uint32_t(0x00000089)));
105  CHECK_EQ(25, m.Call(uint32_t(0x00000041)));
106  CHECK_EQ(26, m.Call(uint32_t(0x00000022)));
107  CHECK_EQ(27, m.Call(uint32_t(0x00000013)));
108  CHECK_EQ(28, m.Call(uint32_t(0x00000008)));
109  CHECK_EQ(29, m.Call(uint32_t(0x00000004)));
110  CHECK_EQ(30, m.Call(uint32_t(0x00000002)));
111  CHECK_EQ(31, m.Call(uint32_t(0x00000001)));
112  CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
113}
114
115
116TEST(RunWord32Popcnt) {
117  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
118  if (!m.machine()->Word32Popcnt().IsSupported()) {
119    // We can only test the operator if it exists on the testing platform.
120    return;
121  }
122  m.Return(m.AddNode(m.machine()->Word32Popcnt().op(), m.Parameter(0)));
123
124  CHECK_EQ(0, m.Call(uint32_t(0x00000000)));
125  CHECK_EQ(1, m.Call(uint32_t(0x00000001)));
126  CHECK_EQ(1, m.Call(uint32_t(0x80000000)));
127  CHECK_EQ(32, m.Call(uint32_t(0xffffffff)));
128  CHECK_EQ(6, m.Call(uint32_t(0x000dc100)));
129  CHECK_EQ(9, m.Call(uint32_t(0xe00dc100)));
130  CHECK_EQ(11, m.Call(uint32_t(0xe00dc103)));
131  CHECK_EQ(9, m.Call(uint32_t(0x000dc107)));
132}
133
134
135#if V8_TARGET_ARCH_64_BIT
136TEST(RunWord64Clz) {
137  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
138  m.Return(m.Word64Clz(m.Parameter(0)));
139
140  CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000)));
141  CHECK_EQ(1, m.Call(uint64_t(0x4000050000000000)));
142  CHECK_EQ(2, m.Call(uint64_t(0x2000030000000000)));
143  CHECK_EQ(3, m.Call(uint64_t(0x1000000300000000)));
144  CHECK_EQ(4, m.Call(uint64_t(0x0805000000000000)));
145  CHECK_EQ(5, m.Call(uint64_t(0x0400600000000000)));
146  CHECK_EQ(6, m.Call(uint64_t(0x0200000000000000)));
147  CHECK_EQ(7, m.Call(uint64_t(0x010000a000000000)));
148  CHECK_EQ(8, m.Call(uint64_t(0x00800c0000000000)));
149  CHECK_EQ(9, m.Call(uint64_t(0x0040000000000000)));
150  CHECK_EQ(10, m.Call(uint64_t(0x0020000d00000000)));
151  CHECK_EQ(11, m.Call(uint64_t(0x00100f0000000000)));
152  CHECK_EQ(12, m.Call(uint64_t(0x0008000000000000)));
153  CHECK_EQ(13, m.Call(uint64_t(0x0004100000000000)));
154  CHECK_EQ(14, m.Call(uint64_t(0x0002002000000000)));
155  CHECK_EQ(15, m.Call(uint64_t(0x0001030000000000)));
156  CHECK_EQ(16, m.Call(uint64_t(0x0000804000000000)));
157  CHECK_EQ(17, m.Call(uint64_t(0x0000400500000000)));
158  CHECK_EQ(18, m.Call(uint64_t(0x0000205000000000)));
159  CHECK_EQ(19, m.Call(uint64_t(0x0000170000000000)));
160  CHECK_EQ(20, m.Call(uint64_t(0x0000087000000000)));
161  CHECK_EQ(21, m.Call(uint64_t(0x0000040500000000)));
162  CHECK_EQ(22, m.Call(uint64_t(0x0000020300000000)));
163  CHECK_EQ(23, m.Call(uint64_t(0x0000010100000000)));
164  CHECK_EQ(24, m.Call(uint64_t(0x0000008900000000)));
165  CHECK_EQ(25, m.Call(uint64_t(0x0000004100000000)));
166  CHECK_EQ(26, m.Call(uint64_t(0x0000002200000000)));
167  CHECK_EQ(27, m.Call(uint64_t(0x0000001300000000)));
168  CHECK_EQ(28, m.Call(uint64_t(0x0000000800000000)));
169  CHECK_EQ(29, m.Call(uint64_t(0x0000000400000000)));
170  CHECK_EQ(30, m.Call(uint64_t(0x0000000200000000)));
171  CHECK_EQ(31, m.Call(uint64_t(0x0000000100000000)));
172  CHECK_EQ(32, m.Call(uint64_t(0x0000000080001000)));
173  CHECK_EQ(33, m.Call(uint64_t(0x0000000040000500)));
174  CHECK_EQ(34, m.Call(uint64_t(0x0000000020000300)));
175  CHECK_EQ(35, m.Call(uint64_t(0x0000000010000003)));
176  CHECK_EQ(36, m.Call(uint64_t(0x0000000008050000)));
177  CHECK_EQ(37, m.Call(uint64_t(0x0000000004006000)));
178  CHECK_EQ(38, m.Call(uint64_t(0x0000000002000000)));
179  CHECK_EQ(39, m.Call(uint64_t(0x00000000010000a0)));
180  CHECK_EQ(40, m.Call(uint64_t(0x0000000000800c00)));
181  CHECK_EQ(41, m.Call(uint64_t(0x0000000000400000)));
182  CHECK_EQ(42, m.Call(uint64_t(0x000000000020000d)));
183  CHECK_EQ(43, m.Call(uint64_t(0x0000000000100f00)));
184  CHECK_EQ(44, m.Call(uint64_t(0x0000000000080000)));
185  CHECK_EQ(45, m.Call(uint64_t(0x0000000000041000)));
186  CHECK_EQ(46, m.Call(uint64_t(0x0000000000020020)));
187  CHECK_EQ(47, m.Call(uint64_t(0x0000000000010300)));
188  CHECK_EQ(48, m.Call(uint64_t(0x0000000000008040)));
189  CHECK_EQ(49, m.Call(uint64_t(0x0000000000004005)));
190  CHECK_EQ(50, m.Call(uint64_t(0x0000000000002050)));
191  CHECK_EQ(51, m.Call(uint64_t(0x0000000000001700)));
192  CHECK_EQ(52, m.Call(uint64_t(0x0000000000000870)));
193  CHECK_EQ(53, m.Call(uint64_t(0x0000000000000405)));
194  CHECK_EQ(54, m.Call(uint64_t(0x0000000000000203)));
195  CHECK_EQ(55, m.Call(uint64_t(0x0000000000000101)));
196  CHECK_EQ(56, m.Call(uint64_t(0x0000000000000089)));
197  CHECK_EQ(57, m.Call(uint64_t(0x0000000000000041)));
198  CHECK_EQ(58, m.Call(uint64_t(0x0000000000000022)));
199  CHECK_EQ(59, m.Call(uint64_t(0x0000000000000013)));
200  CHECK_EQ(60, m.Call(uint64_t(0x0000000000000008)));
201  CHECK_EQ(61, m.Call(uint64_t(0x0000000000000004)));
202  CHECK_EQ(62, m.Call(uint64_t(0x0000000000000002)));
203  CHECK_EQ(63, m.Call(uint64_t(0x0000000000000001)));
204  CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
205}
206
207
208TEST(RunWord64Ctz) {
209  RawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
210  if (!m.machine()->Word64Ctz().IsSupported()) {
211    return;
212  }
213
214  m.Return(m.AddNode(m.machine()->Word64Ctz().op(), m.Parameter(0)));
215
216  CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
217  CHECK_EQ(63, m.Call(uint64_t(0x8000000000000000)));
218  CHECK_EQ(62, m.Call(uint64_t(0x4000000000000000)));
219  CHECK_EQ(61, m.Call(uint64_t(0x2000000000000000)));
220  CHECK_EQ(60, m.Call(uint64_t(0x1000000000000000)));
221  CHECK_EQ(59, m.Call(uint64_t(0xa800000000000000)));
222  CHECK_EQ(58, m.Call(uint64_t(0xf400000000000000)));
223  CHECK_EQ(57, m.Call(uint64_t(0x6200000000000000)));
224  CHECK_EQ(56, m.Call(uint64_t(0x9100000000000000)));
225  CHECK_EQ(55, m.Call(uint64_t(0xcd80000000000000)));
226  CHECK_EQ(54, m.Call(uint64_t(0x0940000000000000)));
227  CHECK_EQ(53, m.Call(uint64_t(0xaf20000000000000)));
228  CHECK_EQ(52, m.Call(uint64_t(0xac10000000000000)));
229  CHECK_EQ(51, m.Call(uint64_t(0xe0b8000000000000)));
230  CHECK_EQ(50, m.Call(uint64_t(0x9ce4000000000000)));
231  CHECK_EQ(49, m.Call(uint64_t(0xc792000000000000)));
232  CHECK_EQ(48, m.Call(uint64_t(0xb8f1000000000000)));
233  CHECK_EQ(47, m.Call(uint64_t(0x3b9f800000000000)));
234  CHECK_EQ(46, m.Call(uint64_t(0xdb4c400000000000)));
235  CHECK_EQ(45, m.Call(uint64_t(0xe9a3200000000000)));
236  CHECK_EQ(44, m.Call(uint64_t(0xfca6100000000000)));
237  CHECK_EQ(43, m.Call(uint64_t(0x6c8a780000000000)));
238  CHECK_EQ(42, m.Call(uint64_t(0x8ce5a40000000000)));
239  CHECK_EQ(41, m.Call(uint64_t(0xcb7d020000000000)));
240  CHECK_EQ(40, m.Call(uint64_t(0xcb4dc10000000000)));
241  CHECK_EQ(39, m.Call(uint64_t(0xdfbec58000000000)));
242  CHECK_EQ(38, m.Call(uint64_t(0x27a9db4000000000)));
243  CHECK_EQ(37, m.Call(uint64_t(0xde3bcb2000000000)));
244  CHECK_EQ(36, m.Call(uint64_t(0xd7e8a61000000000)));
245  CHECK_EQ(35, m.Call(uint64_t(0x9afdbc8800000000)));
246  CHECK_EQ(34, m.Call(uint64_t(0x9afdbc8400000000)));
247  CHECK_EQ(33, m.Call(uint64_t(0x9afdbc8200000000)));
248  CHECK_EQ(32, m.Call(uint64_t(0x9afdbc8100000000)));
249  CHECK_EQ(31, m.Call(uint64_t(0x0000000080000000)));
250  CHECK_EQ(30, m.Call(uint64_t(0x0000000040000000)));
251  CHECK_EQ(29, m.Call(uint64_t(0x0000000020000000)));
252  CHECK_EQ(28, m.Call(uint64_t(0x0000000010000000)));
253  CHECK_EQ(27, m.Call(uint64_t(0x00000000a8000000)));
254  CHECK_EQ(26, m.Call(uint64_t(0x00000000f4000000)));
255  CHECK_EQ(25, m.Call(uint64_t(0x0000000062000000)));
256  CHECK_EQ(24, m.Call(uint64_t(0x0000000091000000)));
257  CHECK_EQ(23, m.Call(uint64_t(0x00000000cd800000)));
258  CHECK_EQ(22, m.Call(uint64_t(0x0000000009400000)));
259  CHECK_EQ(21, m.Call(uint64_t(0x00000000af200000)));
260  CHECK_EQ(20, m.Call(uint64_t(0x00000000ac100000)));
261  CHECK_EQ(19, m.Call(uint64_t(0x00000000e0b80000)));
262  CHECK_EQ(18, m.Call(uint64_t(0x000000009ce40000)));
263  CHECK_EQ(17, m.Call(uint64_t(0x00000000c7920000)));
264  CHECK_EQ(16, m.Call(uint64_t(0x00000000b8f10000)));
265  CHECK_EQ(15, m.Call(uint64_t(0x000000003b9f8000)));
266  CHECK_EQ(14, m.Call(uint64_t(0x00000000db4c4000)));
267  CHECK_EQ(13, m.Call(uint64_t(0x00000000e9a32000)));
268  CHECK_EQ(12, m.Call(uint64_t(0x00000000fca61000)));
269  CHECK_EQ(11, m.Call(uint64_t(0x000000006c8a7800)));
270  CHECK_EQ(10, m.Call(uint64_t(0x000000008ce5a400)));
271  CHECK_EQ(9, m.Call(uint64_t(0x00000000cb7d0200)));
272  CHECK_EQ(8, m.Call(uint64_t(0x00000000cb4dc100)));
273  CHECK_EQ(7, m.Call(uint64_t(0x00000000dfbec580)));
274  CHECK_EQ(6, m.Call(uint64_t(0x0000000027a9db40)));
275  CHECK_EQ(5, m.Call(uint64_t(0x00000000de3bcb20)));
276  CHECK_EQ(4, m.Call(uint64_t(0x00000000d7e8a610)));
277  CHECK_EQ(3, m.Call(uint64_t(0x000000009afdbc88)));
278  CHECK_EQ(2, m.Call(uint64_t(0x000000009afdbc84)));
279  CHECK_EQ(1, m.Call(uint64_t(0x000000009afdbc82)));
280  CHECK_EQ(0, m.Call(uint64_t(0x000000009afdbc81)));
281}
282
283
284TEST(RunWord64Popcnt) {
285  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
286  if (!m.machine()->Word64Popcnt().IsSupported()) {
287    return;
288  }
289
290  m.Return(m.AddNode(m.machine()->Word64Popcnt().op(), m.Parameter(0)));
291
292  CHECK_EQ(0, m.Call(uint64_t(0x0000000000000000)));
293  CHECK_EQ(1, m.Call(uint64_t(0x0000000000000001)));
294  CHECK_EQ(1, m.Call(uint64_t(0x8000000000000000)));
295  CHECK_EQ(64, m.Call(uint64_t(0xffffffffffffffff)));
296  CHECK_EQ(12, m.Call(uint64_t(0x000dc100000dc100)));
297  CHECK_EQ(18, m.Call(uint64_t(0xe00dc100e00dc100)));
298  CHECK_EQ(22, m.Call(uint64_t(0xe00dc103e00dc103)));
299  CHECK_EQ(18, m.Call(uint64_t(0x000dc107000dc107)));
300}
301#endif  // V8_TARGET_ARCH_64_BIT
302
303
304static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
305  switch (index) {
306    case 0:
307      return m->Parameter(0);
308    case 1:
309      return m->Parameter(1);
310    case 2:
311      return m->Int32Constant(0);
312    case 3:
313      return m->Int32Constant(1);
314    case 4:
315      return m->Int32Constant(-1);
316    case 5:
317      return m->Int32Constant(0xff);
318    case 6:
319      return m->Int32Constant(0x01234567);
320    case 7:
321      return m->Load(MachineType::Int32(), m->PointerConstant(NULL));
322    default:
323      return NULL;
324  }
325}
326
327
328TEST(CodeGenInt32Binop) {
329  RawMachineAssemblerTester<void> m;
330
331  const Operator* kOps[] = {
332      m.machine()->Word32And(),      m.machine()->Word32Or(),
333      m.machine()->Word32Xor(),      m.machine()->Word32Shl(),
334      m.machine()->Word32Shr(),      m.machine()->Word32Sar(),
335      m.machine()->Word32Equal(),    m.machine()->Int32Add(),
336      m.machine()->Int32Sub(),       m.machine()->Int32Mul(),
337      m.machine()->Int32MulHigh(),   m.machine()->Int32Div(),
338      m.machine()->Uint32Div(),      m.machine()->Int32Mod(),
339      m.machine()->Uint32Mod(),      m.machine()->Uint32MulHigh(),
340      m.machine()->Int32LessThan(),  m.machine()->Int32LessThanOrEqual(),
341      m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
342
343  for (size_t i = 0; i < arraysize(kOps); ++i) {
344    for (int j = 0; j < 8; j++) {
345      for (int k = 0; k < 8; k++) {
346        RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
347                                             MachineType::Int32());
348        Node* a = Int32Input(&m, j);
349        Node* b = Int32Input(&m, k);
350        m.Return(m.AddNode(kOps[i], a, b));
351        m.GenerateCode();
352      }
353    }
354  }
355}
356
357
358TEST(CodeGenNop) {
359  RawMachineAssemblerTester<void> m;
360  m.Return(m.Int32Constant(0));
361  m.GenerateCode();
362}
363
364
365#if V8_TARGET_ARCH_64_BIT
366static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
367  switch (index) {
368    case 0:
369      return m->Parameter(0);
370    case 1:
371      return m->Parameter(1);
372    case 2:
373      return m->Int64Constant(0);
374    case 3:
375      return m->Int64Constant(1);
376    case 4:
377      return m->Int64Constant(-1);
378    case 5:
379      return m->Int64Constant(0xff);
380    case 6:
381      return m->Int64Constant(0x0123456789abcdefLL);
382    case 7:
383      return m->Load(MachineType::Int64(), m->PointerConstant(NULL));
384    default:
385      return NULL;
386  }
387}
388
389
390TEST(CodeGenInt64Binop) {
391  RawMachineAssemblerTester<void> m;
392
393  const Operator* kOps[] = {
394      m.machine()->Word64And(), m.machine()->Word64Or(),
395      m.machine()->Word64Xor(), m.machine()->Word64Shl(),
396      m.machine()->Word64Shr(), m.machine()->Word64Sar(),
397      m.machine()->Word64Equal(), m.machine()->Int64Add(),
398      m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
399      m.machine()->Uint64Div(), m.machine()->Int64Mod(),
400      m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
401      m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
402      m.machine()->Uint64LessThanOrEqual()};
403
404  for (size_t i = 0; i < arraysize(kOps); ++i) {
405    for (int j = 0; j < 8; j++) {
406      for (int k = 0; k < 8; k++) {
407        RawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
408                                             MachineType::Int64());
409        Node* a = Int64Input(&m, j);
410        Node* b = Int64Input(&m, k);
411        m.Return(m.AddNode(kOps[i], a, b));
412        m.GenerateCode();
413      }
414    }
415  }
416}
417
418
419TEST(RunInt64AddWithOverflowP) {
420  int64_t actual_val = -1;
421  RawMachineAssemblerTester<int32_t> m;
422  Int64BinopTester bt(&m);
423  Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
424  Node* val = m.Projection(0, add);
425  Node* ovf = m.Projection(1, add);
426  m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
427  bt.AddReturn(ovf);
428  FOR_INT64_INPUTS(i) {
429    FOR_INT64_INPUTS(j) {
430      int64_t expected_val;
431      int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
432      CHECK_EQ(expected_ovf, bt.call(*i, *j));
433      CHECK_EQ(expected_val, actual_val);
434    }
435  }
436}
437
438
439TEST(RunInt64AddWithOverflowImm) {
440  int64_t actual_val = -1, expected_val = 0;
441  FOR_INT64_INPUTS(i) {
442    {
443      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
444      Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0));
445      Node* val = m.Projection(0, add);
446      Node* ovf = m.Projection(1, add);
447      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
448      m.Return(ovf);
449      FOR_INT64_INPUTS(j) {
450        int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
451        CHECK_EQ(expected_ovf, m.Call(*j));
452        CHECK_EQ(expected_val, actual_val);
453      }
454    }
455    {
456      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
457      Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i));
458      Node* val = m.Projection(0, add);
459      Node* ovf = m.Projection(1, add);
460      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
461      m.Return(ovf);
462      FOR_INT64_INPUTS(j) {
463        int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
464        CHECK_EQ(expected_ovf, m.Call(*j));
465        CHECK_EQ(expected_val, actual_val);
466      }
467    }
468    FOR_INT64_INPUTS(j) {
469      RawMachineAssemblerTester<int32_t> m;
470      Node* add =
471          m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
472      Node* val = m.Projection(0, add);
473      Node* ovf = m.Projection(1, add);
474      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
475      m.Return(ovf);
476      int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
477      CHECK_EQ(expected_ovf, m.Call());
478      CHECK_EQ(expected_val, actual_val);
479    }
480  }
481}
482
483
484TEST(RunInt64AddWithOverflowInBranchP) {
485  int constant = 911777;
486  RawMachineLabel blocka, blockb;
487  RawMachineAssemblerTester<int32_t> m;
488  Int64BinopTester bt(&m);
489  Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
490  Node* ovf = m.Projection(1, add);
491  m.Branch(ovf, &blocka, &blockb);
492  m.Bind(&blocka);
493  bt.AddReturn(m.Int64Constant(constant));
494  m.Bind(&blockb);
495  Node* val = m.Projection(0, add);
496  Node* truncated = m.TruncateInt64ToInt32(val);
497  bt.AddReturn(truncated);
498  FOR_INT64_INPUTS(i) {
499    FOR_INT64_INPUTS(j) {
500      int32_t expected = constant;
501      int64_t result;
502      if (!bits::SignedAddOverflow64(*i, *j, &result)) {
503        expected = static_cast<int32_t>(result);
504      }
505      CHECK_EQ(expected, bt.call(*i, *j));
506    }
507  }
508}
509
510
511TEST(RunInt64SubWithOverflowP) {
512  int64_t actual_val = -1;
513  RawMachineAssemblerTester<int32_t> m;
514  Int64BinopTester bt(&m);
515  Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1);
516  Node* val = m.Projection(0, add);
517  Node* ovf = m.Projection(1, add);
518  m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
519  bt.AddReturn(ovf);
520  FOR_INT64_INPUTS(i) {
521    FOR_INT64_INPUTS(j) {
522      int64_t expected_val;
523      int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
524      CHECK_EQ(expected_ovf, bt.call(*i, *j));
525      CHECK_EQ(expected_val, actual_val);
526    }
527  }
528}
529
530
531TEST(RunInt64SubWithOverflowImm) {
532  int64_t actual_val = -1, expected_val = 0;
533  FOR_INT64_INPUTS(i) {
534    {
535      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
536      Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0));
537      Node* val = m.Projection(0, add);
538      Node* ovf = m.Projection(1, add);
539      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
540      m.Return(ovf);
541      FOR_INT64_INPUTS(j) {
542        int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
543        CHECK_EQ(expected_ovf, m.Call(*j));
544        CHECK_EQ(expected_val, actual_val);
545      }
546    }
547    {
548      RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
549      Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i));
550      Node* val = m.Projection(0, add);
551      Node* ovf = m.Projection(1, add);
552      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
553      m.Return(ovf);
554      FOR_INT64_INPUTS(j) {
555        int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val);
556        CHECK_EQ(expected_ovf, m.Call(*j));
557        CHECK_EQ(expected_val, actual_val);
558      }
559    }
560    FOR_INT64_INPUTS(j) {
561      RawMachineAssemblerTester<int32_t> m;
562      Node* add =
563          m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
564      Node* val = m.Projection(0, add);
565      Node* ovf = m.Projection(1, add);
566      m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
567      m.Return(ovf);
568      int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
569      CHECK_EQ(expected_ovf, m.Call());
570      CHECK_EQ(expected_val, actual_val);
571    }
572  }
573}
574
575
576TEST(RunInt64SubWithOverflowInBranchP) {
577  int constant = 911999;
578  RawMachineLabel blocka, blockb;
579  RawMachineAssemblerTester<int32_t> m;
580  Int64BinopTester bt(&m);
581  Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1);
582  Node* ovf = m.Projection(1, sub);
583  m.Branch(ovf, &blocka, &blockb);
584  m.Bind(&blocka);
585  bt.AddReturn(m.Int64Constant(constant));
586  m.Bind(&blockb);
587  Node* val = m.Projection(0, sub);
588  Node* truncated = m.TruncateInt64ToInt32(val);
589  bt.AddReturn(truncated);
590  FOR_INT64_INPUTS(i) {
591    FOR_INT64_INPUTS(j) {
592      int32_t expected = constant;
593      int64_t result;
594      if (!bits::SignedSubOverflow64(*i, *j, &result)) {
595        expected = static_cast<int32_t>(result);
596      }
597      CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j)));
598    }
599  }
600}
601
602
603// TODO(titzer): add tests that run 64-bit integer operations.
604#endif  // V8_TARGET_ARCH_64_BIT
605
606
607TEST(RunGoto) {
608  RawMachineAssemblerTester<int32_t> m;
609  int constant = 99999;
610
611  RawMachineLabel next;
612  m.Goto(&next);
613  m.Bind(&next);
614  m.Return(m.Int32Constant(constant));
615
616  CHECK_EQ(constant, m.Call());
617}
618
619
620TEST(RunGotoMultiple) {
621  RawMachineAssemblerTester<int32_t> m;
622  int constant = 9999977;
623
624  RawMachineLabel labels[10];
625  for (size_t i = 0; i < arraysize(labels); i++) {
626    m.Goto(&labels[i]);
627    m.Bind(&labels[i]);
628  }
629  m.Return(m.Int32Constant(constant));
630
631  CHECK_EQ(constant, m.Call());
632}
633
634
635TEST(RunBranch) {
636  RawMachineAssemblerTester<int32_t> m;
637  int constant = 999777;
638
639  RawMachineLabel blocka, blockb;
640  m.Branch(m.Int32Constant(0), &blocka, &blockb);
641  m.Bind(&blocka);
642  m.Return(m.Int32Constant(0 - constant));
643  m.Bind(&blockb);
644  m.Return(m.Int32Constant(constant));
645
646  CHECK_EQ(constant, m.Call());
647}
648
649
650TEST(RunDiamond2) {
651  RawMachineAssemblerTester<int32_t> m;
652
653  int constant = 995666;
654
655  RawMachineLabel blocka, blockb, end;
656  m.Branch(m.Int32Constant(0), &blocka, &blockb);
657  m.Bind(&blocka);
658  m.Goto(&end);
659  m.Bind(&blockb);
660  m.Goto(&end);
661  m.Bind(&end);
662  m.Return(m.Int32Constant(constant));
663
664  CHECK_EQ(constant, m.Call());
665}
666
667
668TEST(RunLoop) {
669  RawMachineAssemblerTester<int32_t> m;
670  int constant = 999555;
671
672  RawMachineLabel header, body, exit;
673  m.Goto(&header);
674  m.Bind(&header);
675  m.Branch(m.Int32Constant(0), &body, &exit);
676  m.Bind(&body);
677  m.Goto(&header);
678  m.Bind(&exit);
679  m.Return(m.Int32Constant(constant));
680
681  CHECK_EQ(constant, m.Call());
682}
683
684
685template <typename R>
686static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
687                            MachineRepresentation rep, Node* true_node,
688                            Node* false_node) {
689  RawMachineLabel blocka, blockb, end;
690  m->Branch(cond_node, &blocka, &blockb);
691  m->Bind(&blocka);
692  m->Goto(&end);
693  m->Bind(&blockb);
694  m->Goto(&end);
695
696  m->Bind(&end);
697  Node* phi = m->Phi(rep, true_node, false_node);
698  m->Return(phi);
699}
700
701
702TEST(RunDiamondPhiConst) {
703  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
704  int false_val = 0xFF666;
705  int true_val = 0x00DDD;
706  Node* true_node = m.Int32Constant(true_val);
707  Node* false_node = m.Int32Constant(false_val);
708  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node,
709                  false_node);
710  CHECK_EQ(false_val, m.Call(0));
711  CHECK_EQ(true_val, m.Call(1));
712}
713
714
715TEST(RunDiamondPhiNumber) {
716  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
717  double false_val = -11.1;
718  double true_val = 200.1;
719  Node* true_node = m.NumberConstant(true_val);
720  Node* false_node = m.NumberConstant(false_val);
721  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
722                  false_node);
723  m.CheckNumber(false_val, m.Call(0));
724  m.CheckNumber(true_val, m.Call(1));
725}
726
727
728TEST(RunDiamondPhiString) {
729  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
730  const char* false_val = "false";
731  const char* true_val = "true";
732  Node* true_node = m.StringConstant(true_val);
733  Node* false_node = m.StringConstant(false_val);
734  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
735                  false_node);
736  m.CheckString(false_val, m.Call(0));
737  m.CheckString(true_val, m.Call(1));
738}
739
740
741TEST(RunDiamondPhiParam) {
742  RawMachineAssemblerTester<int32_t> m(
743      MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
744  BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32,
745                  m.Parameter(1), m.Parameter(2));
746  int32_t c1 = 0x260cb75a;
747  int32_t c2 = 0xcd3e9c8b;
748  int result = m.Call(0, c1, c2);
749  CHECK_EQ(c2, result);
750  result = m.Call(1, c1, c2);
751  CHECK_EQ(c1, result);
752}
753
754
755TEST(RunLoopPhiConst) {
756  RawMachineAssemblerTester<int32_t> m;
757  int true_val = 0x44000;
758  int false_val = 0x00888;
759
760  Node* cond_node = m.Int32Constant(0);
761  Node* true_node = m.Int32Constant(true_val);
762  Node* false_node = m.Int32Constant(false_val);
763
764  // x = false_val; while(false) { x = true_val; } return x;
765  RawMachineLabel body, header, end;
766
767  m.Goto(&header);
768  m.Bind(&header);
769  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node);
770  m.Branch(cond_node, &body, &end);
771  m.Bind(&body);
772  m.Goto(&header);
773  m.Bind(&end);
774  m.Return(phi);
775
776  CHECK_EQ(false_val, m.Call());
777}
778
779
780TEST(RunLoopPhiParam) {
781  RawMachineAssemblerTester<int32_t> m(
782      MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
783
784  RawMachineLabel blocka, blockb, end;
785
786  m.Goto(&blocka);
787
788  m.Bind(&blocka);
789  Node* phi =
790      m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2));
791  Node* cond =
792      m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0));
793  m.Branch(cond, &blockb, &end);
794
795  m.Bind(&blockb);
796  m.Goto(&blocka);
797
798  m.Bind(&end);
799  m.Return(phi);
800
801  int32_t c1 = 0xa81903b4;
802  int32_t c2 = 0x5a1207da;
803  int result = m.Call(0, c1, c2);
804  CHECK_EQ(c1, result);
805  result = m.Call(1, c1, c2);
806  CHECK_EQ(c2, result);
807}
808
809
810TEST(RunLoopPhiInduction) {
811  RawMachineAssemblerTester<int32_t> m;
812
813  int false_val = 0x10777;
814
815  // x = false_val; while(false) { x++; } return x;
816  RawMachineLabel header, body, end;
817  Node* false_node = m.Int32Constant(false_val);
818
819  m.Goto(&header);
820
821  m.Bind(&header);
822  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
823  m.Branch(m.Int32Constant(0), &body, &end);
824
825  m.Bind(&body);
826  Node* add = m.Int32Add(phi, m.Int32Constant(1));
827  phi->ReplaceInput(1, add);
828  m.Goto(&header);
829
830  m.Bind(&end);
831  m.Return(phi);
832
833  CHECK_EQ(false_val, m.Call());
834}
835
836
837TEST(RunLoopIncrement) {
838  RawMachineAssemblerTester<int32_t> m;
839  Int32BinopTester bt(&m);
840
841  // x = 0; while(x ^ param) { x++; } return x;
842  RawMachineLabel header, body, end;
843  Node* zero = m.Int32Constant(0);
844
845  m.Goto(&header);
846
847  m.Bind(&header);
848  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
849  m.Branch(m.WordXor(phi, bt.param0), &body, &end);
850
851  m.Bind(&body);
852  phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
853  m.Goto(&header);
854
855  m.Bind(&end);
856  bt.AddReturn(phi);
857
858  CHECK_EQ(11, bt.call(11, 0));
859  CHECK_EQ(110, bt.call(110, 0));
860  CHECK_EQ(176, bt.call(176, 0));
861}
862
863
864TEST(RunLoopIncrement2) {
865  RawMachineAssemblerTester<int32_t> m;
866  Int32BinopTester bt(&m);
867
868  // x = 0; while(x < param) { x++; } return x;
869  RawMachineLabel header, body, end;
870  Node* zero = m.Int32Constant(0);
871
872  m.Goto(&header);
873
874  m.Bind(&header);
875  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
876  m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end);
877
878  m.Bind(&body);
879  phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
880  m.Goto(&header);
881
882  m.Bind(&end);
883  bt.AddReturn(phi);
884
885  CHECK_EQ(11, bt.call(11, 0));
886  CHECK_EQ(110, bt.call(110, 0));
887  CHECK_EQ(176, bt.call(176, 0));
888  CHECK_EQ(0, bt.call(-200, 0));
889}
890
891
892TEST(RunLoopIncrement3) {
893  RawMachineAssemblerTester<int32_t> m;
894  Int32BinopTester bt(&m);
895
896  // x = 0; while(x < param) { x++; } return x;
897  RawMachineLabel header, body, end;
898  Node* zero = m.Int32Constant(0);
899
900  m.Goto(&header);
901
902  m.Bind(&header);
903  Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
904  m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end);
905
906  m.Bind(&body);
907  phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
908  m.Goto(&header);
909
910  m.Bind(&end);
911  bt.AddReturn(phi);
912
913  CHECK_EQ(11, bt.call(11, 0));
914  CHECK_EQ(110, bt.call(110, 0));
915  CHECK_EQ(176, bt.call(176, 0));
916  CHECK_EQ(200, bt.call(200, 0));
917}
918
919
920TEST(RunLoopDecrement) {
921  RawMachineAssemblerTester<int32_t> m;
922  Int32BinopTester bt(&m);
923
924  // x = param; while(x) { x--; } return x;
925  RawMachineLabel header, body, end;
926
927  m.Goto(&header);
928
929  m.Bind(&header);
930  Node* phi =
931      m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0));
932  m.Branch(phi, &body, &end);
933
934  m.Bind(&body);
935  phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
936  m.Goto(&header);
937
938  m.Bind(&end);
939  bt.AddReturn(phi);
940
941  CHECK_EQ(0, bt.call(11, 0));
942  CHECK_EQ(0, bt.call(110, 0));
943  CHECK_EQ(0, bt.call(197, 0));
944}
945
946
947TEST(RunLoopIncrementFloat32) {
948  RawMachineAssemblerTester<int32_t> m;
949
950  // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
951  RawMachineLabel header, body, end;
952  Node* minus_3 = m.Float32Constant(-3.0f);
953  Node* ten = m.Float32Constant(10.0f);
954
955  m.Goto(&header);
956
957  m.Bind(&header);
958  Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten);
959  m.Branch(m.Float32LessThan(phi, ten), &body, &end);
960
961  m.Bind(&body);
962  phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
963  m.Goto(&header);
964
965  m.Bind(&end);
966  m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
967
968  CHECK_EQ(10, m.Call());
969}
970
971
972TEST(RunLoopIncrementFloat64) {
973  RawMachineAssemblerTester<int32_t> m;
974
975  // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
976  RawMachineLabel header, body, end;
977  Node* minus_3 = m.Float64Constant(-3.0);
978  Node* ten = m.Float64Constant(10.0);
979
980  m.Goto(&header);
981
982  m.Bind(&header);
983  Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten);
984  m.Branch(m.Float64LessThan(phi, ten), &body, &end);
985
986  m.Bind(&body);
987  phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
988  m.Goto(&header);
989
990  m.Bind(&end);
991  m.Return(m.ChangeFloat64ToInt32(phi));
992
993  CHECK_EQ(10, m.Call());
994}
995
996
997TEST(RunSwitch1) {
998  RawMachineAssemblerTester<int32_t> m;
999
1000  int constant = 11223344;
1001
1002  RawMachineLabel block0, block1, def, end;
1003  RawMachineLabel* case_labels[] = {&block0, &block1};
1004  int32_t case_values[] = {0, 1};
1005  m.Switch(m.Int32Constant(0), &def, case_values, case_labels,
1006           arraysize(case_labels));
1007  m.Bind(&block0);
1008  m.Goto(&end);
1009  m.Bind(&block1);
1010  m.Goto(&end);
1011  m.Bind(&def);
1012  m.Goto(&end);
1013  m.Bind(&end);
1014  m.Return(m.Int32Constant(constant));
1015
1016  CHECK_EQ(constant, m.Call());
1017}
1018
1019
1020TEST(RunSwitch2) {
1021  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1022
1023  RawMachineLabel blocka, blockb, blockc;
1024  RawMachineLabel* case_labels[] = {&blocka, &blockb};
1025  int32_t case_values[] = {std::numeric_limits<int32_t>::min(),
1026                           std::numeric_limits<int32_t>::max()};
1027  m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1028           arraysize(case_labels));
1029  m.Bind(&blocka);
1030  m.Return(m.Int32Constant(-1));
1031  m.Bind(&blockb);
1032  m.Return(m.Int32Constant(1));
1033  m.Bind(&blockc);
1034  m.Return(m.Int32Constant(0));
1035
1036  CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max()));
1037  CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min()));
1038  for (int i = -100; i < 100; i += 25) {
1039    CHECK_EQ(0, m.Call(i));
1040  }
1041}
1042
1043
1044TEST(RunSwitch3) {
1045  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1046
1047  RawMachineLabel blocka, blockb, blockc;
1048  RawMachineLabel* case_labels[] = {&blocka, &blockb};
1049  int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0,
1050                           std::numeric_limits<int32_t>::min() + 1};
1051  m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1052           arraysize(case_labels));
1053  m.Bind(&blocka);
1054  m.Return(m.Int32Constant(0));
1055  m.Bind(&blockb);
1056  m.Return(m.Int32Constant(1));
1057  m.Bind(&blockc);
1058  m.Return(m.Int32Constant(2));
1059
1060  CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0));
1061  CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1));
1062  for (int i = -100; i < 100; i += 25) {
1063    CHECK_EQ(2, m.Call(i));
1064  }
1065}
1066
1067
1068TEST(RunSwitch4) {
1069  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1070
1071  const size_t kNumCases = 512;
1072  const size_t kNumValues = kNumCases + 1;
1073  int32_t values[kNumValues];
1074  m.main_isolate()->random_number_generator()->NextBytes(values,
1075                                                         sizeof(values));
1076  RawMachineLabel end, def;
1077  int32_t case_values[kNumCases];
1078  RawMachineLabel* case_labels[kNumCases];
1079  Node* results[kNumValues];
1080  for (size_t i = 0; i < kNumCases; ++i) {
1081    case_values[i] = static_cast<int32_t>(i);
1082    case_labels[i] =
1083        new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
1084  }
1085  m.Switch(m.Parameter(0), &def, case_values, case_labels,
1086           arraysize(case_labels));
1087  for (size_t i = 0; i < kNumCases; ++i) {
1088    m.Bind(case_labels[i]);
1089    results[i] = m.Int32Constant(values[i]);
1090    m.Goto(&end);
1091  }
1092  m.Bind(&def);
1093  results[kNumCases] = m.Int32Constant(values[kNumCases]);
1094  m.Goto(&end);
1095  m.Bind(&end);
1096  const int num_results = static_cast<int>(arraysize(results));
1097  Node* phi =
1098      m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results),
1099                num_results, results);
1100  m.Return(phi);
1101
1102  for (size_t i = 0; i < kNumValues; ++i) {
1103    CHECK_EQ(values[i], m.Call(static_cast<int>(i)));
1104  }
1105}
1106
1107
1108TEST(RunLoadInt32) {
1109  RawMachineAssemblerTester<int32_t> m;
1110
1111  int32_t p1 = 0;  // loads directly from this location.
1112  m.Return(m.LoadFromPointer(&p1, MachineType::Int32()));
1113
1114  FOR_INT32_INPUTS(i) {
1115    p1 = *i;
1116    CHECK_EQ(p1, m.Call());
1117  }
1118}
1119
1120
1121TEST(RunLoadInt32Offset) {
1122  int32_t p1 = 0;  // loads directly from this location.
1123
1124  int32_t offsets[] = {-2000000, -100, -101, 1,          3,
1125                       7,        120,  2000, 2000000000, 0xff};
1126
1127  for (size_t i = 0; i < arraysize(offsets); i++) {
1128    RawMachineAssemblerTester<int32_t> m;
1129    int32_t offset = offsets[i];
1130    byte* pointer = reinterpret_cast<byte*>(&p1) - offset;
1131    // generate load [#base + #index]
1132    m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset));
1133
1134    FOR_INT32_INPUTS(j) {
1135      p1 = *j;
1136      CHECK_EQ(p1, m.Call());
1137    }
1138  }
1139}
1140
1141
1142TEST(RunLoadStoreFloat32Offset) {
1143  float p1 = 0.0f;  // loads directly from this location.
1144  float p2 = 0.0f;  // and stores directly into this location.
1145
1146  FOR_INT32_INPUTS(i) {
1147    int32_t magic = 0x2342aabb + *i * 3;
1148    RawMachineAssemblerTester<int32_t> m;
1149    int32_t offset = *i;
1150    byte* from = reinterpret_cast<byte*>(&p1) - offset;
1151    byte* to = reinterpret_cast<byte*>(&p2) - offset;
1152    // generate load [#base + #index]
1153    Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from),
1154                        m.IntPtrConstant(offset));
1155    m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to),
1156            m.IntPtrConstant(offset), load, kNoWriteBarrier);
1157    m.Return(m.Int32Constant(magic));
1158
1159    FOR_FLOAT32_INPUTS(j) {
1160      p1 = *j;
1161      p2 = *j - 5;
1162      CHECK_EQ(magic, m.Call());
1163      CheckDoubleEq(p1, p2);
1164    }
1165  }
1166}
1167
1168
1169TEST(RunLoadStoreFloat64Offset) {
1170  double p1 = 0;  // loads directly from this location.
1171  double p2 = 0;  // and stores directly into this location.
1172
1173  FOR_INT32_INPUTS(i) {
1174    int32_t magic = 0x2342aabb + *i * 3;
1175    RawMachineAssemblerTester<int32_t> m;
1176    int32_t offset = *i;
1177    byte* from = reinterpret_cast<byte*>(&p1) - offset;
1178    byte* to = reinterpret_cast<byte*>(&p2) - offset;
1179    // generate load [#base + #index]
1180    Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from),
1181                        m.IntPtrConstant(offset));
1182    m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to),
1183            m.IntPtrConstant(offset), load, kNoWriteBarrier);
1184    m.Return(m.Int32Constant(magic));
1185
1186    FOR_FLOAT64_INPUTS(j) {
1187      p1 = *j;
1188      p2 = *j - 5;
1189      CHECK_EQ(magic, m.Call());
1190      CheckDoubleEq(p1, p2);
1191    }
1192  }
1193}
1194
1195
1196TEST(RunInt32AddP) {
1197  RawMachineAssemblerTester<int32_t> m;
1198  Int32BinopTester bt(&m);
1199
1200  bt.AddReturn(m.Int32Add(bt.param0, bt.param1));
1201
1202  FOR_INT32_INPUTS(i) {
1203    FOR_INT32_INPUTS(j) {
1204      // Use uint32_t because signed overflow is UB in C.
1205      int expected = static_cast<int32_t>(*i + *j);
1206      CHECK_EQ(expected, bt.call(*i, *j));
1207    }
1208  }
1209}
1210
1211
1212TEST(RunInt32AddAndWord32EqualP) {
1213  {
1214    RawMachineAssemblerTester<int32_t> m(
1215        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
1216    m.Return(m.Int32Add(m.Parameter(0),
1217                        m.Word32Equal(m.Parameter(1), m.Parameter(2))));
1218    FOR_INT32_INPUTS(i) {
1219      FOR_INT32_INPUTS(j) {
1220        FOR_INT32_INPUTS(k) {
1221          // Use uint32_t because signed overflow is UB in C.
1222          int32_t const expected =
1223              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1224          CHECK_EQ(expected, m.Call(*i, *j, *k));
1225        }
1226      }
1227    }
1228  }
1229  {
1230    RawMachineAssemblerTester<int32_t> m(
1231        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
1232    m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
1233                        m.Parameter(2)));
1234    FOR_INT32_INPUTS(i) {
1235      FOR_INT32_INPUTS(j) {
1236        FOR_INT32_INPUTS(k) {
1237          // Use uint32_t because signed overflow is UB in C.
1238          int32_t const expected =
1239              bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1240          CHECK_EQ(expected, m.Call(*i, *j, *k));
1241        }
1242      }
1243    }
1244  }
1245}
1246
1247
1248TEST(RunInt32AddAndWord32EqualImm) {
1249  {
1250    FOR_INT32_INPUTS(i) {
1251      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1252                                           MachineType::Int32());
1253      m.Return(m.Int32Add(m.Int32Constant(*i),
1254                          m.Word32Equal(m.Parameter(0), m.Parameter(1))));
1255      FOR_INT32_INPUTS(j) {
1256        FOR_INT32_INPUTS(k) {
1257          // Use uint32_t because signed overflow is UB in C.
1258          int32_t const expected =
1259              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1260          CHECK_EQ(expected, m.Call(*j, *k));
1261        }
1262      }
1263    }
1264  }
1265  {
1266    FOR_INT32_INPUTS(i) {
1267      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1268                                           MachineType::Int32());
1269      m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
1270                          m.Parameter(1)));
1271      FOR_INT32_INPUTS(j) {
1272        FOR_INT32_INPUTS(k) {
1273          // Use uint32_t because signed overflow is UB in C.
1274          int32_t const expected =
1275              bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1276          CHECK_EQ(expected, m.Call(*j, *k));
1277        }
1278      }
1279    }
1280  }
1281}
1282
1283
1284TEST(RunInt32AddAndWord32NotEqualP) {
1285  {
1286    RawMachineAssemblerTester<int32_t> m(
1287        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
1288    m.Return(m.Int32Add(m.Parameter(0),
1289                        m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
1290    FOR_INT32_INPUTS(i) {
1291      FOR_INT32_INPUTS(j) {
1292        FOR_INT32_INPUTS(k) {
1293          // Use uint32_t because signed overflow is UB in C.
1294          int32_t const expected =
1295              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1296          CHECK_EQ(expected, m.Call(*i, *j, *k));
1297        }
1298      }
1299    }
1300  }
1301  {
1302    RawMachineAssemblerTester<int32_t> m(
1303        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
1304    m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
1305                        m.Parameter(2)));
1306    FOR_INT32_INPUTS(i) {
1307      FOR_INT32_INPUTS(j) {
1308        FOR_INT32_INPUTS(k) {
1309          // Use uint32_t because signed overflow is UB in C.
1310          int32_t const expected =
1311              bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1312          CHECK_EQ(expected, m.Call(*i, *j, *k));
1313        }
1314      }
1315    }
1316  }
1317}
1318
1319
1320TEST(RunInt32AddAndWord32NotEqualImm) {
1321  {
1322    FOR_INT32_INPUTS(i) {
1323      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1324                                           MachineType::Int32());
1325      m.Return(m.Int32Add(m.Int32Constant(*i),
1326                          m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
1327      FOR_INT32_INPUTS(j) {
1328        FOR_INT32_INPUTS(k) {
1329          // Use uint32_t because signed overflow is UB in C.
1330          int32_t const expected =
1331              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1332          CHECK_EQ(expected, m.Call(*j, *k));
1333        }
1334      }
1335    }
1336  }
1337  {
1338    FOR_INT32_INPUTS(i) {
1339      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1340                                           MachineType::Int32());
1341      m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
1342                          m.Parameter(1)));
1343      FOR_INT32_INPUTS(j) {
1344        FOR_INT32_INPUTS(k) {
1345          // Use uint32_t because signed overflow is UB in C.
1346          int32_t const expected =
1347              bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1348          CHECK_EQ(expected, m.Call(*j, *k));
1349        }
1350      }
1351    }
1352  }
1353}
1354
1355
1356TEST(RunInt32AddAndWord32SarP) {
1357  {
1358    RawMachineAssemblerTester<int32_t> m(
1359        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1360    m.Return(m.Int32Add(m.Parameter(0),
1361                        m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1362    FOR_UINT32_INPUTS(i) {
1363      FOR_INT32_INPUTS(j) {
1364        FOR_UINT32_SHIFTS(shift) {
1365          // Use uint32_t because signed overflow is UB in C.
1366          int32_t expected = *i + (*j >> shift);
1367          CHECK_EQ(expected, m.Call(*i, *j, shift));
1368        }
1369      }
1370    }
1371  }
1372  {
1373    RawMachineAssemblerTester<int32_t> m(
1374        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
1375    m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1376                        m.Parameter(2)));
1377    FOR_INT32_INPUTS(i) {
1378      FOR_UINT32_SHIFTS(shift) {
1379        FOR_UINT32_INPUTS(k) {
1380          // Use uint32_t because signed overflow is UB in C.
1381          int32_t expected = (*i >> shift) + *k;
1382          CHECK_EQ(expected, m.Call(*i, shift, *k));
1383        }
1384      }
1385    }
1386  }
1387}
1388
1389
1390TEST(RunInt32AddAndWord32ShlP) {
1391  {
1392    RawMachineAssemblerTester<int32_t> m(
1393        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1394    m.Return(m.Int32Add(m.Parameter(0),
1395                        m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1396    FOR_UINT32_INPUTS(i) {
1397      FOR_INT32_INPUTS(j) {
1398        FOR_UINT32_SHIFTS(shift) {
1399          // Use uint32_t because signed overflow is UB in C.
1400          int32_t expected = *i + (*j << shift);
1401          CHECK_EQ(expected, m.Call(*i, *j, shift));
1402        }
1403      }
1404    }
1405  }
1406  {
1407    RawMachineAssemblerTester<int32_t> m(
1408        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
1409    m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1410                        m.Parameter(2)));
1411    FOR_INT32_INPUTS(i) {
1412      FOR_UINT32_SHIFTS(shift) {
1413        FOR_UINT32_INPUTS(k) {
1414          // Use uint32_t because signed overflow is UB in C.
1415          int32_t expected = (*i << shift) + *k;
1416          CHECK_EQ(expected, m.Call(*i, shift, *k));
1417        }
1418      }
1419    }
1420  }
1421}
1422
1423
1424TEST(RunInt32AddAndWord32ShrP) {
1425  {
1426    RawMachineAssemblerTester<int32_t> m(
1427        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
1428    m.Return(m.Int32Add(m.Parameter(0),
1429                        m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1430    FOR_UINT32_INPUTS(i) {
1431      FOR_UINT32_INPUTS(j) {
1432        FOR_UINT32_SHIFTS(shift) {
1433          // Use uint32_t because signed overflow is UB in C.
1434          int32_t expected = *i + (*j >> shift);
1435          CHECK_EQ(expected, m.Call(*i, *j, shift));
1436        }
1437      }
1438    }
1439  }
1440  {
1441    RawMachineAssemblerTester<int32_t> m(
1442        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
1443    m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1444                        m.Parameter(2)));
1445    FOR_UINT32_INPUTS(i) {
1446      FOR_UINT32_SHIFTS(shift) {
1447        FOR_UINT32_INPUTS(k) {
1448          // Use uint32_t because signed overflow is UB in C.
1449          int32_t expected = (*i >> shift) + *k;
1450          CHECK_EQ(expected, m.Call(*i, shift, *k));
1451        }
1452      }
1453    }
1454  }
1455}
1456
1457
1458TEST(RunInt32AddInBranch) {
1459  static const int32_t constant = 987654321;
1460  {
1461    RawMachineAssemblerTester<int32_t> m;
1462    Int32BinopTester bt(&m);
1463    RawMachineLabel blocka, blockb;
1464    m.Branch(
1465        m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1466        &blocka, &blockb);
1467    m.Bind(&blocka);
1468    bt.AddReturn(m.Int32Constant(constant));
1469    m.Bind(&blockb);
1470    bt.AddReturn(m.Int32Constant(0 - constant));
1471    FOR_UINT32_INPUTS(i) {
1472      FOR_UINT32_INPUTS(j) {
1473        int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
1474        CHECK_EQ(expected, bt.call(*i, *j));
1475      }
1476    }
1477  }
1478  {
1479    RawMachineAssemblerTester<int32_t> m;
1480    Int32BinopTester bt(&m);
1481    RawMachineLabel blocka, blockb;
1482    m.Branch(
1483        m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1484        &blocka, &blockb);
1485    m.Bind(&blocka);
1486    bt.AddReturn(m.Int32Constant(constant));
1487    m.Bind(&blockb);
1488    bt.AddReturn(m.Int32Constant(0 - constant));
1489    FOR_UINT32_INPUTS(i) {
1490      FOR_UINT32_INPUTS(j) {
1491        int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
1492        CHECK_EQ(expected, bt.call(*i, *j));
1493      }
1494    }
1495  }
1496  {
1497    FOR_UINT32_INPUTS(i) {
1498      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1499      RawMachineLabel blocka, blockb;
1500      m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1501                             m.Int32Constant(0)),
1502               &blocka, &blockb);
1503      m.Bind(&blocka);
1504      m.Return(m.Int32Constant(constant));
1505      m.Bind(&blockb);
1506      m.Return(m.Int32Constant(0 - constant));
1507      FOR_UINT32_INPUTS(j) {
1508        uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
1509        CHECK_EQ(expected, m.Call(*j));
1510      }
1511    }
1512  }
1513  {
1514    FOR_UINT32_INPUTS(i) {
1515      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1516      RawMachineLabel blocka, blockb;
1517      m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1518                                m.Int32Constant(0)),
1519               &blocka, &blockb);
1520      m.Bind(&blocka);
1521      m.Return(m.Int32Constant(constant));
1522      m.Bind(&blockb);
1523      m.Return(m.Int32Constant(0 - constant));
1524      FOR_UINT32_INPUTS(j) {
1525        uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
1526        CHECK_EQ(expected, m.Call(*j));
1527      }
1528    }
1529  }
1530  {
1531    RawMachineAssemblerTester<void> m;
1532    const Operator* shops[] = {m.machine()->Word32Sar(),
1533                               m.machine()->Word32Shl(),
1534                               m.machine()->Word32Shr()};
1535    for (size_t n = 0; n < arraysize(shops); n++) {
1536      RawMachineAssemblerTester<int32_t> m(
1537          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1538      RawMachineLabel blocka, blockb;
1539      m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
1540                                        m.AddNode(shops[n], m.Parameter(1),
1541                                                  m.Parameter(2))),
1542                             m.Int32Constant(0)),
1543               &blocka, &blockb);
1544      m.Bind(&blocka);
1545      m.Return(m.Int32Constant(constant));
1546      m.Bind(&blockb);
1547      m.Return(m.Int32Constant(0 - constant));
1548      FOR_UINT32_INPUTS(i) {
1549        FOR_INT32_INPUTS(j) {
1550          FOR_UINT32_SHIFTS(shift) {
1551            int32_t right;
1552            switch (shops[n]->opcode()) {
1553              default:
1554                UNREACHABLE();
1555              case IrOpcode::kWord32Sar:
1556                right = *j >> shift;
1557                break;
1558              case IrOpcode::kWord32Shl:
1559                right = *j << shift;
1560                break;
1561              case IrOpcode::kWord32Shr:
1562                right = static_cast<uint32_t>(*j) >> shift;
1563                break;
1564            }
1565            int32_t expected = ((*i + right) == 0) ? constant : 0 - constant;
1566            CHECK_EQ(expected, m.Call(*i, *j, shift));
1567          }
1568        }
1569      }
1570    }
1571  }
1572}
1573
1574
1575TEST(RunInt32AddInComparison) {
1576  {
1577    RawMachineAssemblerTester<int32_t> m;
1578    Uint32BinopTester bt(&m);
1579    bt.AddReturn(
1580        m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)));
1581    FOR_UINT32_INPUTS(i) {
1582      FOR_UINT32_INPUTS(j) {
1583        uint32_t expected = (*i + *j) == 0;
1584        CHECK_EQ(expected, bt.call(*i, *j));
1585      }
1586    }
1587  }
1588  {
1589    RawMachineAssemblerTester<int32_t> m;
1590    Uint32BinopTester bt(&m);
1591    bt.AddReturn(
1592        m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1)));
1593    FOR_UINT32_INPUTS(i) {
1594      FOR_UINT32_INPUTS(j) {
1595        uint32_t expected = (*i + *j) == 0;
1596        CHECK_EQ(expected, bt.call(*i, *j));
1597      }
1598    }
1599  }
1600  {
1601    FOR_UINT32_INPUTS(i) {
1602      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1603      m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1604                             m.Int32Constant(0)));
1605      FOR_UINT32_INPUTS(j) {
1606        uint32_t expected = (*i + *j) == 0;
1607        CHECK_EQ(expected, m.Call(*j));
1608      }
1609    }
1610  }
1611  {
1612    FOR_UINT32_INPUTS(i) {
1613      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1614      m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
1615                             m.Int32Constant(0)));
1616      FOR_UINT32_INPUTS(j) {
1617        uint32_t expected = (*j + *i) == 0;
1618        CHECK_EQ(expected, m.Call(*j));
1619      }
1620    }
1621  }
1622  {
1623    RawMachineAssemblerTester<void> m;
1624    const Operator* shops[] = {m.machine()->Word32Sar(),
1625                               m.machine()->Word32Shl(),
1626                               m.machine()->Word32Shr()};
1627    for (size_t n = 0; n < arraysize(shops); n++) {
1628      RawMachineAssemblerTester<int32_t> m(
1629          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1630      m.Return(m.Word32Equal(
1631          m.Int32Add(m.Parameter(0),
1632                     m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
1633          m.Int32Constant(0)));
1634      FOR_UINT32_INPUTS(i) {
1635        FOR_INT32_INPUTS(j) {
1636          FOR_UINT32_SHIFTS(shift) {
1637            int32_t right;
1638            switch (shops[n]->opcode()) {
1639              default:
1640                UNREACHABLE();
1641              case IrOpcode::kWord32Sar:
1642                right = *j >> shift;
1643                break;
1644              case IrOpcode::kWord32Shl:
1645                right = *j << shift;
1646                break;
1647              case IrOpcode::kWord32Shr:
1648                right = static_cast<uint32_t>(*j) >> shift;
1649                break;
1650            }
1651            int32_t expected = (*i + right) == 0;
1652            CHECK_EQ(expected, m.Call(*i, *j, shift));
1653          }
1654        }
1655      }
1656    }
1657  }
1658}
1659
1660
1661TEST(RunInt32SubP) {
1662  RawMachineAssemblerTester<int32_t> m;
1663  Uint32BinopTester bt(&m);
1664
1665  m.Return(m.Int32Sub(bt.param0, bt.param1));
1666
1667  FOR_UINT32_INPUTS(i) {
1668    FOR_UINT32_INPUTS(j) {
1669      uint32_t expected = static_cast<int32_t>(*i - *j);
1670      CHECK_EQ(expected, bt.call(*i, *j));
1671    }
1672  }
1673}
1674
1675
1676TEST(RunInt32SubImm) {
1677  {
1678    FOR_UINT32_INPUTS(i) {
1679      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1680      m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
1681      FOR_UINT32_INPUTS(j) {
1682        uint32_t expected = *i - *j;
1683        CHECK_EQ(expected, m.Call(*j));
1684      }
1685    }
1686  }
1687  {
1688    FOR_UINT32_INPUTS(i) {
1689      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1690      m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
1691      FOR_UINT32_INPUTS(j) {
1692        uint32_t expected = *j - *i;
1693        CHECK_EQ(expected, m.Call(*j));
1694      }
1695    }
1696  }
1697}
1698
1699
1700TEST(RunInt32SubAndWord32SarP) {
1701  {
1702    RawMachineAssemblerTester<int32_t> m(
1703        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1704    m.Return(m.Int32Sub(m.Parameter(0),
1705                        m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1706    FOR_UINT32_INPUTS(i) {
1707      FOR_INT32_INPUTS(j) {
1708        FOR_UINT32_SHIFTS(shift) {
1709          int32_t expected = *i - (*j >> shift);
1710          CHECK_EQ(expected, m.Call(*i, *j, shift));
1711        }
1712      }
1713    }
1714  }
1715  {
1716    RawMachineAssemblerTester<int32_t> m(
1717        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
1718    m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1719                        m.Parameter(2)));
1720    FOR_INT32_INPUTS(i) {
1721      FOR_UINT32_SHIFTS(shift) {
1722        FOR_UINT32_INPUTS(k) {
1723          int32_t expected = (*i >> shift) - *k;
1724          CHECK_EQ(expected, m.Call(*i, shift, *k));
1725        }
1726      }
1727    }
1728  }
1729}
1730
1731
1732TEST(RunInt32SubAndWord32ShlP) {
1733  {
1734    RawMachineAssemblerTester<int32_t> m(
1735        MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1736    m.Return(m.Int32Sub(m.Parameter(0),
1737                        m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1738    FOR_UINT32_INPUTS(i) {
1739      FOR_INT32_INPUTS(j) {
1740        FOR_UINT32_SHIFTS(shift) {
1741          int32_t expected = *i - (*j << shift);
1742          CHECK_EQ(expected, m.Call(*i, *j, shift));
1743        }
1744      }
1745    }
1746  }
1747  {
1748    RawMachineAssemblerTester<int32_t> m(
1749        MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
1750    m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1751                        m.Parameter(2)));
1752    FOR_INT32_INPUTS(i) {
1753      FOR_UINT32_SHIFTS(shift) {
1754        FOR_UINT32_INPUTS(k) {
1755          // Use uint32_t because signed overflow is UB in C.
1756          int32_t expected = (*i << shift) - *k;
1757          CHECK_EQ(expected, m.Call(*i, shift, *k));
1758        }
1759      }
1760    }
1761  }
1762}
1763
1764
1765TEST(RunInt32SubAndWord32ShrP) {
1766  {
1767    RawMachineAssemblerTester<uint32_t> m(
1768        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
1769    m.Return(m.Int32Sub(m.Parameter(0),
1770                        m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1771    FOR_UINT32_INPUTS(i) {
1772      FOR_UINT32_INPUTS(j) {
1773        FOR_UINT32_SHIFTS(shift) {
1774          // Use uint32_t because signed overflow is UB in C.
1775          uint32_t expected = *i - (*j >> shift);
1776          CHECK_EQ(expected, m.Call(*i, *j, shift));
1777        }
1778      }
1779    }
1780  }
1781  {
1782    RawMachineAssemblerTester<uint32_t> m(
1783        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
1784    m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1785                        m.Parameter(2)));
1786    FOR_UINT32_INPUTS(i) {
1787      FOR_UINT32_SHIFTS(shift) {
1788        FOR_UINT32_INPUTS(k) {
1789          // Use uint32_t because signed overflow is UB in C.
1790          uint32_t expected = (*i >> shift) - *k;
1791          CHECK_EQ(expected, m.Call(*i, shift, *k));
1792        }
1793      }
1794    }
1795  }
1796}
1797
1798
1799TEST(RunInt32SubInBranch) {
1800  static const int constant = 987654321;
1801  {
1802    RawMachineAssemblerTester<int32_t> m;
1803    Int32BinopTester bt(&m);
1804    RawMachineLabel blocka, blockb;
1805    m.Branch(
1806        m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1807        &blocka, &blockb);
1808    m.Bind(&blocka);
1809    bt.AddReturn(m.Int32Constant(constant));
1810    m.Bind(&blockb);
1811    bt.AddReturn(m.Int32Constant(0 - constant));
1812    FOR_UINT32_INPUTS(i) {
1813      FOR_UINT32_INPUTS(j) {
1814        int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
1815        CHECK_EQ(expected, bt.call(*i, *j));
1816      }
1817    }
1818  }
1819  {
1820    RawMachineAssemblerTester<int32_t> m;
1821    Int32BinopTester bt(&m);
1822    RawMachineLabel blocka, blockb;
1823    m.Branch(
1824        m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1825        &blocka, &blockb);
1826    m.Bind(&blocka);
1827    bt.AddReturn(m.Int32Constant(constant));
1828    m.Bind(&blockb);
1829    bt.AddReturn(m.Int32Constant(0 - constant));
1830    FOR_UINT32_INPUTS(i) {
1831      FOR_UINT32_INPUTS(j) {
1832        int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1833        CHECK_EQ(expected, bt.call(*i, *j));
1834      }
1835    }
1836  }
1837  {
1838    FOR_UINT32_INPUTS(i) {
1839      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1840      RawMachineLabel blocka, blockb;
1841      m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1842                             m.Int32Constant(0)),
1843               &blocka, &blockb);
1844      m.Bind(&blocka);
1845      m.Return(m.Int32Constant(constant));
1846      m.Bind(&blockb);
1847      m.Return(m.Int32Constant(0 - constant));
1848      FOR_UINT32_INPUTS(j) {
1849        uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
1850        CHECK_EQ(expected, m.Call(*j));
1851      }
1852    }
1853  }
1854  {
1855    FOR_UINT32_INPUTS(i) {
1856      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
1857      RawMachineLabel blocka, blockb;
1858      m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1859                                m.Int32Constant(0)),
1860               &blocka, &blockb);
1861      m.Bind(&blocka);
1862      m.Return(m.Int32Constant(constant));
1863      m.Bind(&blockb);
1864      m.Return(m.Int32Constant(0 - constant));
1865      FOR_UINT32_INPUTS(j) {
1866        int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1867        CHECK_EQ(expected, m.Call(*j));
1868      }
1869    }
1870  }
1871  {
1872    RawMachineAssemblerTester<void> m;
1873    const Operator* shops[] = {m.machine()->Word32Sar(),
1874                               m.machine()->Word32Shl(),
1875                               m.machine()->Word32Shr()};
1876    for (size_t n = 0; n < arraysize(shops); n++) {
1877      RawMachineAssemblerTester<int32_t> m(
1878          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1879      RawMachineLabel blocka, blockb;
1880      m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
1881                                        m.AddNode(shops[n], m.Parameter(1),
1882                                                  m.Parameter(2))),
1883                             m.Int32Constant(0)),
1884               &blocka, &blockb);
1885      m.Bind(&blocka);
1886      m.Return(m.Int32Constant(constant));
1887      m.Bind(&blockb);
1888      m.Return(m.Int32Constant(0 - constant));
1889      FOR_UINT32_INPUTS(i) {
1890        FOR_INT32_INPUTS(j) {
1891          FOR_UINT32_SHIFTS(shift) {
1892            int32_t right;
1893            switch (shops[n]->opcode()) {
1894              default:
1895                UNREACHABLE();
1896              case IrOpcode::kWord32Sar:
1897                right = *j >> shift;
1898                break;
1899              case IrOpcode::kWord32Shl:
1900                right = *j << shift;
1901                break;
1902              case IrOpcode::kWord32Shr:
1903                right = static_cast<uint32_t>(*j) >> shift;
1904                break;
1905            }
1906            int32_t expected = ((*i - right) == 0) ? constant : 0 - constant;
1907            CHECK_EQ(expected, m.Call(*i, *j, shift));
1908          }
1909        }
1910      }
1911    }
1912  }
1913}
1914
1915
1916TEST(RunInt32SubInComparison) {
1917  {
1918    RawMachineAssemblerTester<int32_t> m;
1919    Uint32BinopTester bt(&m);
1920    bt.AddReturn(
1921        m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)));
1922    FOR_UINT32_INPUTS(i) {
1923      FOR_UINT32_INPUTS(j) {
1924        uint32_t expected = (*i - *j) == 0;
1925        CHECK_EQ(expected, bt.call(*i, *j));
1926      }
1927    }
1928  }
1929  {
1930    RawMachineAssemblerTester<int32_t> m;
1931    Uint32BinopTester bt(&m);
1932    bt.AddReturn(
1933        m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1)));
1934    FOR_UINT32_INPUTS(i) {
1935      FOR_UINT32_INPUTS(j) {
1936        uint32_t expected = (*i - *j) == 0;
1937        CHECK_EQ(expected, bt.call(*i, *j));
1938      }
1939    }
1940  }
1941  {
1942    FOR_UINT32_INPUTS(i) {
1943      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1944      m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1945                             m.Int32Constant(0)));
1946      FOR_UINT32_INPUTS(j) {
1947        uint32_t expected = (*i - *j) == 0;
1948        CHECK_EQ(expected, m.Call(*j));
1949      }
1950    }
1951  }
1952  {
1953    FOR_UINT32_INPUTS(i) {
1954      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1955      m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
1956                             m.Int32Constant(0)));
1957      FOR_UINT32_INPUTS(j) {
1958        uint32_t expected = (*j - *i) == 0;
1959        CHECK_EQ(expected, m.Call(*j));
1960      }
1961    }
1962  }
1963  {
1964    RawMachineAssemblerTester<void> m;
1965    const Operator* shops[] = {m.machine()->Word32Sar(),
1966                               m.machine()->Word32Shl(),
1967                               m.machine()->Word32Shr()};
1968    for (size_t n = 0; n < arraysize(shops); n++) {
1969      RawMachineAssemblerTester<int32_t> m(
1970          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1971      m.Return(m.Word32Equal(
1972          m.Int32Sub(m.Parameter(0),
1973                     m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
1974          m.Int32Constant(0)));
1975      FOR_UINT32_INPUTS(i) {
1976        FOR_INT32_INPUTS(j) {
1977          FOR_UINT32_SHIFTS(shift) {
1978            int32_t right;
1979            switch (shops[n]->opcode()) {
1980              default:
1981                UNREACHABLE();
1982              case IrOpcode::kWord32Sar:
1983                right = *j >> shift;
1984                break;
1985              case IrOpcode::kWord32Shl:
1986                right = *j << shift;
1987                break;
1988              case IrOpcode::kWord32Shr:
1989                right = static_cast<uint32_t>(*j) >> shift;
1990                break;
1991            }
1992            int32_t expected = (*i - right) == 0;
1993            CHECK_EQ(expected, m.Call(*i, *j, shift));
1994          }
1995        }
1996      }
1997    }
1998  }
1999}
2000
2001
2002TEST(RunInt32MulP) {
2003  {
2004    RawMachineAssemblerTester<int32_t> m;
2005    Int32BinopTester bt(&m);
2006    bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2007    FOR_INT32_INPUTS(i) {
2008      FOR_INT32_INPUTS(j) {
2009        int expected = static_cast<int32_t>(*i * *j);
2010        CHECK_EQ(expected, bt.call(*i, *j));
2011      }
2012    }
2013  }
2014  {
2015    RawMachineAssemblerTester<int32_t> m;
2016    Uint32BinopTester bt(&m);
2017    bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2018    FOR_UINT32_INPUTS(i) {
2019      FOR_UINT32_INPUTS(j) {
2020        uint32_t expected = *i * *j;
2021        CHECK_EQ(expected, bt.call(*i, *j));
2022      }
2023    }
2024  }
2025}
2026
2027
2028TEST(RunInt32MulHighP) {
2029  RawMachineAssemblerTester<int32_t> m;
2030  Int32BinopTester bt(&m);
2031  bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
2032  FOR_INT32_INPUTS(i) {
2033    FOR_INT32_INPUTS(j) {
2034      int32_t expected = static_cast<int32_t>(
2035          (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
2036      CHECK_EQ(expected, bt.call(*i, *j));
2037    }
2038  }
2039}
2040
2041
2042TEST(RunInt32MulImm) {
2043  {
2044    FOR_UINT32_INPUTS(i) {
2045      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2046      m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
2047      FOR_UINT32_INPUTS(j) {
2048        uint32_t expected = *i * *j;
2049        CHECK_EQ(expected, m.Call(*j));
2050      }
2051    }
2052  }
2053  {
2054    FOR_UINT32_INPUTS(i) {
2055      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2056      m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
2057      FOR_UINT32_INPUTS(j) {
2058        uint32_t expected = *j * *i;
2059        CHECK_EQ(expected, m.Call(*j));
2060      }
2061    }
2062  }
2063}
2064
2065
2066TEST(RunInt32MulAndInt32AddP) {
2067  {
2068    FOR_INT32_INPUTS(i) {
2069      FOR_INT32_INPUTS(j) {
2070        RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2071        int32_t p0 = *i;
2072        int32_t p1 = *j;
2073        m.Return(m.Int32Add(m.Int32Constant(p0),
2074                            m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
2075        FOR_INT32_INPUTS(k) {
2076          int32_t p2 = *k;
2077          int expected = p0 + static_cast<int32_t>(p1 * p2);
2078          CHECK_EQ(expected, m.Call(p2));
2079        }
2080      }
2081    }
2082  }
2083  {
2084    RawMachineAssemblerTester<int32_t> m(
2085        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
2086    m.Return(
2087        m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2088    FOR_INT32_INPUTS(i) {
2089      FOR_INT32_INPUTS(j) {
2090        FOR_INT32_INPUTS(k) {
2091          int32_t p0 = *i;
2092          int32_t p1 = *j;
2093          int32_t p2 = *k;
2094          int expected = p0 + static_cast<int32_t>(p1 * p2);
2095          CHECK_EQ(expected, m.Call(p0, p1, p2));
2096        }
2097      }
2098    }
2099  }
2100  {
2101    RawMachineAssemblerTester<int32_t> m(
2102        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
2103    m.Return(
2104        m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
2105    FOR_INT32_INPUTS(i) {
2106      FOR_INT32_INPUTS(j) {
2107        FOR_INT32_INPUTS(k) {
2108          int32_t p0 = *i;
2109          int32_t p1 = *j;
2110          int32_t p2 = *k;
2111          int expected = static_cast<int32_t>(p0 * p1) + p2;
2112          CHECK_EQ(expected, m.Call(p0, p1, p2));
2113        }
2114      }
2115    }
2116  }
2117  {
2118    FOR_INT32_INPUTS(i) {
2119      RawMachineAssemblerTester<int32_t> m;
2120      Int32BinopTester bt(&m);
2121      bt.AddReturn(
2122          m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2123      FOR_INT32_INPUTS(j) {
2124        FOR_INT32_INPUTS(k) {
2125          int32_t p0 = *j;
2126          int32_t p1 = *k;
2127          int expected = *i + static_cast<int32_t>(p0 * p1);
2128          CHECK_EQ(expected, bt.call(p0, p1));
2129        }
2130      }
2131    }
2132  }
2133}
2134
2135
2136TEST(RunInt32MulAndInt32SubP) {
2137  {
2138    RawMachineAssemblerTester<int32_t> m(
2139        MachineType::Uint32(), MachineType::Int32(), MachineType::Int32());
2140    m.Return(
2141        m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2142    FOR_UINT32_INPUTS(i) {
2143      FOR_INT32_INPUTS(j) {
2144        FOR_INT32_INPUTS(k) {
2145          uint32_t p0 = *i;
2146          int32_t p1 = *j;
2147          int32_t p2 = *k;
2148          // Use uint32_t because signed overflow is UB in C.
2149          int expected = p0 - static_cast<uint32_t>(p1 * p2);
2150          CHECK_EQ(expected, m.Call(p0, p1, p2));
2151        }
2152      }
2153    }
2154  }
2155  {
2156    FOR_UINT32_INPUTS(i) {
2157      RawMachineAssemblerTester<int32_t> m;
2158      Int32BinopTester bt(&m);
2159      bt.AddReturn(
2160          m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2161      FOR_INT32_INPUTS(j) {
2162        FOR_INT32_INPUTS(k) {
2163          int32_t p0 = *j;
2164          int32_t p1 = *k;
2165          // Use uint32_t because signed overflow is UB in C.
2166          int expected = *i - static_cast<uint32_t>(p0 * p1);
2167          CHECK_EQ(expected, bt.call(p0, p1));
2168        }
2169      }
2170    }
2171  }
2172}
2173
2174
2175TEST(RunUint32MulHighP) {
2176  RawMachineAssemblerTester<int32_t> m;
2177  Int32BinopTester bt(&m);
2178  bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
2179  FOR_UINT32_INPUTS(i) {
2180    FOR_UINT32_INPUTS(j) {
2181      int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
2182          (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
2183      CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
2184    }
2185  }
2186}
2187
2188
2189TEST(RunInt32DivP) {
2190  {
2191    RawMachineAssemblerTester<int32_t> m;
2192    Int32BinopTester bt(&m);
2193    bt.AddReturn(m.Int32Div(bt.param0, bt.param1));
2194    FOR_INT32_INPUTS(i) {
2195      FOR_INT32_INPUTS(j) {
2196        int p0 = *i;
2197        int p1 = *j;
2198        if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2199          int expected = static_cast<int32_t>(p0 / p1);
2200          CHECK_EQ(expected, bt.call(p0, p1));
2201        }
2202      }
2203    }
2204  }
2205  {
2206    RawMachineAssemblerTester<int32_t> m;
2207    Int32BinopTester bt(&m);
2208    bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1)));
2209    FOR_INT32_INPUTS(i) {
2210      FOR_INT32_INPUTS(j) {
2211        int p0 = *i;
2212        int p1 = *j;
2213        if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2214          int expected = static_cast<int32_t>(p0 + (p0 / p1));
2215          CHECK_EQ(expected, bt.call(p0, p1));
2216        }
2217      }
2218    }
2219  }
2220}
2221
2222
2223TEST(RunUint32DivP) {
2224  {
2225    RawMachineAssemblerTester<int32_t> m;
2226    Int32BinopTester bt(&m);
2227    bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
2228    FOR_UINT32_INPUTS(i) {
2229      FOR_UINT32_INPUTS(j) {
2230        uint32_t p0 = *i;
2231        uint32_t p1 = *j;
2232        if (p1 != 0) {
2233          int32_t expected = bit_cast<int32_t>(p0 / p1);
2234          CHECK_EQ(expected, bt.call(p0, p1));
2235        }
2236      }
2237    }
2238  }
2239  {
2240    RawMachineAssemblerTester<int32_t> m;
2241    Int32BinopTester bt(&m);
2242    bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
2243    FOR_UINT32_INPUTS(i) {
2244      FOR_UINT32_INPUTS(j) {
2245        uint32_t p0 = *i;
2246        uint32_t p1 = *j;
2247        if (p1 != 0) {
2248          int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1));
2249          CHECK_EQ(expected, bt.call(p0, p1));
2250        }
2251      }
2252    }
2253  }
2254}
2255
2256
2257TEST(RunInt32ModP) {
2258  {
2259    RawMachineAssemblerTester<int32_t> m;
2260    Int32BinopTester bt(&m);
2261    bt.AddReturn(m.Int32Mod(bt.param0, bt.param1));
2262    FOR_INT32_INPUTS(i) {
2263      FOR_INT32_INPUTS(j) {
2264        int p0 = *i;
2265        int p1 = *j;
2266        if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2267          int expected = static_cast<int32_t>(p0 % p1);
2268          CHECK_EQ(expected, bt.call(p0, p1));
2269        }
2270      }
2271    }
2272  }
2273  {
2274    RawMachineAssemblerTester<int32_t> m;
2275    Int32BinopTester bt(&m);
2276    bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1)));
2277    FOR_INT32_INPUTS(i) {
2278      FOR_INT32_INPUTS(j) {
2279        int p0 = *i;
2280        int p1 = *j;
2281        if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2282          int expected = static_cast<int32_t>(p0 + (p0 % p1));
2283          CHECK_EQ(expected, bt.call(p0, p1));
2284        }
2285      }
2286    }
2287  }
2288}
2289
2290
2291TEST(RunUint32ModP) {
2292  {
2293    RawMachineAssemblerTester<int32_t> m;
2294    Uint32BinopTester bt(&m);
2295    bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
2296    FOR_UINT32_INPUTS(i) {
2297      FOR_UINT32_INPUTS(j) {
2298        uint32_t p0 = *i;
2299        uint32_t p1 = *j;
2300        if (p1 != 0) {
2301          uint32_t expected = static_cast<uint32_t>(p0 % p1);
2302          CHECK_EQ(expected, bt.call(p0, p1));
2303        }
2304      }
2305    }
2306  }
2307  {
2308    RawMachineAssemblerTester<int32_t> m;
2309    Uint32BinopTester bt(&m);
2310    bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
2311    FOR_UINT32_INPUTS(i) {
2312      FOR_UINT32_INPUTS(j) {
2313        uint32_t p0 = *i;
2314        uint32_t p1 = *j;
2315        if (p1 != 0) {
2316          uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1));
2317          CHECK_EQ(expected, bt.call(p0, p1));
2318        }
2319      }
2320    }
2321  }
2322}
2323
2324
2325TEST(RunWord32AndP) {
2326  {
2327    RawMachineAssemblerTester<int32_t> m;
2328    Int32BinopTester bt(&m);
2329    bt.AddReturn(m.Word32And(bt.param0, bt.param1));
2330    FOR_UINT32_INPUTS(i) {
2331      FOR_UINT32_INPUTS(j) {
2332        int32_t expected = *i & *j;
2333        CHECK_EQ(expected, bt.call(*i, *j));
2334      }
2335    }
2336  }
2337  {
2338    RawMachineAssemblerTester<int32_t> m;
2339    Int32BinopTester bt(&m);
2340    bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
2341    FOR_UINT32_INPUTS(i) {
2342      FOR_UINT32_INPUTS(j) {
2343        int32_t expected = *i & ~(*j);
2344        CHECK_EQ(expected, bt.call(*i, *j));
2345      }
2346    }
2347  }
2348  {
2349    RawMachineAssemblerTester<int32_t> m;
2350    Int32BinopTester bt(&m);
2351    bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
2352    FOR_UINT32_INPUTS(i) {
2353      FOR_UINT32_INPUTS(j) {
2354        int32_t expected = ~(*i) & *j;
2355        CHECK_EQ(expected, bt.call(*i, *j));
2356      }
2357    }
2358  }
2359}
2360
2361
2362TEST(RunWord32AndAndWord32ShlP) {
2363  {
2364    RawMachineAssemblerTester<int32_t> m;
2365    Uint32BinopTester bt(&m);
2366    bt.AddReturn(
2367        m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2368    FOR_UINT32_INPUTS(i) {
2369      FOR_UINT32_INPUTS(j) {
2370        uint32_t expected = *i << (*j & 0x1f);
2371        CHECK_EQ(expected, bt.call(*i, *j));
2372      }
2373    }
2374  }
2375  {
2376    RawMachineAssemblerTester<int32_t> m;
2377    Uint32BinopTester bt(&m);
2378    bt.AddReturn(
2379        m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2380    FOR_UINT32_INPUTS(i) {
2381      FOR_UINT32_INPUTS(j) {
2382        uint32_t expected = *i << (0x1f & *j);
2383        CHECK_EQ(expected, bt.call(*i, *j));
2384      }
2385    }
2386  }
2387}
2388
2389
2390TEST(RunWord32AndAndWord32ShrP) {
2391  {
2392    RawMachineAssemblerTester<int32_t> m;
2393    Uint32BinopTester bt(&m);
2394    bt.AddReturn(
2395        m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2396    FOR_UINT32_INPUTS(i) {
2397      FOR_UINT32_INPUTS(j) {
2398        uint32_t expected = *i >> (*j & 0x1f);
2399        CHECK_EQ(expected, bt.call(*i, *j));
2400      }
2401    }
2402  }
2403  {
2404    RawMachineAssemblerTester<int32_t> m;
2405    Uint32BinopTester bt(&m);
2406    bt.AddReturn(
2407        m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2408    FOR_UINT32_INPUTS(i) {
2409      FOR_UINT32_INPUTS(j) {
2410        uint32_t expected = *i >> (0x1f & *j);
2411        CHECK_EQ(expected, bt.call(*i, *j));
2412      }
2413    }
2414  }
2415}
2416
2417
2418TEST(RunWord32AndAndWord32SarP) {
2419  {
2420    RawMachineAssemblerTester<int32_t> m;
2421    Int32BinopTester bt(&m);
2422    bt.AddReturn(
2423        m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2424    FOR_INT32_INPUTS(i) {
2425      FOR_INT32_INPUTS(j) {
2426        int32_t expected = *i >> (*j & 0x1f);
2427        CHECK_EQ(expected, bt.call(*i, *j));
2428      }
2429    }
2430  }
2431  {
2432    RawMachineAssemblerTester<int32_t> m;
2433    Int32BinopTester bt(&m);
2434    bt.AddReturn(
2435        m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2436    FOR_INT32_INPUTS(i) {
2437      FOR_INT32_INPUTS(j) {
2438        int32_t expected = *i >> (0x1f & *j);
2439        CHECK_EQ(expected, bt.call(*i, *j));
2440      }
2441    }
2442  }
2443}
2444
2445
2446TEST(RunWord32AndImm) {
2447  {
2448    FOR_UINT32_INPUTS(i) {
2449      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2450      m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
2451      FOR_UINT32_INPUTS(j) {
2452        uint32_t expected = *i & *j;
2453        CHECK_EQ(expected, m.Call(*j));
2454      }
2455    }
2456  }
2457  {
2458    FOR_UINT32_INPUTS(i) {
2459      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2460      m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2461      FOR_UINT32_INPUTS(j) {
2462        uint32_t expected = *i & ~(*j);
2463        CHECK_EQ(expected, m.Call(*j));
2464      }
2465    }
2466  }
2467}
2468
2469
2470TEST(RunWord32AndInBranch) {
2471  static const int constant = 987654321;
2472  {
2473    RawMachineAssemblerTester<int32_t> m;
2474    Int32BinopTester bt(&m);
2475    RawMachineLabel blocka, blockb;
2476    m.Branch(
2477        m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
2478        &blocka, &blockb);
2479    m.Bind(&blocka);
2480    bt.AddReturn(m.Int32Constant(constant));
2481    m.Bind(&blockb);
2482    bt.AddReturn(m.Int32Constant(0 - constant));
2483    FOR_UINT32_INPUTS(i) {
2484      FOR_UINT32_INPUTS(j) {
2485        int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
2486        CHECK_EQ(expected, bt.call(*i, *j));
2487      }
2488    }
2489  }
2490  {
2491    RawMachineAssemblerTester<int32_t> m;
2492    Int32BinopTester bt(&m);
2493    RawMachineLabel blocka, blockb;
2494    m.Branch(
2495        m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
2496        &blocka, &blockb);
2497    m.Bind(&blocka);
2498    bt.AddReturn(m.Int32Constant(constant));
2499    m.Bind(&blockb);
2500    bt.AddReturn(m.Int32Constant(0 - constant));
2501    FOR_UINT32_INPUTS(i) {
2502      FOR_UINT32_INPUTS(j) {
2503        int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2504        CHECK_EQ(expected, bt.call(*i, *j));
2505      }
2506    }
2507  }
2508  {
2509    FOR_UINT32_INPUTS(i) {
2510      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2511      RawMachineLabel blocka, blockb;
2512      m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2513                             m.Int32Constant(0)),
2514               &blocka, &blockb);
2515      m.Bind(&blocka);
2516      m.Return(m.Int32Constant(constant));
2517      m.Bind(&blockb);
2518      m.Return(m.Int32Constant(0 - constant));
2519      FOR_UINT32_INPUTS(j) {
2520        int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
2521        CHECK_EQ(expected, m.Call(*j));
2522      }
2523    }
2524  }
2525  {
2526    FOR_UINT32_INPUTS(i) {
2527      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2528      RawMachineLabel blocka, blockb;
2529      m.Branch(
2530          m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2531                           m.Int32Constant(0)),
2532          &blocka, &blockb);
2533      m.Bind(&blocka);
2534      m.Return(m.Int32Constant(constant));
2535      m.Bind(&blockb);
2536      m.Return(m.Int32Constant(0 - constant));
2537      FOR_UINT32_INPUTS(j) {
2538        int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2539        CHECK_EQ(expected, m.Call(*j));
2540      }
2541    }
2542  }
2543  {
2544    RawMachineAssemblerTester<void> m;
2545    const Operator* shops[] = {m.machine()->Word32Sar(),
2546                               m.machine()->Word32Shl(),
2547                               m.machine()->Word32Shr()};
2548    for (size_t n = 0; n < arraysize(shops); n++) {
2549      RawMachineAssemblerTester<int32_t> m(
2550          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2551      RawMachineLabel blocka, blockb;
2552      m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
2553                                         m.AddNode(shops[n], m.Parameter(1),
2554                                                   m.Parameter(2))),
2555                             m.Int32Constant(0)),
2556               &blocka, &blockb);
2557      m.Bind(&blocka);
2558      m.Return(m.Int32Constant(constant));
2559      m.Bind(&blockb);
2560      m.Return(m.Int32Constant(0 - constant));
2561      FOR_UINT32_INPUTS(i) {
2562        FOR_INT32_INPUTS(j) {
2563          FOR_UINT32_SHIFTS(shift) {
2564            int32_t right;
2565            switch (shops[n]->opcode()) {
2566              default:
2567                UNREACHABLE();
2568              case IrOpcode::kWord32Sar:
2569                right = *j >> shift;
2570                break;
2571              case IrOpcode::kWord32Shl:
2572                right = *j << shift;
2573                break;
2574              case IrOpcode::kWord32Shr:
2575                right = static_cast<uint32_t>(*j) >> shift;
2576                break;
2577            }
2578            int32_t expected = ((*i & right) == 0) ? constant : 0 - constant;
2579            CHECK_EQ(expected, m.Call(*i, *j, shift));
2580          }
2581        }
2582      }
2583    }
2584  }
2585}
2586
2587
2588TEST(RunWord32AndInComparison) {
2589  {
2590    RawMachineAssemblerTester<int32_t> m;
2591    Uint32BinopTester bt(&m);
2592    bt.AddReturn(
2593        m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)));
2594    FOR_UINT32_INPUTS(i) {
2595      FOR_UINT32_INPUTS(j) {
2596        uint32_t expected = (*i & *j) == 0;
2597        CHECK_EQ(expected, bt.call(*i, *j));
2598      }
2599    }
2600  }
2601  {
2602    RawMachineAssemblerTester<int32_t> m;
2603    Uint32BinopTester bt(&m);
2604    bt.AddReturn(
2605        m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1)));
2606    FOR_UINT32_INPUTS(i) {
2607      FOR_UINT32_INPUTS(j) {
2608        uint32_t expected = (*i & *j) == 0;
2609        CHECK_EQ(expected, bt.call(*i, *j));
2610      }
2611    }
2612  }
2613  {
2614    FOR_UINT32_INPUTS(i) {
2615      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2616      m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2617                             m.Int32Constant(0)));
2618      FOR_UINT32_INPUTS(j) {
2619        uint32_t expected = (*i & *j) == 0;
2620        CHECK_EQ(expected, m.Call(*j));
2621      }
2622    }
2623  }
2624  {
2625    FOR_UINT32_INPUTS(i) {
2626      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2627      m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
2628                             m.Int32Constant(0)));
2629      FOR_UINT32_INPUTS(j) {
2630        uint32_t expected = (*j & *i) == 0;
2631        CHECK_EQ(expected, m.Call(*j));
2632      }
2633    }
2634  }
2635}
2636
2637
2638TEST(RunWord32OrP) {
2639  {
2640    RawMachineAssemblerTester<int32_t> m;
2641    Uint32BinopTester bt(&m);
2642    bt.AddReturn(m.Word32Or(bt.param0, bt.param1));
2643    FOR_UINT32_INPUTS(i) {
2644      FOR_UINT32_INPUTS(j) {
2645        uint32_t expected = *i | *j;
2646        CHECK_EQ(expected, bt.call(*i, *j));
2647      }
2648    }
2649  }
2650  {
2651    RawMachineAssemblerTester<int32_t> m;
2652    Uint32BinopTester bt(&m);
2653    bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1)));
2654    FOR_UINT32_INPUTS(i) {
2655      FOR_UINT32_INPUTS(j) {
2656        uint32_t expected = *i | ~(*j);
2657        CHECK_EQ(expected, bt.call(*i, *j));
2658      }
2659    }
2660  }
2661  {
2662    RawMachineAssemblerTester<int32_t> m;
2663    Uint32BinopTester bt(&m);
2664    bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1));
2665    FOR_UINT32_INPUTS(i) {
2666      FOR_UINT32_INPUTS(j) {
2667        uint32_t expected = ~(*i) | *j;
2668        CHECK_EQ(expected, bt.call(*i, *j));
2669      }
2670    }
2671  }
2672}
2673
2674
2675TEST(RunWord32OrImm) {
2676  {
2677    FOR_UINT32_INPUTS(i) {
2678      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2679      m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
2680      FOR_UINT32_INPUTS(j) {
2681        uint32_t expected = *i | *j;
2682        CHECK_EQ(expected, m.Call(*j));
2683      }
2684    }
2685  }
2686  {
2687    FOR_UINT32_INPUTS(i) {
2688      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2689      m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2690      FOR_UINT32_INPUTS(j) {
2691        uint32_t expected = *i | ~(*j);
2692        CHECK_EQ(expected, m.Call(*j));
2693      }
2694    }
2695  }
2696}
2697
2698
2699TEST(RunWord32OrInBranch) {
2700  static const int constant = 987654321;
2701  {
2702    RawMachineAssemblerTester<int32_t> m;
2703    Int32BinopTester bt(&m);
2704    RawMachineLabel blocka, blockb;
2705    m.Branch(
2706        m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2707        &blocka, &blockb);
2708    m.Bind(&blocka);
2709    bt.AddReturn(m.Int32Constant(constant));
2710    m.Bind(&blockb);
2711    bt.AddReturn(m.Int32Constant(0 - constant));
2712    FOR_INT32_INPUTS(i) {
2713      FOR_INT32_INPUTS(j) {
2714        int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2715        CHECK_EQ(expected, bt.call(*i, *j));
2716      }
2717    }
2718  }
2719  {
2720    RawMachineAssemblerTester<int32_t> m;
2721    Int32BinopTester bt(&m);
2722    RawMachineLabel blocka, blockb;
2723    m.Branch(
2724        m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2725        &blocka, &blockb);
2726    m.Bind(&blocka);
2727    bt.AddReturn(m.Int32Constant(constant));
2728    m.Bind(&blockb);
2729    bt.AddReturn(m.Int32Constant(0 - constant));
2730    FOR_INT32_INPUTS(i) {
2731      FOR_INT32_INPUTS(j) {
2732        int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2733        CHECK_EQ(expected, bt.call(*i, *j));
2734      }
2735    }
2736  }
2737  {
2738    FOR_INT32_INPUTS(i) {
2739      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2740      RawMachineLabel blocka, blockb;
2741      m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2742                             m.Int32Constant(0)),
2743               &blocka, &blockb);
2744      m.Bind(&blocka);
2745      m.Return(m.Int32Constant(constant));
2746      m.Bind(&blockb);
2747      m.Return(m.Int32Constant(0 - constant));
2748      FOR_INT32_INPUTS(j) {
2749        int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2750        CHECK_EQ(expected, m.Call(*j));
2751      }
2752    }
2753  }
2754  {
2755    FOR_INT32_INPUTS(i) {
2756      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2757      RawMachineLabel blocka, blockb;
2758      m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2759                                m.Int32Constant(0)),
2760               &blocka, &blockb);
2761      m.Bind(&blocka);
2762      m.Return(m.Int32Constant(constant));
2763      m.Bind(&blockb);
2764      m.Return(m.Int32Constant(0 - constant));
2765      FOR_INT32_INPUTS(j) {
2766        int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2767        CHECK_EQ(expected, m.Call(*j));
2768      }
2769    }
2770  }
2771  {
2772    RawMachineAssemblerTester<void> m;
2773    const Operator* shops[] = {m.machine()->Word32Sar(),
2774                               m.machine()->Word32Shl(),
2775                               m.machine()->Word32Shr()};
2776    for (size_t n = 0; n < arraysize(shops); n++) {
2777      RawMachineAssemblerTester<int32_t> m(
2778          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2779      RawMachineLabel blocka, blockb;
2780      m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
2781                                        m.AddNode(shops[n], m.Parameter(1),
2782                                                  m.Parameter(2))),
2783                             m.Int32Constant(0)),
2784               &blocka, &blockb);
2785      m.Bind(&blocka);
2786      m.Return(m.Int32Constant(constant));
2787      m.Bind(&blockb);
2788      m.Return(m.Int32Constant(0 - constant));
2789      FOR_UINT32_INPUTS(i) {
2790        FOR_INT32_INPUTS(j) {
2791          FOR_UINT32_SHIFTS(shift) {
2792            int32_t right;
2793            switch (shops[n]->opcode()) {
2794              default:
2795                UNREACHABLE();
2796              case IrOpcode::kWord32Sar:
2797                right = *j >> shift;
2798                break;
2799              case IrOpcode::kWord32Shl:
2800                right = *j << shift;
2801                break;
2802              case IrOpcode::kWord32Shr:
2803                right = static_cast<uint32_t>(*j) >> shift;
2804                break;
2805            }
2806            int32_t expected = ((*i | right) == 0) ? constant : 0 - constant;
2807            CHECK_EQ(expected, m.Call(*i, *j, shift));
2808          }
2809        }
2810      }
2811    }
2812  }
2813}
2814
2815
2816TEST(RunWord32OrInComparison) {
2817  {
2818    RawMachineAssemblerTester<int32_t> m;
2819    Int32BinopTester bt(&m);
2820    bt.AddReturn(
2821        m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
2822    FOR_UINT32_INPUTS(i) {
2823      FOR_UINT32_INPUTS(j) {
2824        int32_t expected = (*i | *j) == 0;
2825        CHECK_EQ(expected, bt.call(*i, *j));
2826      }
2827    }
2828  }
2829  {
2830    RawMachineAssemblerTester<int32_t> m;
2831    Int32BinopTester bt(&m);
2832    bt.AddReturn(
2833        m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
2834    FOR_UINT32_INPUTS(i) {
2835      FOR_UINT32_INPUTS(j) {
2836        int32_t expected = (*i | *j) == 0;
2837        CHECK_EQ(expected, bt.call(*i, *j));
2838      }
2839    }
2840  }
2841  {
2842    FOR_UINT32_INPUTS(i) {
2843      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2844      m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2845                             m.Int32Constant(0)));
2846      FOR_UINT32_INPUTS(j) {
2847        uint32_t expected = (*i | *j) == 0;
2848        CHECK_EQ(expected, m.Call(*j));
2849      }
2850    }
2851  }
2852  {
2853    FOR_UINT32_INPUTS(i) {
2854      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2855      m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
2856                             m.Int32Constant(0)));
2857      FOR_UINT32_INPUTS(j) {
2858        uint32_t expected = (*j | *i) == 0;
2859        CHECK_EQ(expected, m.Call(*j));
2860      }
2861    }
2862  }
2863}
2864
2865
2866TEST(RunWord32XorP) {
2867  {
2868    FOR_UINT32_INPUTS(i) {
2869      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2870      m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
2871      FOR_UINT32_INPUTS(j) {
2872        uint32_t expected = *i ^ *j;
2873        CHECK_EQ(expected, m.Call(*j));
2874      }
2875    }
2876  }
2877  {
2878    RawMachineAssemblerTester<int32_t> m;
2879    Uint32BinopTester bt(&m);
2880    bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
2881    FOR_UINT32_INPUTS(i) {
2882      FOR_UINT32_INPUTS(j) {
2883        uint32_t expected = *i ^ *j;
2884        CHECK_EQ(expected, bt.call(*i, *j));
2885      }
2886    }
2887  }
2888  {
2889    RawMachineAssemblerTester<int32_t> m;
2890    Int32BinopTester bt(&m);
2891    bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1)));
2892    FOR_INT32_INPUTS(i) {
2893      FOR_INT32_INPUTS(j) {
2894        int32_t expected = *i ^ ~(*j);
2895        CHECK_EQ(expected, bt.call(*i, *j));
2896      }
2897    }
2898  }
2899  {
2900    RawMachineAssemblerTester<int32_t> m;
2901    Int32BinopTester bt(&m);
2902    bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1));
2903    FOR_INT32_INPUTS(i) {
2904      FOR_INT32_INPUTS(j) {
2905        int32_t expected = ~(*i) ^ *j;
2906        CHECK_EQ(expected, bt.call(*i, *j));
2907      }
2908    }
2909  }
2910  {
2911    FOR_UINT32_INPUTS(i) {
2912      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2913      m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2914      FOR_UINT32_INPUTS(j) {
2915        uint32_t expected = *i ^ ~(*j);
2916        CHECK_EQ(expected, m.Call(*j));
2917      }
2918    }
2919  }
2920}
2921
2922
2923TEST(RunWord32XorInBranch) {
2924  static const uint32_t constant = 987654321;
2925  {
2926    RawMachineAssemblerTester<int32_t> m;
2927    Uint32BinopTester bt(&m);
2928    RawMachineLabel blocka, blockb;
2929    m.Branch(
2930        m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2931        &blocka, &blockb);
2932    m.Bind(&blocka);
2933    bt.AddReturn(m.Int32Constant(constant));
2934    m.Bind(&blockb);
2935    bt.AddReturn(m.Int32Constant(0 - constant));
2936    FOR_UINT32_INPUTS(i) {
2937      FOR_UINT32_INPUTS(j) {
2938        uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
2939        CHECK_EQ(expected, bt.call(*i, *j));
2940      }
2941    }
2942  }
2943  {
2944    RawMachineAssemblerTester<int32_t> m;
2945    Uint32BinopTester bt(&m);
2946    RawMachineLabel blocka, blockb;
2947    m.Branch(
2948        m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2949        &blocka, &blockb);
2950    m.Bind(&blocka);
2951    bt.AddReturn(m.Int32Constant(constant));
2952    m.Bind(&blockb);
2953    bt.AddReturn(m.Int32Constant(0 - constant));
2954    FOR_UINT32_INPUTS(i) {
2955      FOR_UINT32_INPUTS(j) {
2956        uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
2957        CHECK_EQ(expected, bt.call(*i, *j));
2958      }
2959    }
2960  }
2961  {
2962    FOR_UINT32_INPUTS(i) {
2963      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2964      RawMachineLabel blocka, blockb;
2965      m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
2966                             m.Int32Constant(0)),
2967               &blocka, &blockb);
2968      m.Bind(&blocka);
2969      m.Return(m.Int32Constant(constant));
2970      m.Bind(&blockb);
2971      m.Return(m.Int32Constant(0 - constant));
2972      FOR_UINT32_INPUTS(j) {
2973        uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
2974        CHECK_EQ(expected, m.Call(*j));
2975      }
2976    }
2977  }
2978  {
2979    FOR_UINT32_INPUTS(i) {
2980      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2981      RawMachineLabel blocka, blockb;
2982      m.Branch(
2983          m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
2984                           m.Int32Constant(0)),
2985          &blocka, &blockb);
2986      m.Bind(&blocka);
2987      m.Return(m.Int32Constant(constant));
2988      m.Bind(&blockb);
2989      m.Return(m.Int32Constant(0 - constant));
2990      FOR_UINT32_INPUTS(j) {
2991        uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
2992        CHECK_EQ(expected, m.Call(*j));
2993      }
2994    }
2995  }
2996  {
2997    RawMachineAssemblerTester<void> m;
2998    const Operator* shops[] = {m.machine()->Word32Sar(),
2999                               m.machine()->Word32Shl(),
3000                               m.machine()->Word32Shr()};
3001    for (size_t n = 0; n < arraysize(shops); n++) {
3002      RawMachineAssemblerTester<int32_t> m(
3003          MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
3004      RawMachineLabel blocka, blockb;
3005      m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
3006                                         m.AddNode(shops[n], m.Parameter(1),
3007                                                   m.Parameter(2))),
3008                             m.Int32Constant(0)),
3009               &blocka, &blockb);
3010      m.Bind(&blocka);
3011      m.Return(m.Int32Constant(constant));
3012      m.Bind(&blockb);
3013      m.Return(m.Int32Constant(0 - constant));
3014      FOR_UINT32_INPUTS(i) {
3015        FOR_INT32_INPUTS(j) {
3016          FOR_UINT32_SHIFTS(shift) {
3017            int32_t right;
3018            switch (shops[n]->opcode()) {
3019              default:
3020                UNREACHABLE();
3021              case IrOpcode::kWord32Sar:
3022                right = *j >> shift;
3023                break;
3024              case IrOpcode::kWord32Shl:
3025                right = *j << shift;
3026                break;
3027              case IrOpcode::kWord32Shr:
3028                right = static_cast<uint32_t>(*j) >> shift;
3029                break;
3030            }
3031            int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant;
3032            CHECK_EQ(expected, m.Call(*i, *j, shift));
3033          }
3034        }
3035      }
3036    }
3037  }
3038}
3039
3040
3041TEST(RunWord32ShlP) {
3042  {
3043    FOR_UINT32_SHIFTS(shift) {
3044      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3045      m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
3046      FOR_UINT32_INPUTS(j) {
3047        uint32_t expected = *j << shift;
3048        CHECK_EQ(expected, m.Call(*j));
3049      }
3050    }
3051  }
3052  {
3053    RawMachineAssemblerTester<int32_t> m;
3054    Uint32BinopTester bt(&m);
3055    bt.AddReturn(m.Word32Shl(bt.param0, bt.param1));
3056    FOR_UINT32_INPUTS(i) {
3057      FOR_UINT32_SHIFTS(shift) {
3058        uint32_t expected = *i << shift;
3059        CHECK_EQ(expected, bt.call(*i, shift));
3060      }
3061    }
3062  }
3063}
3064
3065
3066TEST(RunWord32ShlInComparison) {
3067  {
3068    RawMachineAssemblerTester<int32_t> m;
3069    Uint32BinopTester bt(&m);
3070    bt.AddReturn(
3071        m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0)));
3072    FOR_UINT32_INPUTS(i) {
3073      FOR_UINT32_SHIFTS(shift) {
3074        uint32_t expected = 0 == (*i << shift);
3075        CHECK_EQ(expected, bt.call(*i, shift));
3076      }
3077    }
3078  }
3079  {
3080    RawMachineAssemblerTester<int32_t> m;
3081    Uint32BinopTester bt(&m);
3082    bt.AddReturn(
3083        m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1)));
3084    FOR_UINT32_INPUTS(i) {
3085      FOR_UINT32_SHIFTS(shift) {
3086        uint32_t expected = 0 == (*i << shift);
3087        CHECK_EQ(expected, bt.call(*i, shift));
3088      }
3089    }
3090  }
3091  {
3092    FOR_UINT32_SHIFTS(shift) {
3093      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3094      m.Return(
3095          m.Word32Equal(m.Int32Constant(0),
3096                        m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))));
3097      FOR_UINT32_INPUTS(i) {
3098        uint32_t expected = 0 == (*i << shift);
3099        CHECK_EQ(expected, m.Call(*i));
3100      }
3101    }
3102  }
3103  {
3104    FOR_UINT32_SHIFTS(shift) {
3105      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3106      m.Return(
3107          m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)),
3108                        m.Int32Constant(0)));
3109      FOR_UINT32_INPUTS(i) {
3110        uint32_t expected = 0 == (*i << shift);
3111        CHECK_EQ(expected, m.Call(*i));
3112      }
3113    }
3114  }
3115}
3116
3117
3118TEST(RunWord32ShrP) {
3119  {
3120    FOR_UINT32_SHIFTS(shift) {
3121      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3122      m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
3123      FOR_UINT32_INPUTS(j) {
3124        uint32_t expected = *j >> shift;
3125        CHECK_EQ(expected, m.Call(*j));
3126      }
3127    }
3128  }
3129  {
3130    RawMachineAssemblerTester<int32_t> m;
3131    Uint32BinopTester bt(&m);
3132    bt.AddReturn(m.Word32Shr(bt.param0, bt.param1));
3133    FOR_UINT32_INPUTS(i) {
3134      FOR_UINT32_SHIFTS(shift) {
3135        uint32_t expected = *i >> shift;
3136        CHECK_EQ(expected, bt.call(*i, shift));
3137      }
3138    }
3139    CHECK_EQ(0x00010000u, bt.call(0x80000000, 15));
3140  }
3141}
3142
3143
3144TEST(RunWord32ShrInComparison) {
3145  {
3146    RawMachineAssemblerTester<int32_t> m;
3147    Uint32BinopTester bt(&m);
3148    bt.AddReturn(
3149        m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0)));
3150    FOR_UINT32_INPUTS(i) {
3151      FOR_UINT32_SHIFTS(shift) {
3152        uint32_t expected = 0 == (*i >> shift);
3153        CHECK_EQ(expected, bt.call(*i, shift));
3154      }
3155    }
3156  }
3157  {
3158    RawMachineAssemblerTester<int32_t> m;
3159    Uint32BinopTester bt(&m);
3160    bt.AddReturn(
3161        m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1)));
3162    FOR_UINT32_INPUTS(i) {
3163      FOR_UINT32_SHIFTS(shift) {
3164        uint32_t expected = 0 == (*i >> shift);
3165        CHECK_EQ(expected, bt.call(*i, shift));
3166      }
3167    }
3168  }
3169  {
3170    FOR_UINT32_SHIFTS(shift) {
3171      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3172      m.Return(
3173          m.Word32Equal(m.Int32Constant(0),
3174                        m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
3175      FOR_UINT32_INPUTS(i) {
3176        uint32_t expected = 0 == (*i >> shift);
3177        CHECK_EQ(expected, m.Call(*i));
3178      }
3179    }
3180  }
3181  {
3182    FOR_UINT32_SHIFTS(shift) {
3183      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3184      m.Return(
3185          m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
3186                        m.Int32Constant(0)));
3187      FOR_UINT32_INPUTS(i) {
3188        uint32_t expected = 0 == (*i >> shift);
3189        CHECK_EQ(expected, m.Call(*i));
3190      }
3191    }
3192  }
3193}
3194
3195
3196TEST(RunWord32SarP) {
3197  {
3198    FOR_INT32_SHIFTS(shift) {
3199      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
3200      m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
3201      FOR_INT32_INPUTS(j) {
3202        int32_t expected = *j >> shift;
3203        CHECK_EQ(expected, m.Call(*j));
3204      }
3205    }
3206  }
3207  {
3208    RawMachineAssemblerTester<int32_t> m;
3209    Int32BinopTester bt(&m);
3210    bt.AddReturn(m.Word32Sar(bt.param0, bt.param1));
3211    FOR_INT32_INPUTS(i) {
3212      FOR_INT32_SHIFTS(shift) {
3213        int32_t expected = *i >> shift;
3214        CHECK_EQ(expected, bt.call(*i, shift));
3215      }
3216    }
3217    CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15));
3218  }
3219}
3220
3221
3222TEST(RunWord32SarInComparison) {
3223  {
3224    RawMachineAssemblerTester<int32_t> m;
3225    Int32BinopTester bt(&m);
3226    bt.AddReturn(
3227        m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0)));
3228    FOR_INT32_INPUTS(i) {
3229      FOR_INT32_SHIFTS(shift) {
3230        int32_t expected = 0 == (*i >> shift);
3231        CHECK_EQ(expected, bt.call(*i, shift));
3232      }
3233    }
3234  }
3235  {
3236    RawMachineAssemblerTester<int32_t> m;
3237    Int32BinopTester bt(&m);
3238    bt.AddReturn(
3239        m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1)));
3240    FOR_INT32_INPUTS(i) {
3241      FOR_INT32_SHIFTS(shift) {
3242        int32_t expected = 0 == (*i >> shift);
3243        CHECK_EQ(expected, bt.call(*i, shift));
3244      }
3245    }
3246  }
3247  {
3248    FOR_INT32_SHIFTS(shift) {
3249      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
3250      m.Return(
3251          m.Word32Equal(m.Int32Constant(0),
3252                        m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))));
3253      FOR_INT32_INPUTS(i) {
3254        int32_t expected = 0 == (*i >> shift);
3255        CHECK_EQ(expected, m.Call(*i));
3256      }
3257    }
3258  }
3259  {
3260    FOR_INT32_SHIFTS(shift) {
3261      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
3262      m.Return(
3263          m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)),
3264                        m.Int32Constant(0)));
3265      FOR_INT32_INPUTS(i) {
3266        int32_t expected = 0 == (*i >> shift);
3267        CHECK_EQ(expected, m.Call(*i));
3268      }
3269    }
3270  }
3271}
3272
3273
3274TEST(RunWord32RorP) {
3275  {
3276    FOR_UINT32_SHIFTS(shift) {
3277      RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
3278      m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)));
3279      FOR_UINT32_INPUTS(j) {
3280        int32_t expected = bits::RotateRight32(*j, shift);
3281        CHECK_EQ(expected, m.Call(*j));
3282      }
3283    }
3284  }
3285  {
3286    RawMachineAssemblerTester<int32_t> m;
3287    Uint32BinopTester bt(&m);
3288    bt.AddReturn(m.Word32Ror(bt.param0, bt.param1));
3289    FOR_UINT32_INPUTS(i) {
3290      FOR_UINT32_SHIFTS(shift) {
3291        uint32_t expected = bits::RotateRight32(*i, shift);
3292        CHECK_EQ(expected, bt.call(*i, shift));
3293      }
3294    }
3295  }
3296}
3297
3298
3299TEST(RunWord32RorInComparison) {
3300  {
3301    RawMachineAssemblerTester<int32_t> m;
3302    Uint32BinopTester bt(&m);
3303    bt.AddReturn(
3304        m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0)));
3305    FOR_UINT32_INPUTS(i) {
3306      FOR_UINT32_SHIFTS(shift) {
3307        uint32_t expected = 0 == bits::RotateRight32(*i, shift);
3308        CHECK_EQ(expected, bt.call(*i, shift));
3309      }
3310    }
3311  }
3312  {
3313    RawMachineAssemblerTester<int32_t> m;
3314    Uint32BinopTester bt(&m);
3315    bt.AddReturn(
3316        m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1)));
3317    FOR_UINT32_INPUTS(i) {
3318      FOR_UINT32_SHIFTS(shift) {
3319        uint32_t expected = 0 == bits::RotateRight32(*i, shift);
3320        CHECK_EQ(expected, bt.call(*i, shift));
3321      }
3322    }
3323  }
3324  {
3325    FOR_UINT32_SHIFTS(shift) {
3326      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3327      m.Return(
3328          m.Word32Equal(m.Int32Constant(0),
3329                        m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))));
3330      FOR_UINT32_INPUTS(i) {
3331        uint32_t expected = 0 == bits::RotateRight32(*i, shift);
3332        CHECK_EQ(expected, m.Call(*i));
3333      }
3334    }
3335  }
3336  {
3337    FOR_UINT32_SHIFTS(shift) {
3338      RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3339      m.Return(
3340          m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)),
3341                        m.Int32Constant(0)));
3342      FOR_UINT32_INPUTS(i) {
3343        uint32_t expected = 0 == bits::RotateRight32(*i, shift);
3344        CHECK_EQ(expected, m.Call(*i));
3345      }
3346    }
3347  }
3348}
3349
3350
3351TEST(RunWord32NotP) {
3352  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
3353  m.Return(m.Word32Not(m.Parameter(0)));
3354  FOR_INT32_INPUTS(i) {
3355    int expected = ~(*i);
3356    CHECK_EQ(expected, m.Call(*i));
3357  }
3358}
3359
3360
3361TEST(RunInt32NegP) {
3362  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
3363  m.Return(m.Int32Neg(m.Parameter(0)));
3364  FOR_INT32_INPUTS(i) {
3365    int expected = -*i;
3366    CHECK_EQ(expected, m.Call(*i));
3367  }
3368}
3369
3370
3371TEST(RunWord32EqualAndWord32SarP) {
3372  {
3373    RawMachineAssemblerTester<int32_t> m(
3374        MachineType::Int32(), MachineType::Int32(), MachineType::Uint32());
3375    m.Return(m.Word32Equal(m.Parameter(0),
3376                           m.Word32Sar(m.Parameter(1), m.Parameter(2))));
3377    FOR_INT32_INPUTS(i) {
3378      FOR_INT32_INPUTS(j) {
3379        FOR_UINT32_SHIFTS(shift) {
3380          int32_t expected = (*i == (*j >> shift));
3381          CHECK_EQ(expected, m.Call(*i, *j, shift));
3382        }
3383      }
3384    }
3385  }
3386  {
3387    RawMachineAssemblerTester<int32_t> m(
3388        MachineType::Int32(), MachineType::Uint32(), MachineType::Int32());
3389    m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
3390                           m.Parameter(2)));
3391    FOR_INT32_INPUTS(i) {
3392      FOR_UINT32_SHIFTS(shift) {
3393        FOR_INT32_INPUTS(k) {
3394          int32_t expected = ((*i >> shift) == *k);
3395          CHECK_EQ(expected, m.Call(*i, shift, *k));
3396        }
3397      }
3398    }
3399  }
3400}
3401
3402
3403TEST(RunWord32EqualAndWord32ShlP) {
3404  {
3405    RawMachineAssemblerTester<int32_t> m(
3406        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
3407    m.Return(m.Word32Equal(m.Parameter(0),
3408                           m.Word32Shl(m.Parameter(1), m.Parameter(2))));
3409    FOR_UINT32_INPUTS(i) {
3410      FOR_UINT32_INPUTS(j) {
3411        FOR_UINT32_SHIFTS(shift) {
3412          int32_t expected = (*i == (*j << shift));
3413          CHECK_EQ(expected, m.Call(*i, *j, shift));
3414        }
3415      }
3416    }
3417  }
3418  {
3419    RawMachineAssemblerTester<int32_t> m(
3420        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
3421    m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
3422                           m.Parameter(2)));
3423    FOR_UINT32_INPUTS(i) {
3424      FOR_UINT32_SHIFTS(shift) {
3425        FOR_UINT32_INPUTS(k) {
3426          int32_t expected = ((*i << shift) == *k);
3427          CHECK_EQ(expected, m.Call(*i, shift, *k));
3428        }
3429      }
3430    }
3431  }
3432}
3433
3434
3435TEST(RunWord32EqualAndWord32ShrP) {
3436  {
3437    RawMachineAssemblerTester<int32_t> m(
3438        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
3439    m.Return(m.Word32Equal(m.Parameter(0),
3440                           m.Word32Shr(m.Parameter(1), m.Parameter(2))));
3441    FOR_UINT32_INPUTS(i) {
3442      FOR_UINT32_INPUTS(j) {
3443        FOR_UINT32_SHIFTS(shift) {
3444          int32_t expected = (*i == (*j >> shift));
3445          CHECK_EQ(expected, m.Call(*i, *j, shift));
3446        }
3447      }
3448    }
3449  }
3450  {
3451    RawMachineAssemblerTester<int32_t> m(
3452        MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
3453    m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
3454                           m.Parameter(2)));
3455    FOR_UINT32_INPUTS(i) {
3456      FOR_UINT32_SHIFTS(shift) {
3457        FOR_UINT32_INPUTS(k) {
3458          int32_t expected = ((*i >> shift) == *k);
3459          CHECK_EQ(expected, m.Call(*i, shift, *k));
3460        }
3461      }
3462    }
3463  }
3464}
3465
3466
3467TEST(RunDeadNodes) {
3468  for (int i = 0; true; i++) {
3469    RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32()
3470                                                : MachineType::None());
3471    int constant = 0x55 + i;
3472    switch (i) {
3473      case 0:
3474        m.Int32Constant(44);
3475        break;
3476      case 1:
3477        m.StringConstant("unused");
3478        break;
3479      case 2:
3480        m.NumberConstant(11.1);
3481        break;
3482      case 3:
3483        m.PointerConstant(&constant);
3484        break;
3485      case 4:
3486        m.LoadFromPointer(&constant, MachineType::Int32());
3487        break;
3488      case 5:
3489        m.Parameter(0);
3490        break;
3491      default:
3492        return;
3493    }
3494    m.Return(m.Int32Constant(constant));
3495    if (i != 5) {
3496      CHECK_EQ(constant, m.Call());
3497    } else {
3498      CHECK_EQ(constant, m.Call(0));
3499    }
3500  }
3501}
3502
3503
3504TEST(RunDeadInt32Binops) {
3505  RawMachineAssemblerTester<int32_t> m;
3506
3507  const Operator* kOps[] = {
3508      m.machine()->Word32And(),            m.machine()->Word32Or(),
3509      m.machine()->Word32Xor(),            m.machine()->Word32Shl(),
3510      m.machine()->Word32Shr(),            m.machine()->Word32Sar(),
3511      m.machine()->Word32Ror(),            m.machine()->Word32Equal(),
3512      m.machine()->Int32Add(),             m.machine()->Int32Sub(),
3513      m.machine()->Int32Mul(),             m.machine()->Int32MulHigh(),
3514      m.machine()->Int32Div(),             m.machine()->Uint32Div(),
3515      m.machine()->Int32Mod(),             m.machine()->Uint32Mod(),
3516      m.machine()->Uint32MulHigh(),        m.machine()->Int32LessThan(),
3517      m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
3518      m.machine()->Uint32LessThanOrEqual()};
3519
3520  for (size_t i = 0; i < arraysize(kOps); ++i) {
3521    RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
3522                                         MachineType::Int32());
3523    int32_t constant = static_cast<int32_t>(0x55555 + i);
3524    m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1));
3525    m.Return(m.Int32Constant(constant));
3526
3527    CHECK_EQ(constant, m.Call(1, 1));
3528  }
3529}
3530
3531
3532template <typename Type>
3533static void RunLoadImmIndex(MachineType rep) {
3534  const int kNumElems = 3;
3535  Type buffer[kNumElems];
3536
3537  // initialize the buffer with raw data.
3538  byte* raw = reinterpret_cast<byte*>(buffer);
3539  for (size_t i = 0; i < sizeof(buffer); i++) {
3540    raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
3541  }
3542
3543  // Test with various large and small offsets.
3544  for (int offset = -1; offset <= 200000; offset *= -5) {
3545    for (int i = 0; i < kNumElems; i++) {
3546      RawMachineAssemblerTester<Type> m;
3547      Node* base = m.PointerConstant(buffer - offset);
3548      Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
3549      m.Return(m.Load(rep, base, index));
3550
3551      Type expected = buffer[i];
3552      Type actual = m.Call();
3553      CHECK(expected == actual);
3554    }
3555  }
3556}
3557
3558
3559TEST(RunLoadImmIndex) {
3560  RunLoadImmIndex<int8_t>(MachineType::Int8());
3561  RunLoadImmIndex<uint8_t>(MachineType::Uint8());
3562  RunLoadImmIndex<int16_t>(MachineType::Int16());
3563  RunLoadImmIndex<uint16_t>(MachineType::Uint16());
3564  RunLoadImmIndex<int32_t>(MachineType::Int32());
3565  RunLoadImmIndex<uint32_t>(MachineType::Uint32());
3566  RunLoadImmIndex<int32_t*>(MachineType::AnyTagged());
3567
3568  // TODO(titzer): test kRepBit loads
3569  // TODO(titzer): test MachineType::Float64() loads
3570  // TODO(titzer): test various indexing modes.
3571}
3572
3573
3574template <typename CType>
3575static void RunLoadStore(MachineType rep) {
3576  const int kNumElems = 4;
3577  CType buffer[kNumElems];
3578
3579  for (int32_t x = 0; x < kNumElems; x++) {
3580    int32_t y = kNumElems - x - 1;
3581    // initialize the buffer with raw data.
3582    byte* raw = reinterpret_cast<byte*>(buffer);
3583    for (size_t i = 0; i < sizeof(buffer); i++) {
3584      raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
3585    }
3586
3587    RawMachineAssemblerTester<int32_t> m;
3588    int32_t OK = 0x29000 + x;
3589    Node* base = m.PointerConstant(buffer);
3590    Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0]));
3591    Node* load = m.Load(rep, base, index0);
3592    Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0]));
3593    m.Store(rep.representation(), base, index1, load, kNoWriteBarrier);
3594    m.Return(m.Int32Constant(OK));
3595
3596    CHECK(buffer[x] != buffer[y]);
3597    CHECK_EQ(OK, m.Call());
3598    CHECK(buffer[x] == buffer[y]);
3599  }
3600}
3601
3602
3603TEST(RunLoadStore) {
3604  RunLoadStore<int8_t>(MachineType::Int8());
3605  RunLoadStore<uint8_t>(MachineType::Uint8());
3606  RunLoadStore<int16_t>(MachineType::Int16());
3607  RunLoadStore<uint16_t>(MachineType::Uint16());
3608  RunLoadStore<int32_t>(MachineType::Int32());
3609  RunLoadStore<uint32_t>(MachineType::Uint32());
3610  RunLoadStore<void*>(MachineType::AnyTagged());
3611  RunLoadStore<float>(MachineType::Float32());
3612  RunLoadStore<double>(MachineType::Float64());
3613}
3614
3615
3616TEST(RunFloat32Add) {
3617  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3618                                             MachineType::Float32());
3619  m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1)));
3620
3621  FOR_FLOAT32_INPUTS(i) {
3622    FOR_FLOAT32_INPUTS(j) {
3623      volatile float expected = *i + *j;
3624      CheckFloatEq(expected, m.Call(*i, *j));
3625    }
3626  }
3627}
3628
3629
3630TEST(RunFloat32Sub) {
3631  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3632                                             MachineType::Float32());
3633  m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1)));
3634
3635  FOR_FLOAT32_INPUTS(i) {
3636    FOR_FLOAT32_INPUTS(j) {
3637      volatile float expected = *i - *j;
3638      CheckFloatEq(expected, m.Call(*i, *j));
3639    }
3640  }
3641}
3642
3643
3644TEST(RunFloat32Mul) {
3645  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3646                                             MachineType::Float32());
3647  m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1)));
3648
3649  FOR_FLOAT32_INPUTS(i) {
3650    FOR_FLOAT32_INPUTS(j) {
3651      volatile float expected = *i * *j;
3652      CheckFloatEq(expected, m.Call(*i, *j));
3653    }
3654  }
3655}
3656
3657
3658TEST(RunFloat32Div) {
3659  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3660                                             MachineType::Float32());
3661  m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1)));
3662
3663  FOR_FLOAT32_INPUTS(i) {
3664    FOR_FLOAT32_INPUTS(j) {
3665      volatile float expected = *i / *j;
3666      CheckFloatEq(expected, m.Call(*i, *j));
3667    }
3668  }
3669}
3670
3671
3672TEST(RunFloat64Add) {
3673  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3674                                              MachineType::Float64());
3675  m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1)));
3676
3677  FOR_FLOAT64_INPUTS(i) {
3678    FOR_FLOAT64_INPUTS(j) {
3679      volatile double expected = *i + *j;
3680      CheckDoubleEq(expected, m.Call(*i, *j));
3681    }
3682  }
3683}
3684
3685
3686TEST(RunFloat64Sub) {
3687  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3688                                              MachineType::Float64());
3689  m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1)));
3690
3691  FOR_FLOAT64_INPUTS(i) {
3692    FOR_FLOAT64_INPUTS(j) {
3693      volatile double expected = *i - *j;
3694      CheckDoubleEq(expected, m.Call(*i, *j));
3695    }
3696  }
3697}
3698
3699
3700TEST(RunFloat64Mul) {
3701  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3702                                              MachineType::Float64());
3703  m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1)));
3704
3705  FOR_FLOAT64_INPUTS(i) {
3706    FOR_FLOAT64_INPUTS(j) {
3707      volatile double expected = *i * *j;
3708      CheckDoubleEq(expected, m.Call(*i, *j));
3709    }
3710  }
3711}
3712
3713
3714TEST(RunFloat64Div) {
3715  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3716                                              MachineType::Float64());
3717  m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1)));
3718
3719  FOR_FLOAT64_INPUTS(i) {
3720    FOR_FLOAT64_INPUTS(j) {
3721      volatile double expected = *i / *j;
3722      CheckDoubleEq(expected, m.Call(*i, *j));
3723    }
3724  }
3725}
3726
3727
3728TEST(RunFloat64Mod) {
3729  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3730                                              MachineType::Float64());
3731  m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
3732
3733  FOR_FLOAT64_INPUTS(i) {
3734    FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(modulo(*i, *j), m.Call(*i, *j)); }
3735  }
3736}
3737
3738
3739TEST(RunDeadFloat32Binops) {
3740  RawMachineAssemblerTester<int32_t> m;
3741
3742  const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(),
3743                           m.machine()->Float32Mul(), m.machine()->Float32Div(),
3744                           NULL};
3745
3746  for (int i = 0; ops[i] != NULL; i++) {
3747    RawMachineAssemblerTester<int32_t> m;
3748    int constant = 0x53355 + i;
3749    m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f));
3750    m.Return(m.Int32Constant(constant));
3751    CHECK_EQ(constant, m.Call());
3752  }
3753}
3754
3755
3756TEST(RunDeadFloat64Binops) {
3757  RawMachineAssemblerTester<int32_t> m;
3758
3759  const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3760                           m.machine()->Float64Mul(), m.machine()->Float64Div(),
3761                           m.machine()->Float64Mod(), NULL};
3762
3763  for (int i = 0; ops[i] != NULL; i++) {
3764    RawMachineAssemblerTester<int32_t> m;
3765    int constant = 0x53355 + i;
3766    m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
3767    m.Return(m.Int32Constant(constant));
3768    CHECK_EQ(constant, m.Call());
3769  }
3770}
3771
3772
3773TEST(RunFloat32AddP) {
3774  RawMachineAssemblerTester<int32_t> m;
3775  Float32BinopTester bt(&m);
3776
3777  bt.AddReturn(m.Float32Add(bt.param0, bt.param1));
3778
3779  FOR_FLOAT32_INPUTS(pl) {
3780    FOR_FLOAT32_INPUTS(pr) {
3781      float expected = *pl + *pr;
3782      CheckFloatEq(expected, bt.call(*pl, *pr));
3783    }
3784  }
3785}
3786
3787
3788TEST(RunFloat64AddP) {
3789  RawMachineAssemblerTester<int32_t> m;
3790  Float64BinopTester bt(&m);
3791
3792  bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
3793
3794  FOR_FLOAT64_INPUTS(pl) {
3795    FOR_FLOAT64_INPUTS(pr) {
3796      double expected = *pl + *pr;
3797      CheckDoubleEq(expected, bt.call(*pl, *pr));
3798    }
3799  }
3800}
3801
3802
3803TEST(RunFloa32MaxP) {
3804  RawMachineAssemblerTester<int32_t> m;
3805  Float32BinopTester bt(&m);
3806  if (!m.machine()->Float32Max().IsSupported()) return;
3807
3808  bt.AddReturn(m.Float32Max(bt.param0, bt.param1));
3809
3810  FOR_FLOAT32_INPUTS(pl) {
3811    FOR_FLOAT32_INPUTS(pr) {
3812      double expected = *pl > *pr ? *pl : *pr;
3813      CheckDoubleEq(expected, bt.call(*pl, *pr));
3814    }
3815  }
3816}
3817
3818
3819TEST(RunFloat64MaxP) {
3820  RawMachineAssemblerTester<int32_t> m;
3821  Float64BinopTester bt(&m);
3822  if (!m.machine()->Float64Max().IsSupported()) return;
3823
3824  bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
3825
3826  FOR_FLOAT64_INPUTS(pl) {
3827    FOR_FLOAT64_INPUTS(pr) {
3828      double expected = *pl > *pr ? *pl : *pr;
3829      CheckDoubleEq(expected, bt.call(*pl, *pr));
3830    }
3831  }
3832}
3833
3834
3835TEST(RunFloat32MinP) {
3836  RawMachineAssemblerTester<int32_t> m;
3837  Float32BinopTester bt(&m);
3838  if (!m.machine()->Float32Min().IsSupported()) return;
3839
3840  bt.AddReturn(m.Float32Min(bt.param0, bt.param1));
3841
3842  FOR_FLOAT32_INPUTS(pl) {
3843    FOR_FLOAT32_INPUTS(pr) {
3844      double expected = *pl < *pr ? *pl : *pr;
3845      CheckDoubleEq(expected, bt.call(*pl, *pr));
3846    }
3847  }
3848}
3849
3850
3851TEST(RunFloat64MinP) {
3852  RawMachineAssemblerTester<int32_t> m;
3853  Float64BinopTester bt(&m);
3854  if (!m.machine()->Float64Min().IsSupported()) return;
3855
3856  bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
3857
3858  FOR_FLOAT64_INPUTS(pl) {
3859    FOR_FLOAT64_INPUTS(pr) {
3860      double expected = *pl < *pr ? *pl : *pr;
3861      CheckDoubleEq(expected, bt.call(*pl, *pr));
3862    }
3863  }
3864}
3865
3866
3867TEST(RunFloat32SubP) {
3868  RawMachineAssemblerTester<int32_t> m;
3869  Float32BinopTester bt(&m);
3870
3871  bt.AddReturn(m.Float32Sub(bt.param0, bt.param1));
3872
3873  FOR_FLOAT32_INPUTS(pl) {
3874    FOR_FLOAT32_INPUTS(pr) {
3875      float expected = *pl - *pr;
3876      CheckFloatEq(expected, bt.call(*pl, *pr));
3877    }
3878  }
3879}
3880
3881
3882TEST(RunFloat32SubImm1) {
3883  FOR_FLOAT32_INPUTS(i) {
3884    BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3885    m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0)));
3886
3887    FOR_FLOAT32_INPUTS(j) {
3888      volatile float expected = *i - *j;
3889      CheckFloatEq(expected, m.Call(*j));
3890    }
3891  }
3892}
3893
3894
3895TEST(RunFloat32SubImm2) {
3896  FOR_FLOAT32_INPUTS(i) {
3897    BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3898    m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i)));
3899
3900    FOR_FLOAT32_INPUTS(j) {
3901      volatile float expected = *j - *i;
3902      CheckFloatEq(expected, m.Call(*j));
3903    }
3904  }
3905}
3906
3907
3908TEST(RunFloat64SubImm1) {
3909  FOR_FLOAT64_INPUTS(i) {
3910    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3911    m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
3912
3913    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i - *j, m.Call(*j)); }
3914  }
3915}
3916
3917
3918TEST(RunFloat64SubImm2) {
3919  FOR_FLOAT64_INPUTS(i) {
3920    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3921    m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
3922
3923    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j - *i, m.Call(*j)); }
3924  }
3925}
3926
3927
3928TEST(RunFloat64SubP) {
3929  RawMachineAssemblerTester<int32_t> m;
3930  Float64BinopTester bt(&m);
3931
3932  bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
3933
3934  FOR_FLOAT64_INPUTS(pl) {
3935    FOR_FLOAT64_INPUTS(pr) {
3936      double expected = *pl - *pr;
3937      CheckDoubleEq(expected, bt.call(*pl, *pr));
3938    }
3939  }
3940}
3941
3942
3943TEST(RunFloat32MulP) {
3944  RawMachineAssemblerTester<int32_t> m;
3945  Float32BinopTester bt(&m);
3946
3947  bt.AddReturn(m.Float32Mul(bt.param0, bt.param1));
3948
3949  FOR_FLOAT32_INPUTS(pl) {
3950    FOR_FLOAT32_INPUTS(pr) {
3951      float expected = *pl * *pr;
3952      CheckFloatEq(expected, bt.call(*pl, *pr));
3953    }
3954  }
3955}
3956
3957
3958TEST(RunFloat64MulP) {
3959  RawMachineAssemblerTester<int32_t> m;
3960  Float64BinopTester bt(&m);
3961
3962  bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
3963
3964  FOR_FLOAT64_INPUTS(pl) {
3965    FOR_FLOAT64_INPUTS(pr) {
3966      double expected = *pl * *pr;
3967      CheckDoubleEq(expected, bt.call(*pl, *pr));
3968    }
3969  }
3970}
3971
3972
3973TEST(RunFloat64MulAndFloat64Add1) {
3974  BufferedRawMachineAssemblerTester<double> m(
3975      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3976  m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
3977                        m.Parameter(2)));
3978
3979  FOR_FLOAT64_INPUTS(i) {
3980    FOR_FLOAT64_INPUTS(j) {
3981      FOR_FLOAT64_INPUTS(k) {
3982        CheckDoubleEq((*i * *j) + *k, m.Call(*i, *j, *k));
3983      }
3984    }
3985  }
3986}
3987
3988
3989TEST(RunFloat64MulAndFloat64Add2) {
3990  BufferedRawMachineAssemblerTester<double> m(
3991      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3992  m.Return(m.Float64Add(m.Parameter(0),
3993                        m.Float64Mul(m.Parameter(1), m.Parameter(2))));
3994
3995  FOR_FLOAT64_INPUTS(i) {
3996    FOR_FLOAT64_INPUTS(j) {
3997      FOR_FLOAT64_INPUTS(k) {
3998        CheckDoubleEq(*i + (*j * *k), m.Call(*i, *j, *k));
3999      }
4000    }
4001  }
4002}
4003
4004
4005TEST(RunFloat64MulAndFloat64Sub1) {
4006  BufferedRawMachineAssemblerTester<double> m(
4007      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4008  m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
4009                        m.Parameter(2)));
4010
4011  FOR_FLOAT64_INPUTS(i) {
4012    FOR_FLOAT64_INPUTS(j) {
4013      FOR_FLOAT64_INPUTS(k) {
4014        CheckDoubleEq((*i * *j) - *k, m.Call(*i, *j, *k));
4015      }
4016    }
4017  }
4018}
4019
4020
4021TEST(RunFloat64MulAndFloat64Sub2) {
4022  BufferedRawMachineAssemblerTester<double> m(
4023      MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4024  m.Return(m.Float64Sub(m.Parameter(0),
4025                        m.Float64Mul(m.Parameter(1), m.Parameter(2))));
4026
4027  FOR_FLOAT64_INPUTS(i) {
4028    FOR_FLOAT64_INPUTS(j) {
4029      FOR_FLOAT64_INPUTS(k) {
4030        CheckDoubleEq(*i - (*j * *k), m.Call(*i, *j, *k));
4031      }
4032    }
4033  }
4034}
4035
4036
4037TEST(RunFloat64MulImm1) {
4038  FOR_FLOAT64_INPUTS(i) {
4039    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4040    m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
4041
4042    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i * *j, m.Call(*j)); }
4043  }
4044}
4045
4046
4047TEST(RunFloat64MulImm2) {
4048  FOR_FLOAT64_INPUTS(i) {
4049    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4050    m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
4051
4052    FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j * *i, m.Call(*j)); }
4053  }
4054}
4055
4056
4057TEST(RunFloat32DivP) {
4058  RawMachineAssemblerTester<int32_t> m;
4059  Float32BinopTester bt(&m);
4060
4061  bt.AddReturn(m.Float32Div(bt.param0, bt.param1));
4062
4063  FOR_FLOAT32_INPUTS(pl) {
4064    FOR_FLOAT32_INPUTS(pr) {
4065      float expected = *pl / *pr;
4066      CheckFloatEq(expected, bt.call(*pl, *pr));
4067    }
4068  }
4069}
4070
4071
4072TEST(RunFloat64DivP) {
4073  RawMachineAssemblerTester<int32_t> m;
4074  Float64BinopTester bt(&m);
4075
4076  bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
4077
4078  FOR_FLOAT64_INPUTS(pl) {
4079    FOR_FLOAT64_INPUTS(pr) {
4080      double expected = *pl / *pr;
4081      CheckDoubleEq(expected, bt.call(*pl, *pr));
4082    }
4083  }
4084}
4085
4086
4087TEST(RunFloat64ModP) {
4088  RawMachineAssemblerTester<int32_t> m;
4089  Float64BinopTester bt(&m);
4090
4091  bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
4092
4093  FOR_FLOAT64_INPUTS(i) {
4094    FOR_FLOAT64_INPUTS(j) {
4095      double expected = modulo(*i, *j);
4096      double found = bt.call(*i, *j);
4097      CheckDoubleEq(expected, found);
4098    }
4099  }
4100}
4101
4102
4103TEST(RunChangeInt32ToFloat64_A) {
4104  int32_t magic = 0x986234;
4105  BufferedRawMachineAssemblerTester<double> m;
4106  m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic)));
4107  CheckDoubleEq(static_cast<double>(magic), m.Call());
4108}
4109
4110
4111TEST(RunChangeInt32ToFloat64_B) {
4112  BufferedRawMachineAssemblerTester<double> m(MachineType::Int32());
4113  m.Return(m.ChangeInt32ToFloat64(m.Parameter(0)));
4114
4115  FOR_INT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
4116}
4117
4118
4119TEST(RunChangeUint32ToFloat64) {
4120  BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32());
4121  m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
4122
4123  FOR_UINT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
4124}
4125
4126
4127TEST(RunChangeFloat64ToInt32_A) {
4128  BufferedRawMachineAssemblerTester<int32_t> m;
4129  double magic = 11.1;
4130  m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic)));
4131  CHECK_EQ(static_cast<int32_t>(magic), m.Call());
4132}
4133
4134
4135TEST(RunChangeFloat64ToInt32_B) {
4136  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64());
4137  m.Return(m.ChangeFloat64ToInt32(m.Parameter(0)));
4138
4139  // Note we don't check fractional inputs, or inputs outside the range of
4140  // int32, because these Convert operators really should be Change operators.
4141  FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
4142
4143  for (int32_t n = 1; n < 31; ++n) {
4144    CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n)));
4145  }
4146
4147  for (int32_t n = 1; n < 31; ++n) {
4148    CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n)));
4149  }
4150}
4151
4152
4153TEST(RunChangeFloat64ToUint32) {
4154  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
4155  m.Return(m.ChangeFloat64ToUint32(m.Parameter(0)));
4156
4157  {
4158    FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
4159  }
4160
4161  // Check various powers of 2.
4162  for (int32_t n = 1; n < 31; ++n) {
4163    { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); }
4164
4165    { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); }
4166  }
4167  // Note we don't check fractional inputs, because these Convert operators
4168  // really should be Change operators.
4169}
4170
4171
4172TEST(RunTruncateFloat64ToFloat32) {
4173  BufferedRawMachineAssemblerTester<float> m(MachineType::Float64());
4174
4175  m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
4176
4177  FOR_FLOAT64_INPUTS(i) { CheckFloatEq(DoubleToFloat32(*i), m.Call(*i)); }
4178}
4179
4180
4181TEST(RunDeadChangeFloat64ToInt32) {
4182  RawMachineAssemblerTester<int32_t> m;
4183  const int magic = 0x88abcda4;
4184  m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
4185  m.Return(m.Int32Constant(magic));
4186  CHECK_EQ(magic, m.Call());
4187}
4188
4189
4190TEST(RunDeadChangeInt32ToFloat64) {
4191  RawMachineAssemblerTester<int32_t> m;
4192  const int magic = 0x8834abcd;
4193  m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
4194  m.Return(m.Int32Constant(magic));
4195  CHECK_EQ(magic, m.Call());
4196}
4197
4198
4199TEST(RunLoopPhiInduction2) {
4200  RawMachineAssemblerTester<int32_t> m;
4201
4202  int false_val = 0x10777;
4203
4204  // x = false_val; while(false) { x++; } return x;
4205  RawMachineLabel header, body, end;
4206  Node* false_node = m.Int32Constant(false_val);
4207  m.Goto(&header);
4208  m.Bind(&header);
4209  Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
4210  m.Branch(m.Int32Constant(0), &body, &end);
4211  m.Bind(&body);
4212  Node* add = m.Int32Add(phi, m.Int32Constant(1));
4213  phi->ReplaceInput(1, add);
4214  m.Goto(&header);
4215  m.Bind(&end);
4216  m.Return(phi);
4217
4218  CHECK_EQ(false_val, m.Call());
4219}
4220
4221
4222TEST(RunFloatDiamond) {
4223  RawMachineAssemblerTester<int32_t> m;
4224
4225  const int magic = 99645;
4226  float buffer = 0.1f;
4227  float constant = 99.99f;
4228
4229  RawMachineLabel blocka, blockb, end;
4230  Node* k1 = m.Float32Constant(constant);
4231  Node* k2 = m.Float32Constant(0 - constant);
4232  m.Branch(m.Int32Constant(0), &blocka, &blockb);
4233  m.Bind(&blocka);
4234  m.Goto(&end);
4235  m.Bind(&blockb);
4236  m.Goto(&end);
4237  m.Bind(&end);
4238  Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1);
4239  m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer),
4240          m.IntPtrConstant(0), phi, kNoWriteBarrier);
4241  m.Return(m.Int32Constant(magic));
4242
4243  CHECK_EQ(magic, m.Call());
4244  CHECK(constant == buffer);
4245}
4246
4247
4248TEST(RunDoubleDiamond) {
4249  RawMachineAssemblerTester<int32_t> m;
4250
4251  const int magic = 99645;
4252  double buffer = 0.1;
4253  double constant = 99.99;
4254
4255  RawMachineLabel blocka, blockb, end;
4256  Node* k1 = m.Float64Constant(constant);
4257  Node* k2 = m.Float64Constant(0 - constant);
4258  m.Branch(m.Int32Constant(0), &blocka, &blockb);
4259  m.Bind(&blocka);
4260  m.Goto(&end);
4261  m.Bind(&blockb);
4262  m.Goto(&end);
4263  m.Bind(&end);
4264  Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1);
4265  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4266          m.Int32Constant(0), phi, kNoWriteBarrier);
4267  m.Return(m.Int32Constant(magic));
4268
4269  CHECK_EQ(magic, m.Call());
4270  CHECK_EQ(constant, buffer);
4271}
4272
4273
4274TEST(RunRefDiamond) {
4275  RawMachineAssemblerTester<int32_t> m;
4276
4277  const int magic = 99644;
4278  Handle<String> rexpected =
4279      CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
4280  String* buffer;
4281
4282  RawMachineLabel blocka, blockb, end;
4283  Node* k1 = m.StringConstant("A");
4284  Node* k2 = m.StringConstant("B");
4285  m.Branch(m.Int32Constant(0), &blocka, &blockb);
4286  m.Bind(&blocka);
4287  m.Goto(&end);
4288  m.Bind(&blockb);
4289  m.Goto(&end);
4290  m.Bind(&end);
4291  Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1);
4292  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer),
4293          m.Int32Constant(0), phi, kNoWriteBarrier);
4294  m.Return(m.Int32Constant(magic));
4295
4296  CHECK_EQ(magic, m.Call());
4297  CHECK(rexpected->SameValue(buffer));
4298}
4299
4300
4301TEST(RunDoubleRefDiamond) {
4302  RawMachineAssemblerTester<int32_t> m;
4303
4304  const int magic = 99648;
4305  double dbuffer = 0.1;
4306  double dconstant = 99.99;
4307  Handle<String> rexpected =
4308      CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
4309  String* rbuffer;
4310
4311  RawMachineLabel blocka, blockb, end;
4312  Node* d1 = m.Float64Constant(dconstant);
4313  Node* d2 = m.Float64Constant(0 - dconstant);
4314  Node* r1 = m.StringConstant("AX");
4315  Node* r2 = m.StringConstant("BX");
4316  m.Branch(m.Int32Constant(0), &blocka, &blockb);
4317  m.Bind(&blocka);
4318  m.Goto(&end);
4319  m.Bind(&blockb);
4320  m.Goto(&end);
4321  m.Bind(&end);
4322  Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4323  Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1);
4324  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4325          m.Int32Constant(0), dphi, kNoWriteBarrier);
4326  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4327          m.Int32Constant(0), rphi, kNoWriteBarrier);
4328  m.Return(m.Int32Constant(magic));
4329
4330  CHECK_EQ(magic, m.Call());
4331  CHECK_EQ(dconstant, dbuffer);
4332  CHECK(rexpected->SameValue(rbuffer));
4333}
4334
4335
4336TEST(RunDoubleRefDoubleDiamond) {
4337  RawMachineAssemblerTester<int32_t> m;
4338
4339  const int magic = 99649;
4340  double dbuffer = 0.1;
4341  double dconstant = 99.997;
4342  Handle<String> rexpected =
4343      CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
4344  String* rbuffer;
4345
4346  RawMachineLabel blocka, blockb, mid, blockd, blocke, end;
4347  Node* d1 = m.Float64Constant(dconstant);
4348  Node* d2 = m.Float64Constant(0 - dconstant);
4349  Node* r1 = m.StringConstant("AD");
4350  Node* r2 = m.StringConstant("BD");
4351  m.Branch(m.Int32Constant(0), &blocka, &blockb);
4352  m.Bind(&blocka);
4353  m.Goto(&mid);
4354  m.Bind(&blockb);
4355  m.Goto(&mid);
4356  m.Bind(&mid);
4357  Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4358  Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1);
4359  m.Branch(m.Int32Constant(0), &blockd, &blocke);
4360
4361  m.Bind(&blockd);
4362  m.Goto(&end);
4363  m.Bind(&blocke);
4364  m.Goto(&end);
4365  m.Bind(&end);
4366  Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1);
4367  Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1);
4368
4369  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4370          m.Int32Constant(0), dphi2, kNoWriteBarrier);
4371  m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4372          m.Int32Constant(0), rphi2, kNoWriteBarrier);
4373  m.Return(m.Int32Constant(magic));
4374
4375  CHECK_EQ(magic, m.Call());
4376  CHECK_EQ(dconstant, dbuffer);
4377  CHECK(rexpected->SameValue(rbuffer));
4378}
4379
4380
4381TEST(RunDoubleLoopPhi) {
4382  RawMachineAssemblerTester<int32_t> m;
4383  RawMachineLabel header, body, end;
4384
4385  int magic = 99773;
4386  double buffer = 0.99;
4387  double dconstant = 777.1;
4388
4389  Node* zero = m.Int32Constant(0);
4390  Node* dk = m.Float64Constant(dconstant);
4391
4392  m.Goto(&header);
4393  m.Bind(&header);
4394  Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk);
4395  phi->ReplaceInput(1, phi);
4396  m.Branch(zero, &body, &end);
4397  m.Bind(&body);
4398  m.Goto(&header);
4399  m.Bind(&end);
4400  m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4401          m.Int32Constant(0), phi, kNoWriteBarrier);
4402  m.Return(m.Int32Constant(magic));
4403
4404  CHECK_EQ(magic, m.Call());
4405}
4406
4407
4408TEST(RunCountToTenAccRaw) {
4409  RawMachineAssemblerTester<int32_t> m;
4410
4411  Node* zero = m.Int32Constant(0);
4412  Node* ten = m.Int32Constant(10);
4413  Node* one = m.Int32Constant(1);
4414
4415  RawMachineLabel header, body, body_cont, end;
4416
4417  m.Goto(&header);
4418
4419  m.Bind(&header);
4420  Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4421  Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
4422  m.Goto(&body);
4423
4424  m.Bind(&body);
4425  Node* next_i = m.Int32Add(i, one);
4426  Node* next_j = m.Int32Add(j, one);
4427  m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4428
4429  m.Bind(&body_cont);
4430  i->ReplaceInput(1, next_i);
4431  j->ReplaceInput(1, next_j);
4432  m.Goto(&header);
4433
4434  m.Bind(&end);
4435  m.Return(ten);
4436
4437  CHECK_EQ(10, m.Call());
4438}
4439
4440
4441TEST(RunCountToTenAccRaw2) {
4442  RawMachineAssemblerTester<int32_t> m;
4443
4444  Node* zero = m.Int32Constant(0);
4445  Node* ten = m.Int32Constant(10);
4446  Node* one = m.Int32Constant(1);
4447
4448  RawMachineLabel header, body, body_cont, end;
4449
4450  m.Goto(&header);
4451
4452  m.Bind(&header);
4453  Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4454  Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
4455  Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero);
4456  m.Goto(&body);
4457
4458  m.Bind(&body);
4459  Node* next_i = m.Int32Add(i, one);
4460  Node* next_j = m.Int32Add(j, one);
4461  Node* next_k = m.Int32Add(j, one);
4462  m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4463
4464  m.Bind(&body_cont);
4465  i->ReplaceInput(1, next_i);
4466  j->ReplaceInput(1, next_j);
4467  k->ReplaceInput(1, next_k);
4468  m.Goto(&header);
4469
4470  m.Bind(&end);
4471  m.Return(ten);
4472
4473  CHECK_EQ(10, m.Call());
4474}
4475
4476
4477TEST(RunAddTree) {
4478  RawMachineAssemblerTester<int32_t> m;
4479  int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
4480
4481  Node* base = m.PointerConstant(inputs);
4482  Node* n0 =
4483      m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t)));
4484  Node* n1 =
4485      m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t)));
4486  Node* n2 =
4487      m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t)));
4488  Node* n3 =
4489      m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t)));
4490  Node* n4 =
4491      m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t)));
4492  Node* n5 =
4493      m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t)));
4494  Node* n6 =
4495      m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t)));
4496  Node* n7 =
4497      m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t)));
4498
4499  Node* i1 = m.Int32Add(n0, n1);
4500  Node* i2 = m.Int32Add(n2, n3);
4501  Node* i3 = m.Int32Add(n4, n5);
4502  Node* i4 = m.Int32Add(n6, n7);
4503
4504  Node* i5 = m.Int32Add(i1, i2);
4505  Node* i6 = m.Int32Add(i3, i4);
4506
4507  Node* i7 = m.Int32Add(i5, i6);
4508
4509  m.Return(i7);
4510
4511  CHECK_EQ(116, m.Call());
4512}
4513
4514
4515static const int kFloat64CompareHelperTestCases = 15;
4516static const int kFloat64CompareHelperNodeType = 4;
4517
4518static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
4519                                int test_case, int node_type, double x,
4520                                double y) {
4521  static double buffer[2];
4522  buffer[0] = x;
4523  buffer[1] = y;
4524  CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
4525  CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
4526  CHECK(x < y);
4527  bool load_a = node_type / 2 == 1;
4528  bool load_b = node_type % 2 == 1;
4529  Node* a =
4530      load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0]))
4531             : m->Float64Constant(x);
4532  Node* b =
4533      load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1]))
4534             : m->Float64Constant(y);
4535  Node* cmp = NULL;
4536  bool expected = false;
4537  switch (test_case) {
4538    // Equal tests.
4539    case 0:
4540      cmp = m->Float64Equal(a, b);
4541      expected = false;
4542      break;
4543    case 1:
4544      cmp = m->Float64Equal(a, a);
4545      expected = true;
4546      break;
4547    // LessThan tests.
4548    case 2:
4549      cmp = m->Float64LessThan(a, b);
4550      expected = true;
4551      break;
4552    case 3:
4553      cmp = m->Float64LessThan(b, a);
4554      expected = false;
4555      break;
4556    case 4:
4557      cmp = m->Float64LessThan(a, a);
4558      expected = false;
4559      break;
4560    // LessThanOrEqual tests.
4561    case 5:
4562      cmp = m->Float64LessThanOrEqual(a, b);
4563      expected = true;
4564      break;
4565    case 6:
4566      cmp = m->Float64LessThanOrEqual(b, a);
4567      expected = false;
4568      break;
4569    case 7:
4570      cmp = m->Float64LessThanOrEqual(a, a);
4571      expected = true;
4572      break;
4573    // NotEqual tests.
4574    case 8:
4575      cmp = m->Float64NotEqual(a, b);
4576      expected = true;
4577      break;
4578    case 9:
4579      cmp = m->Float64NotEqual(b, a);
4580      expected = true;
4581      break;
4582    case 10:
4583      cmp = m->Float64NotEqual(a, a);
4584      expected = false;
4585      break;
4586    // GreaterThan tests.
4587    case 11:
4588      cmp = m->Float64GreaterThan(a, a);
4589      expected = false;
4590      break;
4591    case 12:
4592      cmp = m->Float64GreaterThan(a, b);
4593      expected = false;
4594      break;
4595    // GreaterThanOrEqual tests.
4596    case 13:
4597      cmp = m->Float64GreaterThanOrEqual(a, a);
4598      expected = true;
4599      break;
4600    case 14:
4601      cmp = m->Float64GreaterThanOrEqual(b, a);
4602      expected = true;
4603      break;
4604    default:
4605      UNREACHABLE();
4606  }
4607  m->Return(cmp);
4608  return expected;
4609}
4610
4611
4612TEST(RunFloat64Compare) {
4613  double inf = V8_INFINITY;
4614  // All pairs (a1, a2) are of the form a1 < a2.
4615  double inputs[] = {0.0,  1.0,  -1.0, 0.22, -1.22, 0.22,
4616                     -inf, 0.22, 0.22, inf,  -inf,  inf};
4617
4618  for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
4619    for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
4620         node_type++) {
4621      for (size_t input = 0; input < arraysize(inputs); input += 2) {
4622        RawMachineAssemblerTester<int32_t> m;
4623        int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
4624                                            inputs[input + 1]);
4625        CHECK_EQ(expected, m.Call());
4626      }
4627    }
4628  }
4629}
4630
4631
4632TEST(RunFloat64UnorderedCompare) {
4633  RawMachineAssemblerTester<int32_t> m;
4634
4635  const Operator* operators[] = {m.machine()->Float64Equal(),
4636                                 m.machine()->Float64LessThan(),
4637                                 m.machine()->Float64LessThanOrEqual()};
4638
4639  double nan = std::numeric_limits<double>::quiet_NaN();
4640
4641  FOR_FLOAT64_INPUTS(i) {
4642    for (size_t o = 0; o < arraysize(operators); ++o) {
4643      for (int j = 0; j < 2; j++) {
4644        RawMachineAssemblerTester<int32_t> m;
4645        Node* a = m.Float64Constant(*i);
4646        Node* b = m.Float64Constant(nan);
4647        if (j == 1) std::swap(a, b);
4648        m.Return(m.AddNode(operators[o], a, b));
4649        CHECK_EQ(0, m.Call());
4650      }
4651    }
4652  }
4653}
4654
4655
4656TEST(RunFloat64Equal) {
4657  double input_a = 0.0;
4658  double input_b = 0.0;
4659
4660  RawMachineAssemblerTester<int32_t> m;
4661  Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4662  Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
4663  m.Return(m.Float64Equal(a, b));
4664
4665  CompareWrapper cmp(IrOpcode::kFloat64Equal);
4666  FOR_FLOAT64_INPUTS(pl) {
4667    FOR_FLOAT64_INPUTS(pr) {
4668      input_a = *pl;
4669      input_b = *pr;
4670      int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4671      CHECK_EQ(expected, m.Call());
4672    }
4673  }
4674}
4675
4676
4677TEST(RunFloat64LessThan) {
4678  double input_a = 0.0;
4679  double input_b = 0.0;
4680
4681  RawMachineAssemblerTester<int32_t> m;
4682  Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4683  Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
4684  m.Return(m.Float64LessThan(a, b));
4685
4686  CompareWrapper cmp(IrOpcode::kFloat64LessThan);
4687  FOR_FLOAT64_INPUTS(pl) {
4688    FOR_FLOAT64_INPUTS(pr) {
4689      input_a = *pl;
4690      input_b = *pr;
4691      int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4692      CHECK_EQ(expected, m.Call());
4693    }
4694  }
4695}
4696
4697
4698template <typename IntType>
4699static void LoadStoreTruncation(MachineType kRepresentation) {
4700  IntType input;
4701
4702  RawMachineAssemblerTester<int32_t> m;
4703  Node* a = m.LoadFromPointer(&input, kRepresentation);
4704  Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
4705  m.StoreToPointer(&input, kRepresentation.representation(), ap1);
4706  m.Return(ap1);
4707
4708  const IntType max = std::numeric_limits<IntType>::max();
4709  const IntType min = std::numeric_limits<IntType>::min();
4710
4711  // Test upper bound.
4712  input = max;
4713  CHECK_EQ(max + 1, m.Call());
4714  CHECK_EQ(min, input);
4715
4716  // Test lower bound.
4717  input = min;
4718  CHECK_EQ(static_cast<IntType>(max + 2), m.Call());
4719  CHECK_EQ(min + 1, input);
4720
4721  // Test all one byte values that are not one byte bounds.
4722  for (int i = -127; i < 127; i++) {
4723    input = i;
4724    int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
4725    CHECK_EQ(static_cast<IntType>(expected), m.Call());
4726    CHECK_EQ(static_cast<IntType>(i + 1), input);
4727  }
4728}
4729
4730
4731TEST(RunLoadStoreTruncation) {
4732  LoadStoreTruncation<int8_t>(MachineType::Int8());
4733  LoadStoreTruncation<int16_t>(MachineType::Int16());
4734}
4735
4736
4737static void IntPtrCompare(intptr_t left, intptr_t right) {
4738  for (int test = 0; test < 7; test++) {
4739    RawMachineAssemblerTester<bool> m(MachineType::Pointer(),
4740                                      MachineType::Pointer());
4741    Node* p0 = m.Parameter(0);
4742    Node* p1 = m.Parameter(1);
4743    Node* res = NULL;
4744    bool expected = false;
4745    switch (test) {
4746      case 0:
4747        res = m.IntPtrLessThan(p0, p1);
4748        expected = true;
4749        break;
4750      case 1:
4751        res = m.IntPtrLessThanOrEqual(p0, p1);
4752        expected = true;
4753        break;
4754      case 2:
4755        res = m.IntPtrEqual(p0, p1);
4756        expected = false;
4757        break;
4758      case 3:
4759        res = m.IntPtrGreaterThanOrEqual(p0, p1);
4760        expected = false;
4761        break;
4762      case 4:
4763        res = m.IntPtrGreaterThan(p0, p1);
4764        expected = false;
4765        break;
4766      case 5:
4767        res = m.IntPtrEqual(p0, p0);
4768        expected = true;
4769        break;
4770      case 6:
4771        res = m.IntPtrNotEqual(p0, p1);
4772        expected = true;
4773        break;
4774      default:
4775        UNREACHABLE();
4776        break;
4777    }
4778    m.Return(res);
4779    CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
4780                              reinterpret_cast<int32_t*>(right)));
4781  }
4782}
4783
4784
4785TEST(RunIntPtrCompare) {
4786  intptr_t min = std::numeric_limits<intptr_t>::min();
4787  intptr_t max = std::numeric_limits<intptr_t>::max();
4788  // An ascending chain of intptr_t
4789  intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
4790  for (size_t i = 0; i < arraysize(inputs) - 1; i++) {
4791    IntPtrCompare(inputs[i], inputs[i + 1]);
4792  }
4793}
4794
4795
4796TEST(RunTestIntPtrArithmetic) {
4797  static const int kInputSize = 10;
4798  int32_t inputs[kInputSize];
4799  int32_t outputs[kInputSize];
4800  for (int i = 0; i < kInputSize; i++) {
4801    inputs[i] = i;
4802    outputs[i] = -1;
4803  }
4804  RawMachineAssemblerTester<int32_t*> m;
4805  Node* input = m.PointerConstant(&inputs[0]);
4806  Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
4807  Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
4808  for (int i = 0; i < kInputSize; i++) {
4809    m.Store(MachineRepresentation::kWord32, output,
4810            m.Load(MachineType::Int32(), input), kNoWriteBarrier);
4811    input = m.IntPtrAdd(input, elem_size);
4812    output = m.IntPtrSub(output, elem_size);
4813  }
4814  m.Return(input);
4815  CHECK_EQ(&inputs[kInputSize], m.Call());
4816  for (int i = 0; i < kInputSize; i++) {
4817    CHECK_EQ(i, inputs[i]);
4818    CHECK_EQ(kInputSize - i - 1, outputs[i]);
4819  }
4820}
4821
4822
4823TEST(RunSpillLotsOfThings) {
4824  static const int kInputSize = 1000;
4825  RawMachineAssemblerTester<int32_t> m;
4826  Node* accs[kInputSize];
4827  int32_t outputs[kInputSize];
4828  Node* one = m.Int32Constant(1);
4829  Node* acc = one;
4830  for (int i = 0; i < kInputSize; i++) {
4831    acc = m.Int32Add(acc, one);
4832    accs[i] = acc;
4833  }
4834  for (int i = 0; i < kInputSize; i++) {
4835    m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
4836  }
4837  m.Return(one);
4838  m.Call();
4839  for (int i = 0; i < kInputSize; i++) {
4840    CHECK_EQ(outputs[i], i + 2);
4841  }
4842}
4843
4844
4845TEST(RunSpillConstantsAndParameters) {
4846  static const int kInputSize = 1000;
4847  static const int32_t kBase = 987;
4848  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
4849                                       MachineType::Int32());
4850  int32_t outputs[kInputSize];
4851  Node* csts[kInputSize];
4852  Node* accs[kInputSize];
4853  Node* acc = m.Int32Constant(0);
4854  for (int i = 0; i < kInputSize; i++) {
4855    csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
4856  }
4857  for (int i = 0; i < kInputSize; i++) {
4858    acc = m.Int32Add(acc, csts[i]);
4859    accs[i] = acc;
4860  }
4861  for (int i = 0; i < kInputSize; i++) {
4862    m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
4863  }
4864  m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
4865  FOR_INT32_INPUTS(i) {
4866    FOR_INT32_INPUTS(j) {
4867      int32_t expected = *i + *j;
4868      for (int k = 0; k < kInputSize; k++) {
4869        expected += kBase + k;
4870      }
4871      CHECK_EQ(expected, m.Call(*i, *j));
4872      expected = 0;
4873      for (int k = 0; k < kInputSize; k++) {
4874        expected += kBase + k;
4875        CHECK_EQ(expected, outputs[k]);
4876      }
4877    }
4878  }
4879}
4880
4881
4882TEST(RunNewSpaceConstantsInPhi) {
4883  RawMachineAssemblerTester<Object*> m(MachineType::Int32());
4884
4885  Isolate* isolate = CcTest::i_isolate();
4886  Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
4887  Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
4888  Node* true_node = m.HeapConstant(true_val);
4889  Node* false_node = m.HeapConstant(false_val);
4890
4891  RawMachineLabel blocka, blockb, end;
4892  m.Branch(m.Parameter(0), &blocka, &blockb);
4893  m.Bind(&blocka);
4894  m.Goto(&end);
4895  m.Bind(&blockb);
4896  m.Goto(&end);
4897
4898  m.Bind(&end);
4899  Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node);
4900  m.Return(phi);
4901
4902  CHECK_EQ(*false_val, m.Call(0));
4903  CHECK_EQ(*true_val, m.Call(1));
4904}
4905
4906
4907TEST(RunInt32AddWithOverflowP) {
4908  int32_t actual_val = -1;
4909  RawMachineAssemblerTester<int32_t> m;
4910  Int32BinopTester bt(&m);
4911  Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
4912  Node* val = m.Projection(0, add);
4913  Node* ovf = m.Projection(1, add);
4914  m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
4915  bt.AddReturn(ovf);
4916  FOR_INT32_INPUTS(i) {
4917    FOR_INT32_INPUTS(j) {
4918      int32_t expected_val;
4919      int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4920      CHECK_EQ(expected_ovf, bt.call(*i, *j));
4921      CHECK_EQ(expected_val, actual_val);
4922    }
4923  }
4924}
4925
4926
4927TEST(RunInt32AddWithOverflowImm) {
4928  int32_t actual_val = -1, expected_val = 0;
4929  FOR_INT32_INPUTS(i) {
4930    {
4931      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
4932      Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
4933      Node* val = m.Projection(0, add);
4934      Node* ovf = m.Projection(1, add);
4935      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
4936      m.Return(ovf);
4937      FOR_INT32_INPUTS(j) {
4938        int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4939        CHECK_EQ(expected_ovf, m.Call(*j));
4940        CHECK_EQ(expected_val, actual_val);
4941      }
4942    }
4943    {
4944      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
4945      Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
4946      Node* val = m.Projection(0, add);
4947      Node* ovf = m.Projection(1, add);
4948      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
4949      m.Return(ovf);
4950      FOR_INT32_INPUTS(j) {
4951        int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4952        CHECK_EQ(expected_ovf, m.Call(*j));
4953        CHECK_EQ(expected_val, actual_val);
4954      }
4955    }
4956    FOR_INT32_INPUTS(j) {
4957      RawMachineAssemblerTester<int32_t> m;
4958      Node* add =
4959          m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
4960      Node* val = m.Projection(0, add);
4961      Node* ovf = m.Projection(1, add);
4962      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
4963      m.Return(ovf);
4964      int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4965      CHECK_EQ(expected_ovf, m.Call());
4966      CHECK_EQ(expected_val, actual_val);
4967    }
4968  }
4969}
4970
4971
4972TEST(RunInt32AddWithOverflowInBranchP) {
4973  int constant = 911777;
4974  RawMachineLabel blocka, blockb;
4975  RawMachineAssemblerTester<int32_t> m;
4976  Int32BinopTester bt(&m);
4977  Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
4978  Node* ovf = m.Projection(1, add);
4979  m.Branch(ovf, &blocka, &blockb);
4980  m.Bind(&blocka);
4981  bt.AddReturn(m.Int32Constant(constant));
4982  m.Bind(&blockb);
4983  Node* val = m.Projection(0, add);
4984  bt.AddReturn(val);
4985  FOR_INT32_INPUTS(i) {
4986    FOR_INT32_INPUTS(j) {
4987      int32_t expected;
4988      if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant;
4989      CHECK_EQ(expected, bt.call(*i, *j));
4990    }
4991  }
4992}
4993
4994
4995TEST(RunInt32SubWithOverflowP) {
4996  int32_t actual_val = -1;
4997  RawMachineAssemblerTester<int32_t> m;
4998  Int32BinopTester bt(&m);
4999  Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
5000  Node* val = m.Projection(0, add);
5001  Node* ovf = m.Projection(1, add);
5002  m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
5003  bt.AddReturn(ovf);
5004  FOR_INT32_INPUTS(i) {
5005    FOR_INT32_INPUTS(j) {
5006      int32_t expected_val;
5007      int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5008      CHECK_EQ(expected_ovf, bt.call(*i, *j));
5009      CHECK_EQ(expected_val, actual_val);
5010    }
5011  }
5012}
5013
5014
5015TEST(RunInt32SubWithOverflowImm) {
5016  int32_t actual_val = -1, expected_val = 0;
5017  FOR_INT32_INPUTS(i) {
5018    {
5019      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5020      Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5021      Node* val = m.Projection(0, add);
5022      Node* ovf = m.Projection(1, add);
5023      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
5024      m.Return(ovf);
5025      FOR_INT32_INPUTS(j) {
5026        int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5027        CHECK_EQ(expected_ovf, m.Call(*j));
5028        CHECK_EQ(expected_val, actual_val);
5029      }
5030    }
5031    {
5032      RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5033      Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5034      Node* val = m.Projection(0, add);
5035      Node* ovf = m.Projection(1, add);
5036      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
5037      m.Return(ovf);
5038      FOR_INT32_INPUTS(j) {
5039        int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
5040        CHECK_EQ(expected_ovf, m.Call(*j));
5041        CHECK_EQ(expected_val, actual_val);
5042      }
5043    }
5044    FOR_INT32_INPUTS(j) {
5045      RawMachineAssemblerTester<int32_t> m;
5046      Node* add =
5047          m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5048      Node* val = m.Projection(0, add);
5049      Node* ovf = m.Projection(1, add);
5050      m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
5051      m.Return(ovf);
5052      int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5053      CHECK_EQ(expected_ovf, m.Call());
5054      CHECK_EQ(expected_val, actual_val);
5055    }
5056  }
5057}
5058
5059
5060TEST(RunInt32SubWithOverflowInBranchP) {
5061  int constant = 911999;
5062  RawMachineLabel blocka, blockb;
5063  RawMachineAssemblerTester<int32_t> m;
5064  Int32BinopTester bt(&m);
5065  Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
5066  Node* ovf = m.Projection(1, sub);
5067  m.Branch(ovf, &blocka, &blockb);
5068  m.Bind(&blocka);
5069  bt.AddReturn(m.Int32Constant(constant));
5070  m.Bind(&blockb);
5071  Node* val = m.Projection(0, sub);
5072  bt.AddReturn(val);
5073  FOR_INT32_INPUTS(i) {
5074    FOR_INT32_INPUTS(j) {
5075      int32_t expected;
5076      if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant;
5077      CHECK_EQ(expected, bt.call(*i, *j));
5078    }
5079  }
5080}
5081
5082
5083TEST(RunWord64EqualInBranchP) {
5084  int64_t input;
5085  RawMachineLabel blocka, blockb;
5086  RawMachineAssemblerTester<int64_t> m;
5087  if (!m.machine()->Is64()) return;
5088  Node* value = m.LoadFromPointer(&input, MachineType::Int64());
5089  m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
5090  m.Bind(&blocka);
5091  m.Return(m.Int32Constant(1));
5092  m.Bind(&blockb);
5093  m.Return(m.Int32Constant(2));
5094  input = V8_INT64_C(0);
5095  CHECK_EQ(1, m.Call());
5096  input = V8_INT64_C(1);
5097  CHECK_EQ(2, m.Call());
5098  input = V8_INT64_C(0x100000000);
5099  CHECK_EQ(2, m.Call());
5100}
5101
5102
5103TEST(RunChangeInt32ToInt64P) {
5104  if (kPointerSize < 8) return;
5105  int64_t actual = -1;
5106  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5107  m.StoreToPointer(&actual, MachineRepresentation::kWord64,
5108                   m.ChangeInt32ToInt64(m.Parameter(0)));
5109  m.Return(m.Int32Constant(0));
5110  FOR_INT32_INPUTS(i) {
5111    int64_t expected = *i;
5112    CHECK_EQ(0, m.Call(*i));
5113    CHECK_EQ(expected, actual);
5114  }
5115}
5116
5117
5118TEST(RunChangeUint32ToUint64P) {
5119  if (kPointerSize < 8) return;
5120  int64_t actual = -1;
5121  RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
5122  m.StoreToPointer(&actual, MachineRepresentation::kWord64,
5123                   m.ChangeUint32ToUint64(m.Parameter(0)));
5124  m.Return(m.Int32Constant(0));
5125  FOR_UINT32_INPUTS(i) {
5126    int64_t expected = static_cast<uint64_t>(*i);
5127    CHECK_EQ(0, m.Call(*i));
5128    CHECK_EQ(expected, actual);
5129  }
5130}
5131
5132
5133TEST(RunTruncateInt64ToInt32P) {
5134  if (kPointerSize < 8) return;
5135  int64_t expected = -1;
5136  RawMachineAssemblerTester<int32_t> m;
5137  m.Return(m.TruncateInt64ToInt32(
5138      m.LoadFromPointer(&expected, MachineType::Int64())));
5139  FOR_UINT32_INPUTS(i) {
5140    FOR_UINT32_INPUTS(j) {
5141      expected = (static_cast<uint64_t>(*j) << 32) | *i;
5142      CHECK_EQ(static_cast<int32_t>(expected), m.Call());
5143    }
5144  }
5145}
5146
5147
5148TEST(RunTruncateFloat64ToInt32P) {
5149  struct {
5150    double from;
5151    double raw;
5152  } kValues[] = {{0, 0},
5153                 {0.5, 0},
5154                 {-0.5, 0},
5155                 {1.5, 1},
5156                 {-1.5, -1},
5157                 {5.5, 5},
5158                 {-5.0, -5},
5159                 {std::numeric_limits<double>::quiet_NaN(), 0},
5160                 {std::numeric_limits<double>::infinity(), 0},
5161                 {-std::numeric_limits<double>::quiet_NaN(), 0},
5162                 {-std::numeric_limits<double>::infinity(), 0},
5163                 {4.94065645841e-324, 0},
5164                 {-4.94065645841e-324, 0},
5165                 {0.9999999999999999, 0},
5166                 {-0.9999999999999999, 0},
5167                 {4294967296.0, 0},
5168                 {-4294967296.0, 0},
5169                 {9223372036854775000.0, 4294966272.0},
5170                 {-9223372036854775000.0, -4294966272.0},
5171                 {4.5036e+15, 372629504},
5172                 {-4.5036e+15, -372629504},
5173                 {287524199.5377777, 0x11234567},
5174                 {-287524199.5377777, -0x11234567},
5175                 {2300193596.302222, 2300193596.0},
5176                 {-2300193596.302222, -2300193596.0},
5177                 {4600387192.604444, 305419896},
5178                 {-4600387192.604444, -305419896},
5179                 {4823855600872397.0, 1737075661},
5180                 {-4823855600872397.0, -1737075661},
5181                 {4503603922337791.0, -1},
5182                 {-4503603922337791.0, 1},
5183                 {4503601774854143.0, 2147483647},
5184                 {-4503601774854143.0, -2147483647},
5185                 {9007207844675582.0, -2},
5186                 {-9007207844675582.0, 2},
5187                 {2.4178527921507624e+24, -536870912},
5188                 {-2.4178527921507624e+24, 536870912},
5189                 {2.417853945072267e+24, -536870912},
5190                 {-2.417853945072267e+24, 536870912},
5191                 {4.8357055843015248e+24, -1073741824},
5192                 {-4.8357055843015248e+24, 1073741824},
5193                 {4.8357078901445341e+24, -1073741824},
5194                 {-4.8357078901445341e+24, 1073741824},
5195                 {2147483647.0, 2147483647.0},
5196                 {-2147483648.0, -2147483648.0},
5197                 {9.6714111686030497e+24, -2147483648.0},
5198                 {-9.6714111686030497e+24, -2147483648.0},
5199                 {9.6714157802890681e+24, -2147483648.0},
5200                 {-9.6714157802890681e+24, -2147483648.0},
5201                 {1.9342813113834065e+25, 2147483648.0},
5202                 {-1.9342813113834065e+25, 2147483648.0},
5203                 {3.868562622766813e+25, 0},
5204                 {-3.868562622766813e+25, 0},
5205                 {1.7976931348623157e+308, 0},
5206                 {-1.7976931348623157e+308, 0}};
5207  double input = -1.0;
5208  RawMachineAssemblerTester<int32_t> m;
5209  m.Return(m.TruncateFloat64ToInt32(
5210      TruncationMode::kJavaScript,
5211      m.LoadFromPointer(&input, MachineType::Float64())));
5212  for (size_t i = 0; i < arraysize(kValues); ++i) {
5213    input = kValues[i].from;
5214    uint64_t expected = static_cast<int64_t>(kValues[i].raw);
5215    CHECK_EQ(static_cast<int>(expected), m.Call());
5216  }
5217}
5218
5219
5220TEST(RunChangeFloat32ToFloat64) {
5221  BufferedRawMachineAssemblerTester<double> m(MachineType::Float32());
5222
5223  m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
5224
5225  FOR_FLOAT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
5226}
5227
5228
5229TEST(RunFloat32Constant) {
5230  FOR_FLOAT32_INPUTS(i) {
5231    BufferedRawMachineAssemblerTester<float> m;
5232    m.Return(m.Float32Constant(*i));
5233    CheckFloatEq(*i, m.Call());
5234  }
5235}
5236
5237
5238TEST(RunFloat64ExtractLowWord32) {
5239  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5240  m.Return(m.Float64ExtractLowWord32(m.Parameter(0)));
5241  FOR_FLOAT64_INPUTS(i) {
5242    uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i));
5243    CHECK_EQ(expected, m.Call(*i));
5244  }
5245}
5246
5247
5248TEST(RunFloat64ExtractHighWord32) {
5249  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5250  m.Return(m.Float64ExtractHighWord32(m.Parameter(0)));
5251  FOR_FLOAT64_INPUTS(i) {
5252    uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32);
5253    CHECK_EQ(expected, m.Call(*i));
5254  }
5255}
5256
5257
5258TEST(RunFloat64InsertLowWord32) {
5259  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5260                                              MachineType::Int32());
5261  m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1)));
5262  FOR_FLOAT64_INPUTS(i) {
5263    FOR_INT32_INPUTS(j) {
5264      double expected = bit_cast<double>(
5265          (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) |
5266          (static_cast<uint64_t>(bit_cast<uint32_t>(*j))));
5267      CheckDoubleEq(expected, m.Call(*i, *j));
5268    }
5269  }
5270}
5271
5272
5273TEST(RunFloat64InsertHighWord32) {
5274  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5275                                              MachineType::Uint32());
5276  m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1)));
5277  FOR_FLOAT64_INPUTS(i) {
5278    FOR_UINT32_INPUTS(j) {
5279      uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) |
5280                          (static_cast<uint64_t>(*j) << 32);
5281
5282      CheckDoubleEq(bit_cast<double>(expected), m.Call(*i, *j));
5283    }
5284  }
5285}
5286
5287
5288TEST(RunFloat32Abs) {
5289  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5290  m.Return(m.Float32Abs(m.Parameter(0)));
5291  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::abs(*i), m.Call(*i)); }
5292}
5293
5294
5295TEST(RunFloat64Abs) {
5296  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5297  m.Return(m.Float64Abs(m.Parameter(0)));
5298  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::abs(*i), m.Call(*i)); }
5299}
5300
5301
5302static double two_30 = 1 << 30;             // 2^30 is a smi boundary.
5303static double two_52 = two_30 * (1 << 22);  // 2^52 is a precision boundary.
5304static double kValues[] = {0.1,
5305                           0.2,
5306                           0.49999999999999994,
5307                           0.5,
5308                           0.7,
5309                           1.0 - std::numeric_limits<double>::epsilon(),
5310                           -0.1,
5311                           -0.49999999999999994,
5312                           -0.5,
5313                           -0.7,
5314                           1.1,
5315                           1.0 + std::numeric_limits<double>::epsilon(),
5316                           1.5,
5317                           1.7,
5318                           -1,
5319                           -1 + std::numeric_limits<double>::epsilon(),
5320                           -1 - std::numeric_limits<double>::epsilon(),
5321                           -1.1,
5322                           -1.5,
5323                           -1.7,
5324                           std::numeric_limits<double>::min(),
5325                           -std::numeric_limits<double>::min(),
5326                           std::numeric_limits<double>::max(),
5327                           -std::numeric_limits<double>::max(),
5328                           std::numeric_limits<double>::infinity(),
5329                           -std::numeric_limits<double>::infinity(),
5330                           two_30,
5331                           two_30 + 0.1,
5332                           two_30 + 0.5,
5333                           two_30 + 0.7,
5334                           two_30 - 1,
5335                           two_30 - 1 + 0.1,
5336                           two_30 - 1 + 0.5,
5337                           two_30 - 1 + 0.7,
5338                           -two_30,
5339                           -two_30 + 0.1,
5340                           -two_30 + 0.5,
5341                           -two_30 + 0.7,
5342                           -two_30 + 1,
5343                           -two_30 + 1 + 0.1,
5344                           -two_30 + 1 + 0.5,
5345                           -two_30 + 1 + 0.7,
5346                           two_52,
5347                           two_52 + 0.1,
5348                           two_52 + 0.5,
5349                           two_52 + 0.5,
5350                           two_52 + 0.7,
5351                           two_52 + 0.7,
5352                           two_52 - 1,
5353                           two_52 - 1 + 0.1,
5354                           two_52 - 1 + 0.5,
5355                           two_52 - 1 + 0.7,
5356                           -two_52,
5357                           -two_52 + 0.1,
5358                           -two_52 + 0.5,
5359                           -two_52 + 0.7,
5360                           -two_52 + 1,
5361                           -two_52 + 1 + 0.1,
5362                           -two_52 + 1 + 0.5,
5363                           -two_52 + 1 + 0.7,
5364                           two_30,
5365                           two_30 - 0.1,
5366                           two_30 - 0.5,
5367                           two_30 - 0.7,
5368                           two_30 - 1,
5369                           two_30 - 1 - 0.1,
5370                           two_30 - 1 - 0.5,
5371                           two_30 - 1 - 0.7,
5372                           -two_30,
5373                           -two_30 - 0.1,
5374                           -two_30 - 0.5,
5375                           -two_30 - 0.7,
5376                           -two_30 + 1,
5377                           -two_30 + 1 - 0.1,
5378                           -two_30 + 1 - 0.5,
5379                           -two_30 + 1 - 0.7,
5380                           two_52,
5381                           two_52 - 0.1,
5382                           two_52 - 0.5,
5383                           two_52 - 0.5,
5384                           two_52 - 0.7,
5385                           two_52 - 0.7,
5386                           two_52 - 1,
5387                           two_52 - 1 - 0.1,
5388                           two_52 - 1 - 0.5,
5389                           two_52 - 1 - 0.7,
5390                           -two_52,
5391                           -two_52 - 0.1,
5392                           -two_52 - 0.5,
5393                           -two_52 - 0.7,
5394                           -two_52 + 1,
5395                           -two_52 + 1 - 0.1,
5396                           -two_52 + 1 - 0.5,
5397                           -two_52 + 1 - 0.7};
5398
5399
5400TEST(RunFloat32RoundDown) {
5401  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5402  if (!m.machine()->Float32RoundDown().IsSupported()) return;
5403
5404  m.Return(m.Float32RoundDown(m.Parameter(0)));
5405
5406  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), m.Call(*i)); }
5407}
5408
5409
5410TEST(RunFloat64RoundDown1) {
5411  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5412  if (!m.machine()->Float64RoundDown().IsSupported()) return;
5413
5414  m.Return(m.Float64RoundDown(m.Parameter(0)));
5415
5416  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), m.Call(*i)); }
5417}
5418
5419
5420TEST(RunFloat64RoundDown2) {
5421  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5422  if (!m.machine()->Float64RoundDown().IsSupported()) return;
5423  m.Return(m.Float64Sub(m.Float64Constant(-0.0),
5424                        m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
5425                                                        m.Parameter(0)))));
5426
5427  for (size_t i = 0; i < arraysize(kValues); ++i) {
5428    CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i]));
5429  }
5430}
5431
5432
5433TEST(RunFloat32RoundUp) {
5434  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5435  if (!m.machine()->Float32RoundUp().IsSupported()) return;
5436  m.Return(m.Float32RoundUp(m.Parameter(0)));
5437
5438  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), m.Call(*i)); }
5439}
5440
5441
5442TEST(RunFloat64RoundUp) {
5443  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5444  if (!m.machine()->Float64RoundUp().IsSupported()) return;
5445  m.Return(m.Float64RoundUp(m.Parameter(0)));
5446
5447  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), m.Call(*i)); }
5448}
5449
5450
5451TEST(RunFloat32RoundTiesEven) {
5452  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5453  if (!m.machine()->Float32RoundTiesEven().IsSupported()) return;
5454  m.Return(m.Float32RoundTiesEven(m.Parameter(0)));
5455
5456  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), m.Call(*i)); }
5457}
5458
5459
5460TEST(RunFloat64RoundTiesEven) {
5461  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5462  if (!m.machine()->Float64RoundTiesEven().IsSupported()) return;
5463  m.Return(m.Float64RoundTiesEven(m.Parameter(0)));
5464
5465  FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), m.Call(*i)); }
5466}
5467
5468
5469TEST(RunFloat32RoundTruncate) {
5470  BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5471  if (!m.machine()->Float32RoundTruncate().IsSupported()) return;
5472
5473  m.Return(m.Float32RoundTruncate(m.Parameter(0)));
5474
5475  FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), m.Call(*i)); }
5476}
5477
5478
5479TEST(RunFloat64RoundTruncate) {
5480  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5481  if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
5482  m.Return(m.Float64RoundTruncate(m.Parameter(0)));
5483  for (size_t i = 0; i < arraysize(kValues); ++i) {
5484    CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
5485  }
5486}
5487
5488
5489TEST(RunFloat64RoundTiesAway) {
5490  BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5491  if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
5492  m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
5493  for (size_t i = 0; i < arraysize(kValues); ++i) {
5494    CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
5495  }
5496}
5497
5498
5499#if !USE_SIMULATOR
5500
5501namespace {
5502
5503int32_t const kMagicFoo0 = 0xdeadbeef;
5504
5505
5506int32_t foo0() { return kMagicFoo0; }
5507
5508
5509int32_t foo1(int32_t x) { return x; }
5510
5511
5512int32_t foo2(int32_t x, int32_t y) { return x - y; }
5513
5514
5515int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
5516             int32_t g, int32_t h) {
5517  return a + b + c + d + e + f + g + h;
5518}
5519
5520}  // namespace
5521
5522
5523TEST(RunCallCFunction0) {
5524  auto* foo0_ptr = &foo0;
5525  RawMachineAssemblerTester<int32_t> m;
5526  Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer());
5527  m.Return(m.CallCFunction0(MachineType::Int32(), function));
5528  CHECK_EQ(kMagicFoo0, m.Call());
5529}
5530
5531
5532TEST(RunCallCFunction1) {
5533  auto* foo1_ptr = &foo1;
5534  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5535  Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer());
5536  m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(),
5537                            function, m.Parameter(0)));
5538  FOR_INT32_INPUTS(i) {
5539    int32_t const expected = *i;
5540    CHECK_EQ(expected, m.Call(expected));
5541  }
5542}
5543
5544
5545TEST(RunCallCFunction2) {
5546  auto* foo2_ptr = &foo2;
5547  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5548                                       MachineType::Int32());
5549  Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer());
5550  m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(),
5551                            MachineType::Int32(), function, m.Parameter(0),
5552                            m.Parameter(1)));
5553  FOR_INT32_INPUTS(i) {
5554    int32_t const x = *i;
5555    FOR_INT32_INPUTS(j) {
5556      int32_t const y = *j;
5557      CHECK_EQ(x - y, m.Call(x, y));
5558    }
5559  }
5560}
5561
5562
5563TEST(RunCallCFunction8) {
5564  auto* foo8_ptr = &foo8;
5565  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5566  Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer());
5567  Node* param = m.Parameter(0);
5568  m.Return(m.CallCFunction8(
5569      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5570      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5571      MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5572      function, param, param, param, param, param, param, param, param));
5573  FOR_INT32_INPUTS(i) {
5574    int32_t const x = *i;
5575    CHECK_EQ(x * 8, m.Call(x));
5576  }
5577}
5578#endif  // USE_SIMULATOR
5579
5580#if V8_TARGET_ARCH_64_BIT
5581// TODO(titzer): run int64 tests on all platforms when supported.
5582TEST(RunCheckedLoadInt64) {
5583  int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL};
5584  RawMachineAssemblerTester<int64_t> m(MachineType::Int32());
5585  Node* base = m.PointerConstant(buffer);
5586  Node* index = m.Parameter(0);
5587  Node* length = m.Int32Constant(16);
5588  Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base,
5589                         index, length);
5590  m.Return(load);
5591
5592  CHECK_EQ(buffer[0], m.Call(0));
5593  CHECK_EQ(buffer[1], m.Call(8));
5594  CHECK_EQ(0, m.Call(16));
5595}
5596
5597
5598TEST(RunCheckedStoreInt64) {
5599  const int64_t write = 0x5566778899aabbLL;
5600  const int64_t before = 0x33bbccddeeff0011LL;
5601  int64_t buffer[] = {before, before};
5602  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5603  Node* base = m.PointerConstant(buffer);
5604  Node* index = m.Parameter(0);
5605  Node* length = m.Int32Constant(16);
5606  Node* value = m.Int64Constant(write);
5607  Node* store =
5608      m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base,
5609                index, length, value);
5610  USE(store);
5611  m.Return(m.Int32Constant(11));
5612
5613  CHECK_EQ(11, m.Call(16));
5614  CHECK_EQ(before, buffer[0]);
5615  CHECK_EQ(before, buffer[1]);
5616
5617  CHECK_EQ(11, m.Call(0));
5618  CHECK_EQ(write, buffer[0]);
5619  CHECK_EQ(before, buffer[1]);
5620
5621  CHECK_EQ(11, m.Call(8));
5622  CHECK_EQ(write, buffer[0]);
5623  CHECK_EQ(write, buffer[1]);
5624}
5625
5626
5627TEST(RunBitcastInt64ToFloat64) {
5628  int64_t input = 1;
5629  double output = 0.0;
5630  RawMachineAssemblerTester<int32_t> m;
5631  m.StoreToPointer(
5632      &output, MachineRepresentation::kFloat64,
5633      m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64())));
5634  m.Return(m.Int32Constant(11));
5635  FOR_INT64_INPUTS(i) {
5636    input = *i;
5637    CHECK_EQ(11, m.Call());
5638    double expected = bit_cast<double>(input);
5639    CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output));
5640  }
5641}
5642
5643
5644TEST(RunBitcastFloat64ToInt64) {
5645  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5646
5647  m.Return(m.BitcastFloat64ToInt64(m.Parameter(0)));
5648  FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); }
5649}
5650
5651
5652TEST(RunTryTruncateFloat32ToInt64WithoutCheck) {
5653  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5654  m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0)));
5655
5656  FOR_INT64_INPUTS(i) {
5657    float input = static_cast<float>(*i);
5658    if (input < static_cast<float>(INT64_MAX) &&
5659        input >= static_cast<float>(INT64_MIN)) {
5660      CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5661    }
5662  }
5663}
5664
5665
5666TEST(RunTryTruncateFloat32ToInt64WithCheck) {
5667  int64_t success = 0;
5668  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5669  Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0));
5670  Node* val = m.Projection(0, trunc);
5671  Node* check = m.Projection(1, trunc);
5672  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5673  m.Return(val);
5674
5675  FOR_FLOAT32_INPUTS(i) {
5676    if (*i < static_cast<float>(INT64_MAX) &&
5677        *i >= static_cast<float>(INT64_MIN)) {
5678      CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5679      CHECK_NE(0, success);
5680    } else {
5681      m.Call(*i);
5682      CHECK_EQ(0, success);
5683    }
5684  }
5685}
5686
5687
5688TEST(RunTryTruncateFloat64ToInt64WithoutCheck) {
5689  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5690  m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0)));
5691
5692  FOR_INT64_INPUTS(i) {
5693    double input = static_cast<double>(*i);
5694    CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5695  }
5696}
5697
5698
5699TEST(RunTryTruncateFloat64ToInt64WithCheck) {
5700  int64_t success = 0;
5701  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5702  Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0));
5703  Node* val = m.Projection(0, trunc);
5704  Node* check = m.Projection(1, trunc);
5705  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5706  m.Return(val);
5707
5708  FOR_FLOAT64_INPUTS(i) {
5709    if (*i < static_cast<double>(INT64_MAX) &&
5710        *i >= static_cast<double>(INT64_MIN)) {
5711      // Conversions within this range should succeed.
5712      CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5713      CHECK_NE(0, success);
5714    } else {
5715      m.Call(*i);
5716      CHECK_EQ(0, success);
5717    }
5718  }
5719}
5720
5721
5722TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
5723  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5724  m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
5725
5726  FOR_UINT64_INPUTS(i) {
5727    float input = static_cast<float>(*i);
5728    // This condition on 'input' is required because
5729    // static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
5730    if (input < static_cast<float>(UINT64_MAX)) {
5731      CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5732    }
5733  }
5734}
5735
5736
5737TEST(RunTryTruncateFloat32ToUint64WithCheck) {
5738  int64_t success = 0;
5739  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5740  Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0));
5741  Node* val = m.Projection(0, trunc);
5742  Node* check = m.Projection(1, trunc);
5743  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5744  m.Return(val);
5745
5746  FOR_FLOAT32_INPUTS(i) {
5747    if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
5748      // Conversions within this range should succeed.
5749      CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5750      CHECK_NE(0, success);
5751    } else {
5752      m.Call(*i);
5753      CHECK_EQ(0, success);
5754    }
5755  }
5756}
5757
5758
5759TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
5760  BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64());
5761  m.Return(m.TruncateFloat64ToUint64(m.Parameter(0)));
5762
5763  FOR_UINT64_INPUTS(j) {
5764    double input = static_cast<double>(*j);
5765
5766    if (input < static_cast<float>(UINT64_MAX)) {
5767      CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5768    }
5769  }
5770}
5771
5772
5773TEST(RunTryTruncateFloat64ToUint64WithCheck) {
5774  int64_t success = 0;
5775  BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5776  Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0));
5777  Node* val = m.Projection(0, trunc);
5778  Node* check = m.Projection(1, trunc);
5779  m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5780  m.Return(val);
5781
5782  FOR_FLOAT64_INPUTS(i) {
5783    if (*i < 18446744073709551616.0 && *i > -1) {
5784      // Conversions within this range should succeed.
5785      CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5786      CHECK_NE(0, success);
5787    } else {
5788      m.Call(*i);
5789      CHECK_EQ(0, success);
5790    }
5791  }
5792}
5793
5794
5795TEST(RunRoundInt64ToFloat32) {
5796  BufferedRawMachineAssemblerTester<float> m(MachineType::Int64());
5797  m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
5798  FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
5799}
5800
5801
5802TEST(RunRoundInt64ToFloat64) {
5803  BufferedRawMachineAssemblerTester<double> m(MachineType::Int64());
5804  m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
5805  FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); }
5806}
5807
5808
5809TEST(RunRoundUint64ToFloat64) {
5810  struct {
5811    uint64_t input;
5812    uint64_t expected;
5813  } values[] = {{0x0, 0x0},
5814                {0x1, 0x3ff0000000000000},
5815                {0xffffffff, 0x41efffffffe00000},
5816                {0x1b09788b, 0x41bb09788b000000},
5817                {0x4c5fce8, 0x419317f3a0000000},
5818                {0xcc0de5bf, 0x41e981bcb7e00000},
5819                {0x2, 0x4000000000000000},
5820                {0x3, 0x4008000000000000},
5821                {0x4, 0x4010000000000000},
5822                {0x5, 0x4014000000000000},
5823                {0x8, 0x4020000000000000},
5824                {0x9, 0x4022000000000000},
5825                {0xffffffffffffffff, 0x43f0000000000000},
5826                {0xfffffffffffffffe, 0x43f0000000000000},
5827                {0xfffffffffffffffd, 0x43f0000000000000},
5828                {0x100000000, 0x41f0000000000000},
5829                {0xffffffff00000000, 0x43efffffffe00000},
5830                {0x1b09788b00000000, 0x43bb09788b000000},
5831                {0x4c5fce800000000, 0x439317f3a0000000},
5832                {0xcc0de5bf00000000, 0x43e981bcb7e00000},
5833                {0x200000000, 0x4200000000000000},
5834                {0x300000000, 0x4208000000000000},
5835                {0x400000000, 0x4210000000000000},
5836                {0x500000000, 0x4214000000000000},
5837                {0x800000000, 0x4220000000000000},
5838                {0x900000000, 0x4222000000000000},
5839                {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
5840                {0xece3af835495a16b, 0x43ed9c75f06a92b4},
5841                {0xb668ecc11223344, 0x43a6cd1d98224467},
5842                {0x9e, 0x4063c00000000000},
5843                {0x43, 0x4050c00000000000},
5844                {0xaf73, 0x40e5ee6000000000},
5845                {0x116b, 0x40b16b0000000000},
5846                {0x658ecc, 0x415963b300000000},
5847                {0x2b3b4c, 0x41459da600000000},
5848                {0x88776655, 0x41e10eeccaa00000},
5849                {0x70000000, 0x41dc000000000000},
5850                {0x7200000, 0x419c800000000000},
5851                {0x7fffffff, 0x41dfffffffc00000},
5852                {0x56123761, 0x41d5848dd8400000},
5853                {0x7fffff00, 0x41dfffffc0000000},
5854                {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
5855                {0x80000000eeeeeeee, 0x43e00000001dddde},
5856                {0x88888888dddddddd, 0x43e11111111bbbbc},
5857                {0xa0000000dddddddd, 0x43e40000001bbbbc},
5858                {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
5859                {0xe0000000aaaaaaaa, 0x43ec000000155555},
5860                {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
5861                {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
5862                {0xf0000000dddddddd, 0x43ee0000001bbbbc},
5863                {0x7fffffdddddddd, 0x435ffffff7777777},
5864                {0x3fffffaaaaaaaa, 0x434fffffd5555555},
5865                {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
5866                {0xfffff, 0x412ffffe00000000},
5867                {0x7ffff, 0x411ffffc00000000},
5868                {0x3ffff, 0x410ffff800000000},
5869                {0x1ffff, 0x40fffff000000000},
5870                {0xffff, 0x40efffe000000000},
5871                {0x7fff, 0x40dfffc000000000},
5872                {0x3fff, 0x40cfff8000000000},
5873                {0x1fff, 0x40bfff0000000000},
5874                {0xfff, 0x40affe0000000000},
5875                {0x7ff, 0x409ffc0000000000},
5876                {0x3ff, 0x408ff80000000000},
5877                {0x1ff, 0x407ff00000000000},
5878                {0x3fffffffffff, 0x42cfffffffffff80},
5879                {0x1fffffffffff, 0x42bfffffffffff00},
5880                {0xfffffffffff, 0x42affffffffffe00},
5881                {0x7ffffffffff, 0x429ffffffffffc00},
5882                {0x3ffffffffff, 0x428ffffffffff800},
5883                {0x1ffffffffff, 0x427ffffffffff000},
5884                {0x8000008000000000, 0x43e0000010000000},
5885                {0x8000008000000001, 0x43e0000010000000},
5886                {0x8000000000000400, 0x43e0000000000000},
5887                {0x8000000000000401, 0x43e0000000000001}};
5888
5889  BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64());
5890  m.Return(m.RoundUint64ToFloat64(m.Parameter(0)));
5891
5892  for (size_t i = 0; i < arraysize(values); i++) {
5893    CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input));
5894  }
5895}
5896
5897
5898TEST(RunRoundUint64ToFloat32) {
5899  struct {
5900    uint64_t input;
5901    uint32_t expected;
5902  } values[] = {{0x0, 0x0},
5903                {0x1, 0x3f800000},
5904                {0xffffffff, 0x4f800000},
5905                {0x1b09788b, 0x4dd84bc4},
5906                {0x4c5fce8, 0x4c98bf9d},
5907                {0xcc0de5bf, 0x4f4c0de6},
5908                {0x2, 0x40000000},
5909                {0x3, 0x40400000},
5910                {0x4, 0x40800000},
5911                {0x5, 0x40a00000},
5912                {0x8, 0x41000000},
5913                {0x9, 0x41100000},
5914                {0xffffffffffffffff, 0x5f800000},
5915                {0xfffffffffffffffe, 0x5f800000},
5916                {0xfffffffffffffffd, 0x5f800000},
5917                {0x0, 0x0},
5918                {0x100000000, 0x4f800000},
5919                {0xffffffff00000000, 0x5f800000},
5920                {0x1b09788b00000000, 0x5dd84bc4},
5921                {0x4c5fce800000000, 0x5c98bf9d},
5922                {0xcc0de5bf00000000, 0x5f4c0de6},
5923                {0x200000000, 0x50000000},
5924                {0x300000000, 0x50400000},
5925                {0x400000000, 0x50800000},
5926                {0x500000000, 0x50a00000},
5927                {0x800000000, 0x51000000},
5928                {0x900000000, 0x51100000},
5929                {0x273a798e187937a3, 0x5e1ce9e6},
5930                {0xece3af835495a16b, 0x5f6ce3b0},
5931                {0xb668ecc11223344, 0x5d3668ed},
5932                {0x9e, 0x431e0000},
5933                {0x43, 0x42860000},
5934                {0xaf73, 0x472f7300},
5935                {0x116b, 0x458b5800},
5936                {0x658ecc, 0x4acb1d98},
5937                {0x2b3b4c, 0x4a2ced30},
5938                {0x88776655, 0x4f087766},
5939                {0x70000000, 0x4ee00000},
5940                {0x7200000, 0x4ce40000},
5941                {0x7fffffff, 0x4f000000},
5942                {0x56123761, 0x4eac246f},
5943                {0x7fffff00, 0x4efffffe},
5944                {0x761c4761eeeeeeee, 0x5eec388f},
5945                {0x80000000eeeeeeee, 0x5f000000},
5946                {0x88888888dddddddd, 0x5f088889},
5947                {0xa0000000dddddddd, 0x5f200000},
5948                {0xddddddddaaaaaaaa, 0x5f5dddde},
5949                {0xe0000000aaaaaaaa, 0x5f600000},
5950                {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
5951                {0xfffffffdeeeeeeee, 0x5f800000},
5952                {0xf0000000dddddddd, 0x5f700000},
5953                {0x7fffffdddddddd, 0x5b000000},
5954                {0x3fffffaaaaaaaa, 0x5a7fffff},
5955                {0x1fffffaaaaaaaa, 0x59fffffd},
5956                {0xfffff, 0x497ffff0},
5957                {0x7ffff, 0x48ffffe0},
5958                {0x3ffff, 0x487fffc0},
5959                {0x1ffff, 0x47ffff80},
5960                {0xffff, 0x477fff00},
5961                {0x7fff, 0x46fffe00},
5962                {0x3fff, 0x467ffc00},
5963                {0x1fff, 0x45fff800},
5964                {0xfff, 0x457ff000},
5965                {0x7ff, 0x44ffe000},
5966                {0x3ff, 0x447fc000},
5967                {0x1ff, 0x43ff8000},
5968                {0x3fffffffffff, 0x56800000},
5969                {0x1fffffffffff, 0x56000000},
5970                {0xfffffffffff, 0x55800000},
5971                {0x7ffffffffff, 0x55000000},
5972                {0x3ffffffffff, 0x54800000},
5973                {0x1ffffffffff, 0x54000000},
5974                {0x8000008000000000, 0x5f000000},
5975                {0x8000008000000001, 0x5f000001},
5976                {0x8000000000000400, 0x5f000000},
5977                {0x8000000000000401, 0x5f000000}};
5978
5979  BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64());
5980  m.Return(m.RoundUint64ToFloat32(m.Parameter(0)));
5981
5982  for (size_t i = 0; i < arraysize(values); i++) {
5983    CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input));
5984  }
5985}
5986
5987
5988#endif
5989
5990
5991TEST(RunBitcastFloat32ToInt32) {
5992  float input = 32.25;
5993  RawMachineAssemblerTester<int32_t> m;
5994  m.Return(m.BitcastFloat32ToInt32(
5995      m.LoadFromPointer(&input, MachineType::Float32())));
5996  FOR_FLOAT32_INPUTS(i) {
5997    input = *i;
5998    int32_t expected = bit_cast<int32_t>(input);
5999    CHECK_EQ(expected, m.Call());
6000  }
6001}
6002
6003
6004TEST(RunBitcastInt32ToFloat32) {
6005  int32_t input = 1;
6006  float output = 0.0;
6007  RawMachineAssemblerTester<int32_t> m;
6008  m.StoreToPointer(
6009      &output, MachineRepresentation::kFloat32,
6010      m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32())));
6011  m.Return(m.Int32Constant(11));
6012  FOR_INT32_INPUTS(i) {
6013    input = *i;
6014    CHECK_EQ(11, m.Call());
6015    float expected = bit_cast<float>(input);
6016    CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output));
6017  }
6018}
6019
6020
6021TEST(RunComputedCodeObject) {
6022  GraphBuilderTester<int32_t> a;
6023  a.Return(a.Int32Constant(33));
6024  a.End();
6025  Handle<Code> code_a = a.GetCode();
6026
6027  GraphBuilderTester<int32_t> b;
6028  b.Return(b.Int32Constant(44));
6029  b.End();
6030  Handle<Code> code_b = b.GetCode();
6031
6032  RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6033  RawMachineLabel tlabel;
6034  RawMachineLabel flabel;
6035  RawMachineLabel merge;
6036  r.Branch(r.Parameter(0), &tlabel, &flabel);
6037  r.Bind(&tlabel);
6038  Node* fa = r.HeapConstant(code_a);
6039  r.Goto(&merge);
6040  r.Bind(&flabel);
6041  Node* fb = r.HeapConstant(code_b);
6042  r.Goto(&merge);
6043  r.Bind(&merge);
6044  Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6045
6046  // TODO(titzer): all this descriptor hackery is just to call the above
6047  // functions as code objects instead of direct addresses.
6048  CSignature0<int32_t> sig;
6049  CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig);
6050  LinkageLocation ret[] = {c->GetReturnLocation(0)};
6051  Signature<LinkageLocation> loc(1, 0, ret);
6052  CallDescriptor* desc = new (r.zone()) CallDescriptor(  // --
6053      CallDescriptor::kCallCodeObject,                   // kind
6054      MachineType::AnyTagged(),                          // target_type
6055      c->GetInputLocation(0),                            // target_loc
6056      &sig,                                              // machine_sig
6057      &loc,                                              // location_sig
6058      0,                                                 // stack count
6059      Operator::kNoProperties,                           // properties
6060      c->CalleeSavedRegisters(),                         // callee saved
6061      c->CalleeSavedFPRegisters(),                       // callee saved FP
6062      CallDescriptor::kNoFlags,                          // flags
6063      "c-call-as-code");
6064  Node* call = r.AddNode(r.common()->Call(desc), phi);
6065  r.Return(call);
6066
6067  CHECK_EQ(33, r.Call(1));
6068  CHECK_EQ(44, r.Call(0));
6069}
6070
6071}  // namespace compiler
6072}  // namespace internal
6073}  // namespace v8
6074