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