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