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 
17 using namespace v8::base;
18 
19 namespace v8 {
20 namespace internal {
21 namespace compiler {
22 
23 
TEST(RunInt32Add)24 TEST(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 
TEST(RunWord32Ctz)32 TEST(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 
TEST(RunWord32Clz)76 TEST(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 
TEST(RunWord32Popcnt)116 TEST(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
TEST(RunWord64Clz)136 TEST(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 
TEST(RunWord64Ctz)208 TEST(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 
TEST(RunWord64Popcnt)284 TEST(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 
Int32Input(RawMachineAssemblerTester<int32_t> * m,int index)304 static 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 
TEST(CodeGenInt32Binop)328 TEST(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 
TEST(CodeGenNop)358 TEST(CodeGenNop) {
359   RawMachineAssemblerTester<void> m;
360   m.Return(m.Int32Constant(0));
361   m.GenerateCode();
362 }
363 
364 
365 #if V8_TARGET_ARCH_64_BIT
Int64Input(RawMachineAssemblerTester<int64_t> * m,int index)366 static 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 
TEST(CodeGenInt64Binop)390 TEST(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 
TEST(RunInt64AddWithOverflowP)419 TEST(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 
TEST(RunInt64AddWithOverflowImm)439 TEST(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 
TEST(RunInt64AddWithOverflowInBranchP)484 TEST(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 
TEST(RunInt64SubWithOverflowP)511 TEST(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 
TEST(RunInt64SubWithOverflowImm)531 TEST(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 
TEST(RunInt64SubWithOverflowInBranchP)576 TEST(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 
TEST(RunGoto)607 TEST(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 
TEST(RunGotoMultiple)620 TEST(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 
TEST(RunBranch)635 TEST(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 
TEST(RunDiamond2)650 TEST(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 
TEST(RunLoop)668 TEST(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 
685 template <typename R>
BuildDiamondPhi(RawMachineAssemblerTester<R> * m,Node * cond_node,MachineRepresentation rep,Node * true_node,Node * false_node)686 static 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 
TEST(RunDiamondPhiConst)702 TEST(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 
TEST(RunDiamondPhiNumber)715 TEST(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 
TEST(RunDiamondPhiString)728 TEST(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 
TEST(RunDiamondPhiParam)741 TEST(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 
TEST(RunLoopPhiConst)755 TEST(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 
TEST(RunLoopPhiParam)780 TEST(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 
TEST(RunLoopPhiInduction)810 TEST(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 
TEST(RunLoopIncrement)837 TEST(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 
TEST(RunLoopIncrement2)864 TEST(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 
TEST(RunLoopIncrement3)892 TEST(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 
TEST(RunLoopDecrement)920 TEST(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 
TEST(RunLoopIncrementFloat32)947 TEST(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 
TEST(RunLoopIncrementFloat64)972 TEST(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 
TEST(RunSwitch1)997 TEST(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 
TEST(RunSwitch2)1020 TEST(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 
TEST(RunSwitch3)1044 TEST(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 
TEST(RunSwitch4)1068 TEST(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 
TEST(RunLoadInt32)1108 TEST(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 
TEST(RunLoadInt32Offset)1121 TEST(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 
TEST(RunLoadStoreFloat32Offset)1142 TEST(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 
TEST(RunLoadStoreFloat64Offset)1169 TEST(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 
TEST(RunInt32AddP)1196 TEST(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 
TEST(RunInt32AddAndWord32EqualP)1212 TEST(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 
TEST(RunInt32AddAndWord32EqualImm)1248 TEST(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 
TEST(RunInt32AddAndWord32NotEqualP)1284 TEST(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 
TEST(RunInt32AddAndWord32NotEqualImm)1320 TEST(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 
TEST(RunInt32AddAndWord32SarP)1356 TEST(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 
TEST(RunInt32AddAndWord32ShlP)1390 TEST(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 
TEST(RunInt32AddAndWord32ShrP)1424 TEST(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 
TEST(RunInt32AddInBranch)1458 TEST(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 
TEST(RunInt32AddInComparison)1575 TEST(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 
TEST(RunInt32SubP)1661 TEST(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 
TEST(RunInt32SubImm)1676 TEST(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 
TEST(RunInt32SubAndWord32SarP)1700 TEST(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 
TEST(RunInt32SubAndWord32ShlP)1732 TEST(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 
TEST(RunInt32SubAndWord32ShrP)1765 TEST(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 
TEST(RunInt32SubInBranch)1799 TEST(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 
TEST(RunInt32SubInComparison)1916 TEST(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 
TEST(RunInt32MulP)2002 TEST(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 
TEST(RunInt32MulHighP)2028 TEST(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 
TEST(RunInt32MulImm)2042 TEST(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 
TEST(RunInt32MulAndInt32AddP)2066 TEST(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 
TEST(RunInt32MulAndInt32SubP)2136 TEST(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 
TEST(RunUint32MulHighP)2175 TEST(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 
TEST(RunInt32DivP)2189 TEST(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 
TEST(RunUint32DivP)2223 TEST(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 
TEST(RunInt32ModP)2257 TEST(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 
TEST(RunUint32ModP)2291 TEST(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 
TEST(RunWord32AndP)2325 TEST(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 
TEST(RunWord32AndAndWord32ShlP)2362 TEST(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 
TEST(RunWord32AndAndWord32ShrP)2390 TEST(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 
TEST(RunWord32AndAndWord32SarP)2418 TEST(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 
TEST(RunWord32AndImm)2446 TEST(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 
TEST(RunWord32AndInBranch)2470 TEST(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 
TEST(RunWord32AndInComparison)2588 TEST(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 
TEST(RunWord32OrP)2638 TEST(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 
TEST(RunWord32OrImm)2675 TEST(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 
TEST(RunWord32OrInBranch)2699 TEST(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 
TEST(RunWord32OrInComparison)2816 TEST(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 
TEST(RunWord32XorP)2866 TEST(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 
TEST(RunWord32XorInBranch)2923 TEST(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 
TEST(RunWord32ShlP)3041 TEST(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 
TEST(RunWord32ShlInComparison)3066 TEST(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 
TEST(RunWord32ShrP)3118 TEST(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 
TEST(RunWord32ShrInComparison)3144 TEST(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 
TEST(RunWord32SarP)3196 TEST(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 
TEST(RunWord32SarInComparison)3222 TEST(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 
TEST(RunWord32RorP)3274 TEST(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 
TEST(RunWord32RorInComparison)3299 TEST(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 
TEST(RunWord32NotP)3351 TEST(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 
TEST(RunInt32NegP)3361 TEST(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 
TEST(RunWord32EqualAndWord32SarP)3371 TEST(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 
TEST(RunWord32EqualAndWord32ShlP)3403 TEST(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 
TEST(RunWord32EqualAndWord32ShrP)3435 TEST(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 
TEST(RunDeadNodes)3467 TEST(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 
TEST(RunDeadInt32Binops)3504 TEST(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 
3532 template <typename Type>
RunLoadImmIndex(MachineType rep)3533 static 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 
TEST(RunLoadImmIndex)3559 TEST(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 
3574 template <typename CType>
RunLoadStore(MachineType rep)3575 static 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 
TEST(RunLoadStore)3603 TEST(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 
TEST(RunFloat32Add)3616 TEST(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 
TEST(RunFloat32Sub)3630 TEST(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 
TEST(RunFloat32Mul)3644 TEST(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 
TEST(RunFloat32Div)3658 TEST(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 
TEST(RunFloat64Add)3672 TEST(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 
TEST(RunFloat64Sub)3686 TEST(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 
TEST(RunFloat64Mul)3700 TEST(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 
TEST(RunFloat64Div)3714 TEST(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 
TEST(RunFloat64Mod)3728 TEST(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 
TEST(RunDeadFloat32Binops)3739 TEST(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 
TEST(RunDeadFloat64Binops)3756 TEST(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 
TEST(RunFloat32AddP)3773 TEST(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 
TEST(RunFloat64AddP)3788 TEST(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 
TEST(RunFloa32MaxP)3803 TEST(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 
TEST(RunFloat64MaxP)3819 TEST(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 
TEST(RunFloat32MinP)3835 TEST(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 
TEST(RunFloat64MinP)3851 TEST(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 
TEST(RunFloat32SubP)3867 TEST(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 
TEST(RunFloat32SubImm1)3882 TEST(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 
TEST(RunFloat32SubImm2)3895 TEST(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 
TEST(RunFloat64SubImm1)3908 TEST(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 
TEST(RunFloat64SubImm2)3918 TEST(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 
TEST(RunFloat64SubP)3928 TEST(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 
TEST(RunFloat32MulP)3943 TEST(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 
TEST(RunFloat64MulP)3958 TEST(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 
TEST(RunFloat64MulAndFloat64Add1)3973 TEST(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 
TEST(RunFloat64MulAndFloat64Add2)3989 TEST(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 
TEST(RunFloat64MulAndFloat64Sub1)4005 TEST(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 
TEST(RunFloat64MulAndFloat64Sub2)4021 TEST(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 
TEST(RunFloat64MulImm1)4037 TEST(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 
TEST(RunFloat64MulImm2)4047 TEST(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 
TEST(RunFloat32DivP)4057 TEST(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 
TEST(RunFloat64DivP)4072 TEST(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 
TEST(RunFloat64ModP)4087 TEST(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 
TEST(RunChangeInt32ToFloat64_A)4103 TEST(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 
TEST(RunChangeInt32ToFloat64_B)4111 TEST(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 
TEST(RunChangeUint32ToFloat64)4119 TEST(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 
TEST(RunChangeFloat64ToInt32_A)4127 TEST(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 
TEST(RunChangeFloat64ToInt32_B)4135 TEST(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 
TEST(RunChangeFloat64ToUint32)4153 TEST(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 
TEST(RunTruncateFloat64ToFloat32)4172 TEST(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 
TEST(RunDeadChangeFloat64ToInt32)4181 TEST(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 
TEST(RunDeadChangeInt32ToFloat64)4190 TEST(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 
TEST(RunLoopPhiInduction2)4199 TEST(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 
TEST(RunFloatDiamond)4222 TEST(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 
TEST(RunDoubleDiamond)4248 TEST(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 
TEST(RunRefDiamond)4274 TEST(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 
TEST(RunDoubleRefDiamond)4301 TEST(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 
TEST(RunDoubleRefDoubleDiamond)4336 TEST(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 
TEST(RunDoubleLoopPhi)4381 TEST(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 
TEST(RunCountToTenAccRaw)4408 TEST(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 
TEST(RunCountToTenAccRaw2)4441 TEST(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 
TEST(RunAddTree)4477 TEST(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 
4515 static const int kFloat64CompareHelperTestCases = 15;
4516 static const int kFloat64CompareHelperNodeType = 4;
4517 
Float64CompareHelper(RawMachineAssemblerTester<int32_t> * m,int test_case,int node_type,double x,double y)4518 static 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 
TEST(RunFloat64Compare)4612 TEST(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 
TEST(RunFloat64UnorderedCompare)4632 TEST(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 
TEST(RunFloat64Equal)4656 TEST(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 
TEST(RunFloat64LessThan)4677 TEST(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 
4698 template <typename IntType>
LoadStoreTruncation(MachineType kRepresentation)4699 static 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 
TEST(RunLoadStoreTruncation)4731 TEST(RunLoadStoreTruncation) {
4732   LoadStoreTruncation<int8_t>(MachineType::Int8());
4733   LoadStoreTruncation<int16_t>(MachineType::Int16());
4734 }
4735 
4736 
IntPtrCompare(intptr_t left,intptr_t right)4737 static 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 
TEST(RunIntPtrCompare)4785 TEST(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 
TEST(RunTestIntPtrArithmetic)4796 TEST(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 
TEST(RunSpillLotsOfThings)4823 TEST(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 
TEST(RunSpillConstantsAndParameters)4845 TEST(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 
TEST(RunNewSpaceConstantsInPhi)4882 TEST(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 
TEST(RunInt32AddWithOverflowP)4907 TEST(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 
TEST(RunInt32AddWithOverflowImm)4927 TEST(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 
TEST(RunInt32AddWithOverflowInBranchP)4972 TEST(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 
TEST(RunInt32SubWithOverflowP)4995 TEST(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 
TEST(RunInt32SubWithOverflowImm)5015 TEST(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 
TEST(RunInt32SubWithOverflowInBranchP)5060 TEST(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 
TEST(RunWord64EqualInBranchP)5083 TEST(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 
TEST(RunChangeInt32ToInt64P)5103 TEST(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 
TEST(RunChangeUint32ToUint64P)5118 TEST(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 
TEST(RunTruncateInt64ToInt32P)5133 TEST(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 
TEST(RunTruncateFloat64ToInt32P)5148 TEST(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 
TEST(RunChangeFloat32ToFloat64)5220 TEST(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 
TEST(RunFloat32Constant)5229 TEST(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 
TEST(RunFloat64ExtractLowWord32)5238 TEST(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 
TEST(RunFloat64ExtractHighWord32)5248 TEST(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 
TEST(RunFloat64InsertLowWord32)5258 TEST(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 
TEST(RunFloat64InsertHighWord32)5273 TEST(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 
TEST(RunFloat32Abs)5288 TEST(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 
TEST(RunFloat64Abs)5295 TEST(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 
5302 static double two_30 = 1 << 30;             // 2^30 is a smi boundary.
5303 static double two_52 = two_30 * (1 << 22);  // 2^52 is a precision boundary.
5304 static 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 
TEST(RunFloat32RoundDown)5400 TEST(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 
TEST(RunFloat64RoundDown1)5410 TEST(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 
TEST(RunFloat64RoundDown2)5420 TEST(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 
TEST(RunFloat32RoundUp)5433 TEST(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 
TEST(RunFloat64RoundUp)5442 TEST(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 
TEST(RunFloat32RoundTiesEven)5451 TEST(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 
TEST(RunFloat64RoundTiesEven)5460 TEST(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 
TEST(RunFloat32RoundTruncate)5469 TEST(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 
TEST(RunFloat64RoundTruncate)5479 TEST(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 
TEST(RunFloat64RoundTiesAway)5489 TEST(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 
5501 namespace {
5502 
5503 int32_t const kMagicFoo0 = 0xdeadbeef;
5504 
5505 
foo0()5506 int32_t foo0() { return kMagicFoo0; }
5507 
5508 
foo1(int32_t x)5509 int32_t foo1(int32_t x) { return x; }
5510 
5511 
foo2(int32_t x,int32_t y)5512 int32_t foo2(int32_t x, int32_t y) { return x - y; }
5513 
5514 
foo8(int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f,int32_t g,int32_t h)5515 int32_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 
TEST(RunCallCFunction0)5523 TEST(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 
TEST(RunCallCFunction1)5532 TEST(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 
TEST(RunCallCFunction2)5545 TEST(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 
TEST(RunCallCFunction8)5563 TEST(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.
TEST(RunCheckedLoadInt64)5582 TEST(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 
TEST(RunCheckedStoreInt64)5598 TEST(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 
TEST(RunBitcastInt64ToFloat64)5627 TEST(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 
TEST(RunBitcastFloat64ToInt64)5644 TEST(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 
TEST(RunTryTruncateFloat32ToInt64WithoutCheck)5652 TEST(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 
TEST(RunTryTruncateFloat32ToInt64WithCheck)5666 TEST(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 
TEST(RunTryTruncateFloat64ToInt64WithoutCheck)5688 TEST(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 
TEST(RunTryTruncateFloat64ToInt64WithCheck)5699 TEST(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 
TEST(RunTryTruncateFloat32ToUint64WithoutCheck)5722 TEST(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 
TEST(RunTryTruncateFloat32ToUint64WithCheck)5737 TEST(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 
TEST(RunTryTruncateFloat64ToUint64WithoutCheck)5759 TEST(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 
TEST(RunTryTruncateFloat64ToUint64WithCheck)5773 TEST(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 
TEST(RunRoundInt64ToFloat32)5795 TEST(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 
TEST(RunRoundInt64ToFloat64)5802 TEST(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 
TEST(RunRoundUint64ToFloat64)5809 TEST(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 
TEST(RunRoundUint64ToFloat32)5898 TEST(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 
TEST(RunBitcastFloat32ToInt32)5991 TEST(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 
TEST(RunBitcastInt32ToFloat32)6004 TEST(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 
TEST(RunComputedCodeObject)6021 TEST(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