blob: 6d681bca85f04272fbd0758ff1d7b9c980fdd8c7 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include <cmath>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006#include <functional>
7#include <limits>
8
9#include "src/base/bits.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/base/utils/random-number-generator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040011#include "src/codegen.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "test/cctest/cctest.h"
13#include "test/cctest/compiler/codegen-tester.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "test/cctest/compiler/graph-builder-tester.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#include "test/cctest/compiler/value-helper.h"
16
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017using namespace v8::base;
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019namespace v8 {
20namespace internal {
21namespace compiler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023
24TEST(RunInt32Add) {
25 RawMachineAssemblerTester<int32_t> m;
26 Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1));
27 m.Return(add);
28 CHECK_EQ(1, m.Call());
29}
30
Ben Murdochc5610432016-08-08 18:44:38 +010031static int RunInt32AddShift(bool is_left, int32_t add_left, int32_t add_right,
32 int32_t shift_left, int32_t shit_right) {
33 RawMachineAssemblerTester<int32_t> m;
34 Node* shift =
35 m.Word32Shl(m.Int32Constant(shift_left), m.Int32Constant(shit_right));
36 Node* add = m.Int32Add(m.Int32Constant(add_left), m.Int32Constant(add_right));
37 Node* lsa = is_left ? m.Int32Add(shift, add) : m.Int32Add(add, shift);
38 m.Return(lsa);
39 return m.Call();
40}
41
42TEST(RunInt32AddShift) {
43 struct Test_case {
44 int32_t add_left, add_right, shift_left, shit_right, expected;
45 };
46
47 Test_case tc[] = {
48 {20, 22, 4, 2, 58},
49 {20, 22, 4, 1, 50},
50 {20, 22, 1, 6, 106},
51 {INT_MAX - 2, 1, 1, 1, INT_MIN}, // INT_MAX - 2 + 1 + (1 << 1), overflow.
52 };
53 const size_t tc_size = sizeof(tc) / sizeof(Test_case);
54
55 for (size_t i = 0; i < tc_size; ++i) {
56 CHECK_EQ(tc[i].expected,
57 RunInt32AddShift(false, tc[i].add_left, tc[i].add_right,
58 tc[i].shift_left, tc[i].shit_right));
59 CHECK_EQ(tc[i].expected,
60 RunInt32AddShift(true, tc[i].add_left, tc[i].add_right,
61 tc[i].shift_left, tc[i].shit_right));
62 }
63}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064
Ben Murdoch097c5b22016-05-18 11:27:45 +010065TEST(RunWord32ReverseBits) {
66 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
67 if (!m.machine()->Word32ReverseBits().IsSupported()) {
68 // We can only test the operator if it exists on the testing platform.
69 return;
70 }
71 m.Return(m.AddNode(m.machine()->Word32ReverseBits().op(), m.Parameter(0)));
72
73 CHECK_EQ(uint32_t(0x00000000), m.Call(uint32_t(0x00000000)));
74 CHECK_EQ(uint32_t(0x12345678), m.Call(uint32_t(0x1e6a2c48)));
75 CHECK_EQ(uint32_t(0xfedcba09), m.Call(uint32_t(0x905d3b7f)));
76 CHECK_EQ(uint32_t(0x01010101), m.Call(uint32_t(0x80808080)));
77 CHECK_EQ(uint32_t(0x01020408), m.Call(uint32_t(0x10204080)));
78 CHECK_EQ(uint32_t(0xf0703010), m.Call(uint32_t(0x080c0e0f)));
79 CHECK_EQ(uint32_t(0x1f8d0a3a), m.Call(uint32_t(0x5c50b1f8)));
80 CHECK_EQ(uint32_t(0xffffffff), m.Call(uint32_t(0xffffffff)));
81}
82
83
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084TEST(RunWord32Ctz) {
85 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
86 if (!m.machine()->Word32Ctz().IsSupported()) {
87 // We can only test the operator if it exists on the testing platform.
88 return;
89 }
90 m.Return(m.AddNode(m.machine()->Word32Ctz().op(), m.Parameter(0)));
91
92 CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
93 CHECK_EQ(31, m.Call(uint32_t(0x80000000)));
94 CHECK_EQ(30, m.Call(uint32_t(0x40000000)));
95 CHECK_EQ(29, m.Call(uint32_t(0x20000000)));
96 CHECK_EQ(28, m.Call(uint32_t(0x10000000)));
97 CHECK_EQ(27, m.Call(uint32_t(0xa8000000)));
98 CHECK_EQ(26, m.Call(uint32_t(0xf4000000)));
99 CHECK_EQ(25, m.Call(uint32_t(0x62000000)));
100 CHECK_EQ(24, m.Call(uint32_t(0x91000000)));
101 CHECK_EQ(23, m.Call(uint32_t(0xcd800000)));
102 CHECK_EQ(22, m.Call(uint32_t(0x09400000)));
103 CHECK_EQ(21, m.Call(uint32_t(0xaf200000)));
104 CHECK_EQ(20, m.Call(uint32_t(0xac100000)));
105 CHECK_EQ(19, m.Call(uint32_t(0xe0b80000)));
106 CHECK_EQ(18, m.Call(uint32_t(0x9ce40000)));
107 CHECK_EQ(17, m.Call(uint32_t(0xc7920000)));
108 CHECK_EQ(16, m.Call(uint32_t(0xb8f10000)));
109 CHECK_EQ(15, m.Call(uint32_t(0x3b9f8000)));
110 CHECK_EQ(14, m.Call(uint32_t(0xdb4c4000)));
111 CHECK_EQ(13, m.Call(uint32_t(0xe9a32000)));
112 CHECK_EQ(12, m.Call(uint32_t(0xfca61000)));
113 CHECK_EQ(11, m.Call(uint32_t(0x6c8a7800)));
114 CHECK_EQ(10, m.Call(uint32_t(0x8ce5a400)));
115 CHECK_EQ(9, m.Call(uint32_t(0xcb7d0200)));
116 CHECK_EQ(8, m.Call(uint32_t(0xcb4dc100)));
117 CHECK_EQ(7, m.Call(uint32_t(0xdfbec580)));
118 CHECK_EQ(6, m.Call(uint32_t(0x27a9db40)));
119 CHECK_EQ(5, m.Call(uint32_t(0xde3bcb20)));
120 CHECK_EQ(4, m.Call(uint32_t(0xd7e8a610)));
121 CHECK_EQ(3, m.Call(uint32_t(0x9afdbc88)));
122 CHECK_EQ(2, m.Call(uint32_t(0x9afdbc84)));
123 CHECK_EQ(1, m.Call(uint32_t(0x9afdbc82)));
124 CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
125}
126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127TEST(RunWord32Clz) {
128 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
129 m.Return(m.Word32Clz(m.Parameter(0)));
130
131 CHECK_EQ(0, m.Call(uint32_t(0x80001000)));
132 CHECK_EQ(1, m.Call(uint32_t(0x40000500)));
133 CHECK_EQ(2, m.Call(uint32_t(0x20000300)));
134 CHECK_EQ(3, m.Call(uint32_t(0x10000003)));
135 CHECK_EQ(4, m.Call(uint32_t(0x08050000)));
136 CHECK_EQ(5, m.Call(uint32_t(0x04006000)));
137 CHECK_EQ(6, m.Call(uint32_t(0x02000000)));
138 CHECK_EQ(7, m.Call(uint32_t(0x010000a0)));
139 CHECK_EQ(8, m.Call(uint32_t(0x00800c00)));
140 CHECK_EQ(9, m.Call(uint32_t(0x00400000)));
141 CHECK_EQ(10, m.Call(uint32_t(0x0020000d)));
142 CHECK_EQ(11, m.Call(uint32_t(0x00100f00)));
143 CHECK_EQ(12, m.Call(uint32_t(0x00080000)));
144 CHECK_EQ(13, m.Call(uint32_t(0x00041000)));
145 CHECK_EQ(14, m.Call(uint32_t(0x00020020)));
146 CHECK_EQ(15, m.Call(uint32_t(0x00010300)));
147 CHECK_EQ(16, m.Call(uint32_t(0x00008040)));
148 CHECK_EQ(17, m.Call(uint32_t(0x00004005)));
149 CHECK_EQ(18, m.Call(uint32_t(0x00002050)));
150 CHECK_EQ(19, m.Call(uint32_t(0x00001700)));
151 CHECK_EQ(20, m.Call(uint32_t(0x00000870)));
152 CHECK_EQ(21, m.Call(uint32_t(0x00000405)));
153 CHECK_EQ(22, m.Call(uint32_t(0x00000203)));
154 CHECK_EQ(23, m.Call(uint32_t(0x00000101)));
155 CHECK_EQ(24, m.Call(uint32_t(0x00000089)));
156 CHECK_EQ(25, m.Call(uint32_t(0x00000041)));
157 CHECK_EQ(26, m.Call(uint32_t(0x00000022)));
158 CHECK_EQ(27, m.Call(uint32_t(0x00000013)));
159 CHECK_EQ(28, m.Call(uint32_t(0x00000008)));
160 CHECK_EQ(29, m.Call(uint32_t(0x00000004)));
161 CHECK_EQ(30, m.Call(uint32_t(0x00000002)));
162 CHECK_EQ(31, m.Call(uint32_t(0x00000001)));
163 CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
164}
165
166
167TEST(RunWord32Popcnt) {
168 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
169 if (!m.machine()->Word32Popcnt().IsSupported()) {
170 // We can only test the operator if it exists on the testing platform.
171 return;
172 }
173 m.Return(m.AddNode(m.machine()->Word32Popcnt().op(), m.Parameter(0)));
174
175 CHECK_EQ(0, m.Call(uint32_t(0x00000000)));
176 CHECK_EQ(1, m.Call(uint32_t(0x00000001)));
177 CHECK_EQ(1, m.Call(uint32_t(0x80000000)));
178 CHECK_EQ(32, m.Call(uint32_t(0xffffffff)));
179 CHECK_EQ(6, m.Call(uint32_t(0x000dc100)));
180 CHECK_EQ(9, m.Call(uint32_t(0xe00dc100)));
181 CHECK_EQ(11, m.Call(uint32_t(0xe00dc103)));
182 CHECK_EQ(9, m.Call(uint32_t(0x000dc107)));
183}
184
185
186#if V8_TARGET_ARCH_64_BIT
Ben Murdoch097c5b22016-05-18 11:27:45 +0100187TEST(RunWord64ReverseBits) {
188 RawMachineAssemblerTester<uint64_t> m(MachineType::Uint64());
189 if (!m.machine()->Word64ReverseBits().IsSupported()) {
190 return;
191 }
192
193 m.Return(m.AddNode(m.machine()->Word64ReverseBits().op(), m.Parameter(0)));
194
195 CHECK_EQ(uint64_t(0x0000000000000000), m.Call(uint64_t(0x0000000000000000)));
196 CHECK_EQ(uint64_t(0x1234567890abcdef), m.Call(uint64_t(0xf7b3d5091e6a2c48)));
197 CHECK_EQ(uint64_t(0xfedcba0987654321), m.Call(uint64_t(0x84c2a6e1905d3b7f)));
198 CHECK_EQ(uint64_t(0x0101010101010101), m.Call(uint64_t(0x8080808080808080)));
199 CHECK_EQ(uint64_t(0x0102040803060c01), m.Call(uint64_t(0x803060c010204080)));
200 CHECK_EQ(uint64_t(0xf0703010e060200f), m.Call(uint64_t(0xf0040607080c0e0f)));
201 CHECK_EQ(uint64_t(0x2f8a6df01c21fa3b), m.Call(uint64_t(0xdc5f84380fb651f4)));
202 CHECK_EQ(uint64_t(0xffffffffffffffff), m.Call(uint64_t(0xffffffffffffffff)));
203}
204
205
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206TEST(RunWord64Clz) {
207 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
208 m.Return(m.Word64Clz(m.Parameter(0)));
209
210 CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000)));
211 CHECK_EQ(1, m.Call(uint64_t(0x4000050000000000)));
212 CHECK_EQ(2, m.Call(uint64_t(0x2000030000000000)));
213 CHECK_EQ(3, m.Call(uint64_t(0x1000000300000000)));
214 CHECK_EQ(4, m.Call(uint64_t(0x0805000000000000)));
215 CHECK_EQ(5, m.Call(uint64_t(0x0400600000000000)));
216 CHECK_EQ(6, m.Call(uint64_t(0x0200000000000000)));
217 CHECK_EQ(7, m.Call(uint64_t(0x010000a000000000)));
218 CHECK_EQ(8, m.Call(uint64_t(0x00800c0000000000)));
219 CHECK_EQ(9, m.Call(uint64_t(0x0040000000000000)));
220 CHECK_EQ(10, m.Call(uint64_t(0x0020000d00000000)));
221 CHECK_EQ(11, m.Call(uint64_t(0x00100f0000000000)));
222 CHECK_EQ(12, m.Call(uint64_t(0x0008000000000000)));
223 CHECK_EQ(13, m.Call(uint64_t(0x0004100000000000)));
224 CHECK_EQ(14, m.Call(uint64_t(0x0002002000000000)));
225 CHECK_EQ(15, m.Call(uint64_t(0x0001030000000000)));
226 CHECK_EQ(16, m.Call(uint64_t(0x0000804000000000)));
227 CHECK_EQ(17, m.Call(uint64_t(0x0000400500000000)));
228 CHECK_EQ(18, m.Call(uint64_t(0x0000205000000000)));
229 CHECK_EQ(19, m.Call(uint64_t(0x0000170000000000)));
230 CHECK_EQ(20, m.Call(uint64_t(0x0000087000000000)));
231 CHECK_EQ(21, m.Call(uint64_t(0x0000040500000000)));
232 CHECK_EQ(22, m.Call(uint64_t(0x0000020300000000)));
233 CHECK_EQ(23, m.Call(uint64_t(0x0000010100000000)));
234 CHECK_EQ(24, m.Call(uint64_t(0x0000008900000000)));
235 CHECK_EQ(25, m.Call(uint64_t(0x0000004100000000)));
236 CHECK_EQ(26, m.Call(uint64_t(0x0000002200000000)));
237 CHECK_EQ(27, m.Call(uint64_t(0x0000001300000000)));
238 CHECK_EQ(28, m.Call(uint64_t(0x0000000800000000)));
239 CHECK_EQ(29, m.Call(uint64_t(0x0000000400000000)));
240 CHECK_EQ(30, m.Call(uint64_t(0x0000000200000000)));
241 CHECK_EQ(31, m.Call(uint64_t(0x0000000100000000)));
242 CHECK_EQ(32, m.Call(uint64_t(0x0000000080001000)));
243 CHECK_EQ(33, m.Call(uint64_t(0x0000000040000500)));
244 CHECK_EQ(34, m.Call(uint64_t(0x0000000020000300)));
245 CHECK_EQ(35, m.Call(uint64_t(0x0000000010000003)));
246 CHECK_EQ(36, m.Call(uint64_t(0x0000000008050000)));
247 CHECK_EQ(37, m.Call(uint64_t(0x0000000004006000)));
248 CHECK_EQ(38, m.Call(uint64_t(0x0000000002000000)));
249 CHECK_EQ(39, m.Call(uint64_t(0x00000000010000a0)));
250 CHECK_EQ(40, m.Call(uint64_t(0x0000000000800c00)));
251 CHECK_EQ(41, m.Call(uint64_t(0x0000000000400000)));
252 CHECK_EQ(42, m.Call(uint64_t(0x000000000020000d)));
253 CHECK_EQ(43, m.Call(uint64_t(0x0000000000100f00)));
254 CHECK_EQ(44, m.Call(uint64_t(0x0000000000080000)));
255 CHECK_EQ(45, m.Call(uint64_t(0x0000000000041000)));
256 CHECK_EQ(46, m.Call(uint64_t(0x0000000000020020)));
257 CHECK_EQ(47, m.Call(uint64_t(0x0000000000010300)));
258 CHECK_EQ(48, m.Call(uint64_t(0x0000000000008040)));
259 CHECK_EQ(49, m.Call(uint64_t(0x0000000000004005)));
260 CHECK_EQ(50, m.Call(uint64_t(0x0000000000002050)));
261 CHECK_EQ(51, m.Call(uint64_t(0x0000000000001700)));
262 CHECK_EQ(52, m.Call(uint64_t(0x0000000000000870)));
263 CHECK_EQ(53, m.Call(uint64_t(0x0000000000000405)));
264 CHECK_EQ(54, m.Call(uint64_t(0x0000000000000203)));
265 CHECK_EQ(55, m.Call(uint64_t(0x0000000000000101)));
266 CHECK_EQ(56, m.Call(uint64_t(0x0000000000000089)));
267 CHECK_EQ(57, m.Call(uint64_t(0x0000000000000041)));
268 CHECK_EQ(58, m.Call(uint64_t(0x0000000000000022)));
269 CHECK_EQ(59, m.Call(uint64_t(0x0000000000000013)));
270 CHECK_EQ(60, m.Call(uint64_t(0x0000000000000008)));
271 CHECK_EQ(61, m.Call(uint64_t(0x0000000000000004)));
272 CHECK_EQ(62, m.Call(uint64_t(0x0000000000000002)));
273 CHECK_EQ(63, m.Call(uint64_t(0x0000000000000001)));
274 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
275}
276
277
278TEST(RunWord64Ctz) {
279 RawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
280 if (!m.machine()->Word64Ctz().IsSupported()) {
281 return;
282 }
283
284 m.Return(m.AddNode(m.machine()->Word64Ctz().op(), m.Parameter(0)));
285
286 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
287 CHECK_EQ(63, m.Call(uint64_t(0x8000000000000000)));
288 CHECK_EQ(62, m.Call(uint64_t(0x4000000000000000)));
289 CHECK_EQ(61, m.Call(uint64_t(0x2000000000000000)));
290 CHECK_EQ(60, m.Call(uint64_t(0x1000000000000000)));
291 CHECK_EQ(59, m.Call(uint64_t(0xa800000000000000)));
292 CHECK_EQ(58, m.Call(uint64_t(0xf400000000000000)));
293 CHECK_EQ(57, m.Call(uint64_t(0x6200000000000000)));
294 CHECK_EQ(56, m.Call(uint64_t(0x9100000000000000)));
295 CHECK_EQ(55, m.Call(uint64_t(0xcd80000000000000)));
296 CHECK_EQ(54, m.Call(uint64_t(0x0940000000000000)));
297 CHECK_EQ(53, m.Call(uint64_t(0xaf20000000000000)));
298 CHECK_EQ(52, m.Call(uint64_t(0xac10000000000000)));
299 CHECK_EQ(51, m.Call(uint64_t(0xe0b8000000000000)));
300 CHECK_EQ(50, m.Call(uint64_t(0x9ce4000000000000)));
301 CHECK_EQ(49, m.Call(uint64_t(0xc792000000000000)));
302 CHECK_EQ(48, m.Call(uint64_t(0xb8f1000000000000)));
303 CHECK_EQ(47, m.Call(uint64_t(0x3b9f800000000000)));
304 CHECK_EQ(46, m.Call(uint64_t(0xdb4c400000000000)));
305 CHECK_EQ(45, m.Call(uint64_t(0xe9a3200000000000)));
306 CHECK_EQ(44, m.Call(uint64_t(0xfca6100000000000)));
307 CHECK_EQ(43, m.Call(uint64_t(0x6c8a780000000000)));
308 CHECK_EQ(42, m.Call(uint64_t(0x8ce5a40000000000)));
309 CHECK_EQ(41, m.Call(uint64_t(0xcb7d020000000000)));
310 CHECK_EQ(40, m.Call(uint64_t(0xcb4dc10000000000)));
311 CHECK_EQ(39, m.Call(uint64_t(0xdfbec58000000000)));
312 CHECK_EQ(38, m.Call(uint64_t(0x27a9db4000000000)));
313 CHECK_EQ(37, m.Call(uint64_t(0xde3bcb2000000000)));
314 CHECK_EQ(36, m.Call(uint64_t(0xd7e8a61000000000)));
315 CHECK_EQ(35, m.Call(uint64_t(0x9afdbc8800000000)));
316 CHECK_EQ(34, m.Call(uint64_t(0x9afdbc8400000000)));
317 CHECK_EQ(33, m.Call(uint64_t(0x9afdbc8200000000)));
318 CHECK_EQ(32, m.Call(uint64_t(0x9afdbc8100000000)));
319 CHECK_EQ(31, m.Call(uint64_t(0x0000000080000000)));
320 CHECK_EQ(30, m.Call(uint64_t(0x0000000040000000)));
321 CHECK_EQ(29, m.Call(uint64_t(0x0000000020000000)));
322 CHECK_EQ(28, m.Call(uint64_t(0x0000000010000000)));
323 CHECK_EQ(27, m.Call(uint64_t(0x00000000a8000000)));
324 CHECK_EQ(26, m.Call(uint64_t(0x00000000f4000000)));
325 CHECK_EQ(25, m.Call(uint64_t(0x0000000062000000)));
326 CHECK_EQ(24, m.Call(uint64_t(0x0000000091000000)));
327 CHECK_EQ(23, m.Call(uint64_t(0x00000000cd800000)));
328 CHECK_EQ(22, m.Call(uint64_t(0x0000000009400000)));
329 CHECK_EQ(21, m.Call(uint64_t(0x00000000af200000)));
330 CHECK_EQ(20, m.Call(uint64_t(0x00000000ac100000)));
331 CHECK_EQ(19, m.Call(uint64_t(0x00000000e0b80000)));
332 CHECK_EQ(18, m.Call(uint64_t(0x000000009ce40000)));
333 CHECK_EQ(17, m.Call(uint64_t(0x00000000c7920000)));
334 CHECK_EQ(16, m.Call(uint64_t(0x00000000b8f10000)));
335 CHECK_EQ(15, m.Call(uint64_t(0x000000003b9f8000)));
336 CHECK_EQ(14, m.Call(uint64_t(0x00000000db4c4000)));
337 CHECK_EQ(13, m.Call(uint64_t(0x00000000e9a32000)));
338 CHECK_EQ(12, m.Call(uint64_t(0x00000000fca61000)));
339 CHECK_EQ(11, m.Call(uint64_t(0x000000006c8a7800)));
340 CHECK_EQ(10, m.Call(uint64_t(0x000000008ce5a400)));
341 CHECK_EQ(9, m.Call(uint64_t(0x00000000cb7d0200)));
342 CHECK_EQ(8, m.Call(uint64_t(0x00000000cb4dc100)));
343 CHECK_EQ(7, m.Call(uint64_t(0x00000000dfbec580)));
344 CHECK_EQ(6, m.Call(uint64_t(0x0000000027a9db40)));
345 CHECK_EQ(5, m.Call(uint64_t(0x00000000de3bcb20)));
346 CHECK_EQ(4, m.Call(uint64_t(0x00000000d7e8a610)));
347 CHECK_EQ(3, m.Call(uint64_t(0x000000009afdbc88)));
348 CHECK_EQ(2, m.Call(uint64_t(0x000000009afdbc84)));
349 CHECK_EQ(1, m.Call(uint64_t(0x000000009afdbc82)));
350 CHECK_EQ(0, m.Call(uint64_t(0x000000009afdbc81)));
351}
352
353
354TEST(RunWord64Popcnt) {
355 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
356 if (!m.machine()->Word64Popcnt().IsSupported()) {
357 return;
358 }
359
360 m.Return(m.AddNode(m.machine()->Word64Popcnt().op(), m.Parameter(0)));
361
362 CHECK_EQ(0, m.Call(uint64_t(0x0000000000000000)));
363 CHECK_EQ(1, m.Call(uint64_t(0x0000000000000001)));
364 CHECK_EQ(1, m.Call(uint64_t(0x8000000000000000)));
365 CHECK_EQ(64, m.Call(uint64_t(0xffffffffffffffff)));
366 CHECK_EQ(12, m.Call(uint64_t(0x000dc100000dc100)));
367 CHECK_EQ(18, m.Call(uint64_t(0xe00dc100e00dc100)));
368 CHECK_EQ(22, m.Call(uint64_t(0xe00dc103e00dc103)));
369 CHECK_EQ(18, m.Call(uint64_t(0x000dc107000dc107)));
370}
371#endif // V8_TARGET_ARCH_64_BIT
372
373
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
375 switch (index) {
376 case 0:
377 return m->Parameter(0);
378 case 1:
379 return m->Parameter(1);
380 case 2:
381 return m->Int32Constant(0);
382 case 3:
383 return m->Int32Constant(1);
384 case 4:
385 return m->Int32Constant(-1);
386 case 5:
387 return m->Int32Constant(0xff);
388 case 6:
389 return m->Int32Constant(0x01234567);
390 case 7:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 return m->Load(MachineType::Int32(), m->PointerConstant(NULL));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392 default:
393 return NULL;
394 }
395}
396
397
398TEST(CodeGenInt32Binop) {
399 RawMachineAssemblerTester<void> m;
400
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400401 const Operator* kOps[] = {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000402 m.machine()->Word32And(), m.machine()->Word32Or(),
403 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
404 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
405 m.machine()->Word32Equal(), m.machine()->Int32Add(),
406 m.machine()->Int32Sub(), m.machine()->Int32Mul(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400407 m.machine()->Int32MulHigh(), m.machine()->Int32Div(),
408 m.machine()->Uint32Div(), m.machine()->Int32Mod(),
409 m.machine()->Uint32Mod(), m.machine()->Uint32MulHigh(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400411 m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000412
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400413 for (size_t i = 0; i < arraysize(kOps); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000414 for (int j = 0; j < 8; j++) {
415 for (int k = 0; k < 8; k++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
417 MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000418 Node* a = Int32Input(&m, j);
419 Node* b = Int32Input(&m, k);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000420 m.Return(m.AddNode(kOps[i], a, b));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000421 m.GenerateCode();
422 }
423 }
424 }
425}
426
427
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428TEST(CodeGenNop) {
429 RawMachineAssemblerTester<void> m;
430 m.Return(m.Int32Constant(0));
431 m.GenerateCode();
432}
433
434
435#if V8_TARGET_ARCH_64_BIT
436static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
437 switch (index) {
438 case 0:
439 return m->Parameter(0);
440 case 1:
441 return m->Parameter(1);
442 case 2:
443 return m->Int64Constant(0);
444 case 3:
445 return m->Int64Constant(1);
446 case 4:
447 return m->Int64Constant(-1);
448 case 5:
449 return m->Int64Constant(0xff);
450 case 6:
451 return m->Int64Constant(0x0123456789abcdefLL);
452 case 7:
453 return m->Load(MachineType::Int64(), m->PointerConstant(NULL));
454 default:
455 return NULL;
456 }
457}
458
459
460TEST(CodeGenInt64Binop) {
461 RawMachineAssemblerTester<void> m;
462
463 const Operator* kOps[] = {
464 m.machine()->Word64And(), m.machine()->Word64Or(),
465 m.machine()->Word64Xor(), m.machine()->Word64Shl(),
466 m.machine()->Word64Shr(), m.machine()->Word64Sar(),
467 m.machine()->Word64Equal(), m.machine()->Int64Add(),
468 m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
469 m.machine()->Uint64Div(), m.machine()->Int64Mod(),
470 m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
471 m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
472 m.machine()->Uint64LessThanOrEqual()};
473
474 for (size_t i = 0; i < arraysize(kOps); ++i) {
475 for (int j = 0; j < 8; j++) {
476 for (int k = 0; k < 8; k++) {
477 RawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
478 MachineType::Int64());
479 Node* a = Int64Input(&m, j);
480 Node* b = Int64Input(&m, k);
481 m.Return(m.AddNode(kOps[i], a, b));
482 m.GenerateCode();
483 }
484 }
485 }
486}
487
488
489TEST(RunInt64AddWithOverflowP) {
490 int64_t actual_val = -1;
491 RawMachineAssemblerTester<int32_t> m;
492 Int64BinopTester bt(&m);
493 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
494 Node* val = m.Projection(0, add);
495 Node* ovf = m.Projection(1, add);
496 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
497 bt.AddReturn(ovf);
498 FOR_INT64_INPUTS(i) {
499 FOR_INT64_INPUTS(j) {
500 int64_t expected_val;
501 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
502 CHECK_EQ(expected_ovf, bt.call(*i, *j));
503 CHECK_EQ(expected_val, actual_val);
504 }
505 }
506}
507
508
509TEST(RunInt64AddWithOverflowImm) {
510 int64_t actual_val = -1, expected_val = 0;
511 FOR_INT64_INPUTS(i) {
512 {
513 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
514 Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0));
515 Node* val = m.Projection(0, add);
516 Node* ovf = m.Projection(1, add);
517 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
518 m.Return(ovf);
519 FOR_INT64_INPUTS(j) {
520 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
521 CHECK_EQ(expected_ovf, m.Call(*j));
522 CHECK_EQ(expected_val, actual_val);
523 }
524 }
525 {
526 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
527 Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i));
528 Node* val = m.Projection(0, add);
529 Node* ovf = m.Projection(1, add);
530 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
531 m.Return(ovf);
532 FOR_INT64_INPUTS(j) {
533 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
534 CHECK_EQ(expected_ovf, m.Call(*j));
535 CHECK_EQ(expected_val, actual_val);
536 }
537 }
538 FOR_INT64_INPUTS(j) {
539 RawMachineAssemblerTester<int32_t> m;
540 Node* add =
541 m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
542 Node* val = m.Projection(0, add);
543 Node* ovf = m.Projection(1, add);
544 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
545 m.Return(ovf);
546 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
547 CHECK_EQ(expected_ovf, m.Call());
548 CHECK_EQ(expected_val, actual_val);
549 }
550 }
551}
552
553
554TEST(RunInt64AddWithOverflowInBranchP) {
555 int constant = 911777;
556 RawMachineLabel blocka, blockb;
557 RawMachineAssemblerTester<int32_t> m;
558 Int64BinopTester bt(&m);
559 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
560 Node* ovf = m.Projection(1, add);
561 m.Branch(ovf, &blocka, &blockb);
562 m.Bind(&blocka);
563 bt.AddReturn(m.Int64Constant(constant));
564 m.Bind(&blockb);
565 Node* val = m.Projection(0, add);
566 Node* truncated = m.TruncateInt64ToInt32(val);
567 bt.AddReturn(truncated);
568 FOR_INT64_INPUTS(i) {
569 FOR_INT64_INPUTS(j) {
570 int32_t expected = constant;
571 int64_t result;
572 if (!bits::SignedAddOverflow64(*i, *j, &result)) {
573 expected = static_cast<int32_t>(result);
574 }
575 CHECK_EQ(expected, bt.call(*i, *j));
576 }
577 }
578}
579
580
581TEST(RunInt64SubWithOverflowP) {
582 int64_t actual_val = -1;
583 RawMachineAssemblerTester<int32_t> m;
584 Int64BinopTester bt(&m);
585 Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1);
586 Node* val = m.Projection(0, add);
587 Node* ovf = m.Projection(1, add);
588 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
589 bt.AddReturn(ovf);
590 FOR_INT64_INPUTS(i) {
591 FOR_INT64_INPUTS(j) {
592 int64_t expected_val;
593 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
594 CHECK_EQ(expected_ovf, bt.call(*i, *j));
595 CHECK_EQ(expected_val, actual_val);
596 }
597 }
598}
599
600
601TEST(RunInt64SubWithOverflowImm) {
602 int64_t actual_val = -1, expected_val = 0;
603 FOR_INT64_INPUTS(i) {
604 {
605 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
606 Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0));
607 Node* val = m.Projection(0, add);
608 Node* ovf = m.Projection(1, add);
609 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
610 m.Return(ovf);
611 FOR_INT64_INPUTS(j) {
612 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
613 CHECK_EQ(expected_ovf, m.Call(*j));
614 CHECK_EQ(expected_val, actual_val);
615 }
616 }
617 {
618 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
619 Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i));
620 Node* val = m.Projection(0, add);
621 Node* ovf = m.Projection(1, add);
622 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
623 m.Return(ovf);
624 FOR_INT64_INPUTS(j) {
625 int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val);
626 CHECK_EQ(expected_ovf, m.Call(*j));
627 CHECK_EQ(expected_val, actual_val);
628 }
629 }
630 FOR_INT64_INPUTS(j) {
631 RawMachineAssemblerTester<int32_t> m;
632 Node* add =
633 m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
634 Node* val = m.Projection(0, add);
635 Node* ovf = m.Projection(1, add);
636 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
637 m.Return(ovf);
638 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
639 CHECK_EQ(expected_ovf, m.Call());
640 CHECK_EQ(expected_val, actual_val);
641 }
642 }
643}
644
645
646TEST(RunInt64SubWithOverflowInBranchP) {
647 int constant = 911999;
648 RawMachineLabel blocka, blockb;
649 RawMachineAssemblerTester<int32_t> m;
650 Int64BinopTester bt(&m);
651 Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1);
652 Node* ovf = m.Projection(1, sub);
653 m.Branch(ovf, &blocka, &blockb);
654 m.Bind(&blocka);
655 bt.AddReturn(m.Int64Constant(constant));
656 m.Bind(&blockb);
657 Node* val = m.Projection(0, sub);
658 Node* truncated = m.TruncateInt64ToInt32(val);
659 bt.AddReturn(truncated);
660 FOR_INT64_INPUTS(i) {
661 FOR_INT64_INPUTS(j) {
662 int32_t expected = constant;
663 int64_t result;
664 if (!bits::SignedSubOverflow64(*i, *j, &result)) {
665 expected = static_cast<int32_t>(result);
666 }
667 CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j)));
668 }
669 }
670}
671
Ben Murdochc5610432016-08-08 18:44:38 +0100672static int64_t RunInt64AddShift(bool is_left, int64_t add_left,
673 int64_t add_right, int64_t shift_left,
674 int64_t shit_right) {
675 RawMachineAssemblerTester<int64_t> m;
676 Node* shift = m.Word64Shl(m.Int64Constant(4), m.Int64Constant(2));
677 Node* add = m.Int64Add(m.Int64Constant(20), m.Int64Constant(22));
678 Node* dlsa = is_left ? m.Int64Add(shift, add) : m.Int64Add(add, shift);
679 m.Return(dlsa);
680 return m.Call();
681}
682
683TEST(RunInt64AddShift) {
684 struct Test_case {
685 int64_t add_left, add_right, shift_left, shit_right, expected;
686 };
687
688 Test_case tc[] = {
689 {20, 22, 4, 2, 58},
690 {20, 22, 4, 1, 50},
691 {20, 22, 1, 6, 106},
692 {INT64_MAX - 2, 1, 1, 1,
693 INT64_MIN}, // INT64_MAX - 2 + 1 + (1 << 1), overflow.
694 };
695 const size_t tc_size = sizeof(tc) / sizeof(Test_case);
696
697 for (size_t i = 0; i < tc_size; ++i) {
698 CHECK_EQ(58, RunInt64AddShift(false, tc[i].add_left, tc[i].add_right,
699 tc[i].shift_left, tc[i].shit_right));
700 CHECK_EQ(58, RunInt64AddShift(true, tc[i].add_left, tc[i].add_right,
701 tc[i].shift_left, tc[i].shit_right));
702 }
703}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704
705// TODO(titzer): add tests that run 64-bit integer operations.
706#endif // V8_TARGET_ARCH_64_BIT
707
708
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000709TEST(RunGoto) {
710 RawMachineAssemblerTester<int32_t> m;
711 int constant = 99999;
712
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000713 RawMachineLabel next;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000714 m.Goto(&next);
715 m.Bind(&next);
716 m.Return(m.Int32Constant(constant));
717
718 CHECK_EQ(constant, m.Call());
719}
720
721
722TEST(RunGotoMultiple) {
723 RawMachineAssemblerTester<int32_t> m;
724 int constant = 9999977;
725
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000726 RawMachineLabel labels[10];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 for (size_t i = 0; i < arraysize(labels); i++) {
728 m.Goto(&labels[i]);
729 m.Bind(&labels[i]);
730 }
731 m.Return(m.Int32Constant(constant));
732
733 CHECK_EQ(constant, m.Call());
734}
735
736
737TEST(RunBranch) {
738 RawMachineAssemblerTester<int32_t> m;
739 int constant = 999777;
740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742 m.Branch(m.Int32Constant(0), &blocka, &blockb);
743 m.Bind(&blocka);
744 m.Return(m.Int32Constant(0 - constant));
745 m.Bind(&blockb);
746 m.Return(m.Int32Constant(constant));
747
748 CHECK_EQ(constant, m.Call());
749}
750
751
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000752TEST(RunDiamond2) {
753 RawMachineAssemblerTester<int32_t> m;
754
755 int constant = 995666;
756
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000758 m.Branch(m.Int32Constant(0), &blocka, &blockb);
759 m.Bind(&blocka);
760 m.Goto(&end);
761 m.Bind(&blockb);
762 m.Goto(&end);
763 m.Bind(&end);
764 m.Return(m.Int32Constant(constant));
765
766 CHECK_EQ(constant, m.Call());
767}
768
769
770TEST(RunLoop) {
771 RawMachineAssemblerTester<int32_t> m;
772 int constant = 999555;
773
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774 RawMachineLabel header, body, exit;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000775 m.Goto(&header);
776 m.Bind(&header);
777 m.Branch(m.Int32Constant(0), &body, &exit);
778 m.Bind(&body);
779 m.Goto(&header);
780 m.Bind(&exit);
781 m.Return(m.Int32Constant(constant));
782
783 CHECK_EQ(constant, m.Call());
784}
785
786
787template <typename R>
788static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000789 MachineRepresentation rep, Node* true_node,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000790 Node* false_node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000792 m->Branch(cond_node, &blocka, &blockb);
793 m->Bind(&blocka);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794 m->Goto(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000795 m->Bind(&blockb);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 m->Goto(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000798 m->Bind(&end);
799 Node* phi = m->Phi(rep, true_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000800 m->Return(phi);
801}
802
803
804TEST(RunDiamondPhiConst) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806 int false_val = 0xFF666;
807 int true_val = 0x00DDD;
808 Node* true_node = m.Int32Constant(true_val);
809 Node* false_node = m.Int32Constant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node,
811 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 CHECK_EQ(false_val, m.Call(0));
813 CHECK_EQ(true_val, m.Call(1));
814}
815
816
817TEST(RunDiamondPhiNumber) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000819 double false_val = -11.1;
820 double true_val = 200.1;
821 Node* true_node = m.NumberConstant(true_val);
822 Node* false_node = m.NumberConstant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000823 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
824 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 m.CheckNumber(false_val, m.Call(0));
826 m.CheckNumber(true_val, m.Call(1));
827}
828
829
830TEST(RunDiamondPhiString) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000832 const char* false_val = "false";
833 const char* true_val = "true";
834 Node* true_node = m.StringConstant(true_val);
835 Node* false_node = m.StringConstant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000836 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
837 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838 m.CheckString(false_val, m.Call(0));
839 m.CheckString(true_val, m.Call(1));
840}
841
842
843TEST(RunDiamondPhiParam) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000844 RawMachineAssemblerTester<int32_t> m(
845 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
846 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32,
847 m.Parameter(1), m.Parameter(2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000848 int32_t c1 = 0x260cb75a;
849 int32_t c2 = 0xcd3e9c8b;
850 int result = m.Call(0, c1, c2);
851 CHECK_EQ(c2, result);
852 result = m.Call(1, c1, c2);
853 CHECK_EQ(c1, result);
854}
855
856
857TEST(RunLoopPhiConst) {
858 RawMachineAssemblerTester<int32_t> m;
859 int true_val = 0x44000;
860 int false_val = 0x00888;
861
862 Node* cond_node = m.Int32Constant(0);
863 Node* true_node = m.Int32Constant(true_val);
864 Node* false_node = m.Int32Constant(false_val);
865
866 // x = false_val; while(false) { x = true_val; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 RawMachineLabel body, header, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868
869 m.Goto(&header);
870 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000871 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node);
872 m.Branch(cond_node, &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000873 m.Bind(&body);
874 m.Goto(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000875 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000876 m.Return(phi);
877
878 CHECK_EQ(false_val, m.Call());
879}
880
881
882TEST(RunLoopPhiParam) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000883 RawMachineAssemblerTester<int32_t> m(
884 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000885
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887
888 m.Goto(&blocka);
889
890 m.Bind(&blocka);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000891 Node* phi =
892 m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2));
893 Node* cond =
894 m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0));
895 m.Branch(cond, &blockb, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896
897 m.Bind(&blockb);
898 m.Goto(&blocka);
899
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000900 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000901 m.Return(phi);
902
903 int32_t c1 = 0xa81903b4;
904 int32_t c2 = 0x5a1207da;
905 int result = m.Call(0, c1, c2);
906 CHECK_EQ(c1, result);
907 result = m.Call(1, c1, c2);
908 CHECK_EQ(c2, result);
909}
910
911
912TEST(RunLoopPhiInduction) {
913 RawMachineAssemblerTester<int32_t> m;
914
915 int false_val = 0x10777;
916
917 // x = false_val; while(false) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 Node* false_node = m.Int32Constant(false_val);
920
921 m.Goto(&header);
922
923 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
925 m.Branch(m.Int32Constant(0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000926
927 m.Bind(&body);
928 Node* add = m.Int32Add(phi, m.Int32Constant(1));
929 phi->ReplaceInput(1, add);
930 m.Goto(&header);
931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000932 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000933 m.Return(phi);
934
935 CHECK_EQ(false_val, m.Call());
936}
937
938
939TEST(RunLoopIncrement) {
940 RawMachineAssemblerTester<int32_t> m;
941 Int32BinopTester bt(&m);
942
943 // x = 0; while(x ^ param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000945 Node* zero = m.Int32Constant(0);
946
947 m.Goto(&header);
948
949 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
951 m.Branch(m.WordXor(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000952
953 m.Bind(&body);
954 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
955 m.Goto(&header);
956
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000958 bt.AddReturn(phi);
959
960 CHECK_EQ(11, bt.call(11, 0));
961 CHECK_EQ(110, bt.call(110, 0));
962 CHECK_EQ(176, bt.call(176, 0));
963}
964
965
966TEST(RunLoopIncrement2) {
967 RawMachineAssemblerTester<int32_t> m;
968 Int32BinopTester bt(&m);
969
970 // x = 0; while(x < param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000971 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000972 Node* zero = m.Int32Constant(0);
973
974 m.Goto(&header);
975
976 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000977 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
978 m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000979
980 m.Bind(&body);
981 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
982 m.Goto(&header);
983
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000985 bt.AddReturn(phi);
986
987 CHECK_EQ(11, bt.call(11, 0));
988 CHECK_EQ(110, bt.call(110, 0));
989 CHECK_EQ(176, bt.call(176, 0));
990 CHECK_EQ(0, bt.call(-200, 0));
991}
992
993
994TEST(RunLoopIncrement3) {
995 RawMachineAssemblerTester<int32_t> m;
996 Int32BinopTester bt(&m);
997
998 // x = 0; while(x < param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000999 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001000 Node* zero = m.Int32Constant(0);
1001
1002 m.Goto(&header);
1003
1004 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001005 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
1006 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001007
1008 m.Bind(&body);
1009 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
1010 m.Goto(&header);
1011
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001012 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013 bt.AddReturn(phi);
1014
1015 CHECK_EQ(11, bt.call(11, 0));
1016 CHECK_EQ(110, bt.call(110, 0));
1017 CHECK_EQ(176, bt.call(176, 0));
1018 CHECK_EQ(200, bt.call(200, 0));
1019}
1020
1021
1022TEST(RunLoopDecrement) {
1023 RawMachineAssemblerTester<int32_t> m;
1024 Int32BinopTester bt(&m);
1025
1026 // x = param; while(x) { x--; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001027 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028
1029 m.Goto(&header);
1030
1031 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001032 Node* phi =
1033 m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0));
1034 m.Branch(phi, &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001035
1036 m.Bind(&body);
1037 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
1038 m.Goto(&header);
1039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001040 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041 bt.AddReturn(phi);
1042
1043 CHECK_EQ(0, bt.call(11, 0));
1044 CHECK_EQ(0, bt.call(110, 0));
1045 CHECK_EQ(0, bt.call(197, 0));
1046}
1047
1048
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001049TEST(RunLoopIncrementFloat32) {
1050 RawMachineAssemblerTester<int32_t> m;
1051
1052 // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
1053 RawMachineLabel header, body, end;
1054 Node* minus_3 = m.Float32Constant(-3.0f);
1055 Node* ten = m.Float32Constant(10.0f);
1056
1057 m.Goto(&header);
1058
1059 m.Bind(&header);
1060 Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten);
1061 m.Branch(m.Float32LessThan(phi, ten), &body, &end);
1062
1063 m.Bind(&body);
1064 phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
1065 m.Goto(&header);
1066
1067 m.Bind(&end);
1068 m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
1069
1070 CHECK_EQ(10, m.Call());
1071}
1072
1073
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001074TEST(RunLoopIncrementFloat64) {
1075 RawMachineAssemblerTester<int32_t> m;
1076
1077 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 Node* minus_3 = m.Float64Constant(-3.0);
1080 Node* ten = m.Float64Constant(10.0);
1081
1082 m.Goto(&header);
1083
1084 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001085 Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten);
1086 m.Branch(m.Float64LessThan(phi, ten), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001087
1088 m.Bind(&body);
1089 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
1090 m.Goto(&header);
1091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001093 m.Return(m.ChangeFloat64ToInt32(phi));
1094
1095 CHECK_EQ(10, m.Call());
1096}
1097
1098
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001099TEST(RunSwitch1) {
1100 RawMachineAssemblerTester<int32_t> m;
1101
1102 int constant = 11223344;
1103
1104 RawMachineLabel block0, block1, def, end;
1105 RawMachineLabel* case_labels[] = {&block0, &block1};
1106 int32_t case_values[] = {0, 1};
1107 m.Switch(m.Int32Constant(0), &def, case_values, case_labels,
1108 arraysize(case_labels));
1109 m.Bind(&block0);
1110 m.Goto(&end);
1111 m.Bind(&block1);
1112 m.Goto(&end);
1113 m.Bind(&def);
1114 m.Goto(&end);
1115 m.Bind(&end);
1116 m.Return(m.Int32Constant(constant));
1117
1118 CHECK_EQ(constant, m.Call());
1119}
1120
1121
1122TEST(RunSwitch2) {
1123 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1124
1125 RawMachineLabel blocka, blockb, blockc;
1126 RawMachineLabel* case_labels[] = {&blocka, &blockb};
1127 int32_t case_values[] = {std::numeric_limits<int32_t>::min(),
1128 std::numeric_limits<int32_t>::max()};
1129 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1130 arraysize(case_labels));
1131 m.Bind(&blocka);
1132 m.Return(m.Int32Constant(-1));
1133 m.Bind(&blockb);
1134 m.Return(m.Int32Constant(1));
1135 m.Bind(&blockc);
1136 m.Return(m.Int32Constant(0));
1137
1138 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max()));
1139 CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min()));
1140 for (int i = -100; i < 100; i += 25) {
1141 CHECK_EQ(0, m.Call(i));
1142 }
1143}
1144
1145
1146TEST(RunSwitch3) {
1147 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1148
1149 RawMachineLabel blocka, blockb, blockc;
1150 RawMachineLabel* case_labels[] = {&blocka, &blockb};
1151 int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0,
1152 std::numeric_limits<int32_t>::min() + 1};
1153 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1154 arraysize(case_labels));
1155 m.Bind(&blocka);
1156 m.Return(m.Int32Constant(0));
1157 m.Bind(&blockb);
1158 m.Return(m.Int32Constant(1));
1159 m.Bind(&blockc);
1160 m.Return(m.Int32Constant(2));
1161
1162 CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0));
1163 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1));
1164 for (int i = -100; i < 100; i += 25) {
1165 CHECK_EQ(2, m.Call(i));
1166 }
1167}
1168
1169
1170TEST(RunSwitch4) {
1171 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1172
1173 const size_t kNumCases = 512;
1174 const size_t kNumValues = kNumCases + 1;
1175 int32_t values[kNumValues];
1176 m.main_isolate()->random_number_generator()->NextBytes(values,
1177 sizeof(values));
1178 RawMachineLabel end, def;
1179 int32_t case_values[kNumCases];
1180 RawMachineLabel* case_labels[kNumCases];
1181 Node* results[kNumValues];
1182 for (size_t i = 0; i < kNumCases; ++i) {
1183 case_values[i] = static_cast<int32_t>(i);
1184 case_labels[i] =
1185 new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
1186 }
1187 m.Switch(m.Parameter(0), &def, case_values, case_labels,
1188 arraysize(case_labels));
1189 for (size_t i = 0; i < kNumCases; ++i) {
1190 m.Bind(case_labels[i]);
1191 results[i] = m.Int32Constant(values[i]);
1192 m.Goto(&end);
1193 }
1194 m.Bind(&def);
1195 results[kNumCases] = m.Int32Constant(values[kNumCases]);
1196 m.Goto(&end);
1197 m.Bind(&end);
1198 const int num_results = static_cast<int>(arraysize(results));
1199 Node* phi =
1200 m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results),
1201 num_results, results);
1202 m.Return(phi);
1203
1204 for (size_t i = 0; i < kNumValues; ++i) {
1205 CHECK_EQ(values[i], m.Call(static_cast<int>(i)));
1206 }
1207}
1208
1209
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210TEST(RunInt32AddP) {
1211 RawMachineAssemblerTester<int32_t> m;
1212 Int32BinopTester bt(&m);
1213
1214 bt.AddReturn(m.Int32Add(bt.param0, bt.param1));
1215
1216 FOR_INT32_INPUTS(i) {
1217 FOR_INT32_INPUTS(j) {
1218 // Use uint32_t because signed overflow is UB in C.
1219 int expected = static_cast<int32_t>(*i + *j);
1220 CHECK_EQ(expected, bt.call(*i, *j));
1221 }
1222 }
1223}
1224
1225
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001226TEST(RunInt32AddAndWord32EqualP) {
1227 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228 RawMachineAssemblerTester<int32_t> m(
1229 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001230 m.Return(m.Int32Add(m.Parameter(0),
1231 m.Word32Equal(m.Parameter(1), m.Parameter(2))));
1232 FOR_INT32_INPUTS(i) {
1233 FOR_INT32_INPUTS(j) {
1234 FOR_INT32_INPUTS(k) {
1235 // Use uint32_t because signed overflow is UB in C.
1236 int32_t const expected =
1237 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1238 CHECK_EQ(expected, m.Call(*i, *j, *k));
1239 }
1240 }
1241 }
1242 }
1243 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244 RawMachineAssemblerTester<int32_t> m(
1245 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001246 m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
1247 m.Parameter(2)));
1248 FOR_INT32_INPUTS(i) {
1249 FOR_INT32_INPUTS(j) {
1250 FOR_INT32_INPUTS(k) {
1251 // Use uint32_t because signed overflow is UB in C.
1252 int32_t const expected =
1253 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1254 CHECK_EQ(expected, m.Call(*i, *j, *k));
1255 }
1256 }
1257 }
1258 }
1259}
1260
1261
1262TEST(RunInt32AddAndWord32EqualImm) {
1263 {
1264 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001265 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1266 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001267 m.Return(m.Int32Add(m.Int32Constant(*i),
1268 m.Word32Equal(m.Parameter(0), m.Parameter(1))));
1269 FOR_INT32_INPUTS(j) {
1270 FOR_INT32_INPUTS(k) {
1271 // Use uint32_t because signed overflow is UB in C.
1272 int32_t const expected =
1273 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1274 CHECK_EQ(expected, m.Call(*j, *k));
1275 }
1276 }
1277 }
1278 }
1279 {
1280 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001281 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1282 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001283 m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
1284 m.Parameter(1)));
1285 FOR_INT32_INPUTS(j) {
1286 FOR_INT32_INPUTS(k) {
1287 // Use uint32_t because signed overflow is UB in C.
1288 int32_t const expected =
1289 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1290 CHECK_EQ(expected, m.Call(*j, *k));
1291 }
1292 }
1293 }
1294 }
1295}
1296
1297
1298TEST(RunInt32AddAndWord32NotEqualP) {
1299 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001300 RawMachineAssemblerTester<int32_t> m(
1301 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001302 m.Return(m.Int32Add(m.Parameter(0),
1303 m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
1304 FOR_INT32_INPUTS(i) {
1305 FOR_INT32_INPUTS(j) {
1306 FOR_INT32_INPUTS(k) {
1307 // Use uint32_t because signed overflow is UB in C.
1308 int32_t const expected =
1309 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1310 CHECK_EQ(expected, m.Call(*i, *j, *k));
1311 }
1312 }
1313 }
1314 }
1315 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001316 RawMachineAssemblerTester<int32_t> m(
1317 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001318 m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
1319 m.Parameter(2)));
1320 FOR_INT32_INPUTS(i) {
1321 FOR_INT32_INPUTS(j) {
1322 FOR_INT32_INPUTS(k) {
1323 // Use uint32_t because signed overflow is UB in C.
1324 int32_t const expected =
1325 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1326 CHECK_EQ(expected, m.Call(*i, *j, *k));
1327 }
1328 }
1329 }
1330 }
1331}
1332
1333
1334TEST(RunInt32AddAndWord32NotEqualImm) {
1335 {
1336 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001337 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1338 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001339 m.Return(m.Int32Add(m.Int32Constant(*i),
1340 m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
1341 FOR_INT32_INPUTS(j) {
1342 FOR_INT32_INPUTS(k) {
1343 // Use uint32_t because signed overflow is UB in C.
1344 int32_t const expected =
1345 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1346 CHECK_EQ(expected, m.Call(*j, *k));
1347 }
1348 }
1349 }
1350 }
1351 {
1352 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001353 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1354 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001355 m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
1356 m.Parameter(1)));
1357 FOR_INT32_INPUTS(j) {
1358 FOR_INT32_INPUTS(k) {
1359 // Use uint32_t because signed overflow is UB in C.
1360 int32_t const expected =
1361 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1362 CHECK_EQ(expected, m.Call(*j, *k));
1363 }
1364 }
1365 }
1366 }
1367}
1368
1369
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001370TEST(RunInt32AddAndWord32SarP) {
1371 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001372 RawMachineAssemblerTester<int32_t> m(
1373 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001374 m.Return(m.Int32Add(m.Parameter(0),
1375 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1376 FOR_UINT32_INPUTS(i) {
1377 FOR_INT32_INPUTS(j) {
1378 FOR_UINT32_SHIFTS(shift) {
1379 // Use uint32_t because signed overflow is UB in C.
1380 int32_t expected = *i + (*j >> shift);
1381 CHECK_EQ(expected, m.Call(*i, *j, shift));
1382 }
1383 }
1384 }
1385 }
1386 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001387 RawMachineAssemblerTester<int32_t> m(
1388 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001389 m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1390 m.Parameter(2)));
1391 FOR_INT32_INPUTS(i) {
1392 FOR_UINT32_SHIFTS(shift) {
1393 FOR_UINT32_INPUTS(k) {
1394 // Use uint32_t because signed overflow is UB in C.
1395 int32_t expected = (*i >> shift) + *k;
1396 CHECK_EQ(expected, m.Call(*i, shift, *k));
1397 }
1398 }
1399 }
1400 }
1401}
1402
1403
1404TEST(RunInt32AddAndWord32ShlP) {
1405 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001406 RawMachineAssemblerTester<int32_t> m(
1407 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001408 m.Return(m.Int32Add(m.Parameter(0),
1409 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1410 FOR_UINT32_INPUTS(i) {
1411 FOR_INT32_INPUTS(j) {
1412 FOR_UINT32_SHIFTS(shift) {
1413 // Use uint32_t because signed overflow is UB in C.
1414 int32_t expected = *i + (*j << shift);
1415 CHECK_EQ(expected, m.Call(*i, *j, shift));
1416 }
1417 }
1418 }
1419 }
1420 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001421 RawMachineAssemblerTester<int32_t> m(
1422 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001423 m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1424 m.Parameter(2)));
1425 FOR_INT32_INPUTS(i) {
1426 FOR_UINT32_SHIFTS(shift) {
1427 FOR_UINT32_INPUTS(k) {
1428 // Use uint32_t because signed overflow is UB in C.
1429 int32_t expected = (*i << shift) + *k;
1430 CHECK_EQ(expected, m.Call(*i, shift, *k));
1431 }
1432 }
1433 }
1434 }
1435}
1436
1437
1438TEST(RunInt32AddAndWord32ShrP) {
1439 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001440 RawMachineAssemblerTester<int32_t> m(
1441 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001442 m.Return(m.Int32Add(m.Parameter(0),
1443 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1444 FOR_UINT32_INPUTS(i) {
1445 FOR_UINT32_INPUTS(j) {
1446 FOR_UINT32_SHIFTS(shift) {
1447 // Use uint32_t because signed overflow is UB in C.
1448 int32_t expected = *i + (*j >> shift);
1449 CHECK_EQ(expected, m.Call(*i, *j, shift));
1450 }
1451 }
1452 }
1453 }
1454 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001455 RawMachineAssemblerTester<int32_t> m(
1456 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001457 m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1458 m.Parameter(2)));
1459 FOR_UINT32_INPUTS(i) {
1460 FOR_UINT32_SHIFTS(shift) {
1461 FOR_UINT32_INPUTS(k) {
1462 // Use uint32_t because signed overflow is UB in C.
1463 int32_t expected = (*i >> shift) + *k;
1464 CHECK_EQ(expected, m.Call(*i, shift, *k));
1465 }
1466 }
1467 }
1468 }
1469}
1470
1471
1472TEST(RunInt32AddInBranch) {
1473 static const int32_t constant = 987654321;
1474 {
1475 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001476 Int32BinopTester bt(&m);
1477 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001478 m.Branch(
1479 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1480 &blocka, &blockb);
1481 m.Bind(&blocka);
1482 bt.AddReturn(m.Int32Constant(constant));
1483 m.Bind(&blockb);
1484 bt.AddReturn(m.Int32Constant(0 - constant));
1485 FOR_UINT32_INPUTS(i) {
1486 FOR_UINT32_INPUTS(j) {
1487 int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
1488 CHECK_EQ(expected, bt.call(*i, *j));
1489 }
1490 }
1491 }
1492 {
1493 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494 Int32BinopTester bt(&m);
1495 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001496 m.Branch(
1497 m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1498 &blocka, &blockb);
1499 m.Bind(&blocka);
1500 bt.AddReturn(m.Int32Constant(constant));
1501 m.Bind(&blockb);
1502 bt.AddReturn(m.Int32Constant(0 - constant));
1503 FOR_UINT32_INPUTS(i) {
1504 FOR_UINT32_INPUTS(j) {
1505 int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
1506 CHECK_EQ(expected, bt.call(*i, *j));
1507 }
1508 }
1509 }
1510 {
1511 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001512 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1513 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001514 m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1515 m.Int32Constant(0)),
1516 &blocka, &blockb);
1517 m.Bind(&blocka);
1518 m.Return(m.Int32Constant(constant));
1519 m.Bind(&blockb);
1520 m.Return(m.Int32Constant(0 - constant));
1521 FOR_UINT32_INPUTS(j) {
1522 uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001523 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001524 }
1525 }
1526 }
1527 {
1528 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001529 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1530 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001531 m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1532 m.Int32Constant(0)),
1533 &blocka, &blockb);
1534 m.Bind(&blocka);
1535 m.Return(m.Int32Constant(constant));
1536 m.Bind(&blockb);
1537 m.Return(m.Int32Constant(0 - constant));
1538 FOR_UINT32_INPUTS(j) {
1539 uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001540 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001541 }
1542 }
1543 }
1544 {
1545 RawMachineAssemblerTester<void> m;
1546 const Operator* shops[] = {m.machine()->Word32Sar(),
1547 m.machine()->Word32Shl(),
1548 m.machine()->Word32Shr()};
1549 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001550 RawMachineAssemblerTester<int32_t> m(
1551 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1552 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001553 m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001554 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001555 m.Parameter(2))),
1556 m.Int32Constant(0)),
1557 &blocka, &blockb);
1558 m.Bind(&blocka);
1559 m.Return(m.Int32Constant(constant));
1560 m.Bind(&blockb);
1561 m.Return(m.Int32Constant(0 - constant));
1562 FOR_UINT32_INPUTS(i) {
1563 FOR_INT32_INPUTS(j) {
1564 FOR_UINT32_SHIFTS(shift) {
1565 int32_t right;
1566 switch (shops[n]->opcode()) {
1567 default:
1568 UNREACHABLE();
1569 case IrOpcode::kWord32Sar:
1570 right = *j >> shift;
1571 break;
1572 case IrOpcode::kWord32Shl:
1573 right = *j << shift;
1574 break;
1575 case IrOpcode::kWord32Shr:
1576 right = static_cast<uint32_t>(*j) >> shift;
1577 break;
1578 }
1579 int32_t expected = ((*i + right) == 0) ? constant : 0 - constant;
1580 CHECK_EQ(expected, m.Call(*i, *j, shift));
1581 }
1582 }
1583 }
1584 }
1585 }
1586}
1587
1588
1589TEST(RunInt32AddInComparison) {
1590 {
1591 RawMachineAssemblerTester<int32_t> m;
1592 Uint32BinopTester bt(&m);
1593 bt.AddReturn(
1594 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)));
1595 FOR_UINT32_INPUTS(i) {
1596 FOR_UINT32_INPUTS(j) {
1597 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001598 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001599 }
1600 }
1601 }
1602 {
1603 RawMachineAssemblerTester<int32_t> m;
1604 Uint32BinopTester bt(&m);
1605 bt.AddReturn(
1606 m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1)));
1607 FOR_UINT32_INPUTS(i) {
1608 FOR_UINT32_INPUTS(j) {
1609 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001610 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001611 }
1612 }
1613 }
1614 {
1615 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001617 m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1618 m.Int32Constant(0)));
1619 FOR_UINT32_INPUTS(j) {
1620 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001621 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 }
1623 }
1624 }
1625 {
1626 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001627 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001628 m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
1629 m.Int32Constant(0)));
1630 FOR_UINT32_INPUTS(j) {
1631 uint32_t expected = (*j + *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001632 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001633 }
1634 }
1635 }
1636 {
1637 RawMachineAssemblerTester<void> m;
1638 const Operator* shops[] = {m.machine()->Word32Sar(),
1639 m.machine()->Word32Shl(),
1640 m.machine()->Word32Shr()};
1641 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001642 RawMachineAssemblerTester<int32_t> m(
1643 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001644 m.Return(m.Word32Equal(
1645 m.Int32Add(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001646 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001647 m.Int32Constant(0)));
1648 FOR_UINT32_INPUTS(i) {
1649 FOR_INT32_INPUTS(j) {
1650 FOR_UINT32_SHIFTS(shift) {
1651 int32_t right;
1652 switch (shops[n]->opcode()) {
1653 default:
1654 UNREACHABLE();
1655 case IrOpcode::kWord32Sar:
1656 right = *j >> shift;
1657 break;
1658 case IrOpcode::kWord32Shl:
1659 right = *j << shift;
1660 break;
1661 case IrOpcode::kWord32Shr:
1662 right = static_cast<uint32_t>(*j) >> shift;
1663 break;
1664 }
1665 int32_t expected = (*i + right) == 0;
1666 CHECK_EQ(expected, m.Call(*i, *j, shift));
1667 }
1668 }
1669 }
1670 }
1671 }
1672}
1673
1674
1675TEST(RunInt32SubP) {
1676 RawMachineAssemblerTester<int32_t> m;
1677 Uint32BinopTester bt(&m);
1678
1679 m.Return(m.Int32Sub(bt.param0, bt.param1));
1680
1681 FOR_UINT32_INPUTS(i) {
1682 FOR_UINT32_INPUTS(j) {
1683 uint32_t expected = static_cast<int32_t>(*i - *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001684 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001685 }
1686 }
1687}
1688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689TEST(RunInt32SubImm) {
1690 {
1691 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001692 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001693 m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
1694 FOR_UINT32_INPUTS(j) {
1695 uint32_t expected = *i - *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001696 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001697 }
1698 }
1699 }
1700 {
1701 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001702 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001703 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
1704 FOR_UINT32_INPUTS(j) {
1705 uint32_t expected = *j - *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001706 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001707 }
1708 }
1709 }
1710}
1711
Ben Murdochc5610432016-08-08 18:44:38 +01001712TEST(RunInt32SubImm2) {
1713 BufferedRawMachineAssemblerTester<int32_t> r;
1714 r.Return(r.Int32Sub(r.Int32Constant(-1), r.Int32Constant(0)));
1715 CHECK_EQ(-1, r.Call());
1716}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001717
1718TEST(RunInt32SubAndWord32SarP) {
1719 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001720 RawMachineAssemblerTester<int32_t> m(
1721 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001722 m.Return(m.Int32Sub(m.Parameter(0),
1723 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1724 FOR_UINT32_INPUTS(i) {
1725 FOR_INT32_INPUTS(j) {
1726 FOR_UINT32_SHIFTS(shift) {
1727 int32_t expected = *i - (*j >> shift);
1728 CHECK_EQ(expected, m.Call(*i, *j, shift));
1729 }
1730 }
1731 }
1732 }
1733 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001734 RawMachineAssemblerTester<int32_t> m(
1735 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736 m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1737 m.Parameter(2)));
1738 FOR_INT32_INPUTS(i) {
1739 FOR_UINT32_SHIFTS(shift) {
1740 FOR_UINT32_INPUTS(k) {
1741 int32_t expected = (*i >> shift) - *k;
1742 CHECK_EQ(expected, m.Call(*i, shift, *k));
1743 }
1744 }
1745 }
1746 }
1747}
1748
1749
1750TEST(RunInt32SubAndWord32ShlP) {
1751 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001752 RawMachineAssemblerTester<int32_t> m(
1753 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001754 m.Return(m.Int32Sub(m.Parameter(0),
1755 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1756 FOR_UINT32_INPUTS(i) {
1757 FOR_INT32_INPUTS(j) {
1758 FOR_UINT32_SHIFTS(shift) {
1759 int32_t expected = *i - (*j << shift);
1760 CHECK_EQ(expected, m.Call(*i, *j, shift));
1761 }
1762 }
1763 }
1764 }
1765 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001766 RawMachineAssemblerTester<int32_t> m(
1767 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001768 m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1769 m.Parameter(2)));
1770 FOR_INT32_INPUTS(i) {
1771 FOR_UINT32_SHIFTS(shift) {
1772 FOR_UINT32_INPUTS(k) {
1773 // Use uint32_t because signed overflow is UB in C.
1774 int32_t expected = (*i << shift) - *k;
1775 CHECK_EQ(expected, m.Call(*i, shift, *k));
1776 }
1777 }
1778 }
1779 }
1780}
1781
1782
1783TEST(RunInt32SubAndWord32ShrP) {
1784 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785 RawMachineAssemblerTester<uint32_t> m(
1786 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001787 m.Return(m.Int32Sub(m.Parameter(0),
1788 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1789 FOR_UINT32_INPUTS(i) {
1790 FOR_UINT32_INPUTS(j) {
1791 FOR_UINT32_SHIFTS(shift) {
1792 // Use uint32_t because signed overflow is UB in C.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001793 uint32_t expected = *i - (*j >> shift);
1794 CHECK_EQ(expected, m.Call(*i, *j, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001795 }
1796 }
1797 }
1798 }
1799 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001800 RawMachineAssemblerTester<uint32_t> m(
1801 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001802 m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1803 m.Parameter(2)));
1804 FOR_UINT32_INPUTS(i) {
1805 FOR_UINT32_SHIFTS(shift) {
1806 FOR_UINT32_INPUTS(k) {
1807 // Use uint32_t because signed overflow is UB in C.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001808 uint32_t expected = (*i >> shift) - *k;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001809 CHECK_EQ(expected, m.Call(*i, shift, *k));
1810 }
1811 }
1812 }
1813 }
1814}
1815
1816
1817TEST(RunInt32SubInBranch) {
1818 static const int constant = 987654321;
1819 {
1820 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001821 Int32BinopTester bt(&m);
1822 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001823 m.Branch(
1824 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1825 &blocka, &blockb);
1826 m.Bind(&blocka);
1827 bt.AddReturn(m.Int32Constant(constant));
1828 m.Bind(&blockb);
1829 bt.AddReturn(m.Int32Constant(0 - constant));
1830 FOR_UINT32_INPUTS(i) {
1831 FOR_UINT32_INPUTS(j) {
1832 int32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
1833 CHECK_EQ(expected, bt.call(*i, *j));
1834 }
1835 }
1836 }
1837 {
1838 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001839 Int32BinopTester bt(&m);
1840 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001841 m.Branch(
1842 m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1843 &blocka, &blockb);
1844 m.Bind(&blocka);
1845 bt.AddReturn(m.Int32Constant(constant));
1846 m.Bind(&blockb);
1847 bt.AddReturn(m.Int32Constant(0 - constant));
1848 FOR_UINT32_INPUTS(i) {
1849 FOR_UINT32_INPUTS(j) {
1850 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1851 CHECK_EQ(expected, bt.call(*i, *j));
1852 }
1853 }
1854 }
1855 {
1856 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001857 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1858 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001859 m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1860 m.Int32Constant(0)),
1861 &blocka, &blockb);
1862 m.Bind(&blocka);
1863 m.Return(m.Int32Constant(constant));
1864 m.Bind(&blockb);
1865 m.Return(m.Int32Constant(0 - constant));
1866 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001867 uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001868 CHECK_EQ(expected, m.Call(*j));
1869 }
1870 }
1871 }
1872 {
1873 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001874 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
1875 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001876 m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1877 m.Int32Constant(0)),
1878 &blocka, &blockb);
1879 m.Bind(&blocka);
1880 m.Return(m.Int32Constant(constant));
1881 m.Bind(&blockb);
1882 m.Return(m.Int32Constant(0 - constant));
1883 FOR_UINT32_INPUTS(j) {
1884 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1885 CHECK_EQ(expected, m.Call(*j));
1886 }
1887 }
1888 }
1889 {
1890 RawMachineAssemblerTester<void> m;
1891 const Operator* shops[] = {m.machine()->Word32Sar(),
1892 m.machine()->Word32Shl(),
1893 m.machine()->Word32Shr()};
1894 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001895 RawMachineAssemblerTester<int32_t> m(
1896 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1897 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001898 m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001899 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001900 m.Parameter(2))),
1901 m.Int32Constant(0)),
1902 &blocka, &blockb);
1903 m.Bind(&blocka);
1904 m.Return(m.Int32Constant(constant));
1905 m.Bind(&blockb);
1906 m.Return(m.Int32Constant(0 - constant));
1907 FOR_UINT32_INPUTS(i) {
1908 FOR_INT32_INPUTS(j) {
1909 FOR_UINT32_SHIFTS(shift) {
1910 int32_t right;
1911 switch (shops[n]->opcode()) {
1912 default:
1913 UNREACHABLE();
1914 case IrOpcode::kWord32Sar:
1915 right = *j >> shift;
1916 break;
1917 case IrOpcode::kWord32Shl:
1918 right = *j << shift;
1919 break;
1920 case IrOpcode::kWord32Shr:
1921 right = static_cast<uint32_t>(*j) >> shift;
1922 break;
1923 }
1924 int32_t expected = ((*i - right) == 0) ? constant : 0 - constant;
1925 CHECK_EQ(expected, m.Call(*i, *j, shift));
1926 }
1927 }
1928 }
1929 }
1930 }
1931}
1932
1933
1934TEST(RunInt32SubInComparison) {
1935 {
1936 RawMachineAssemblerTester<int32_t> m;
1937 Uint32BinopTester bt(&m);
1938 bt.AddReturn(
1939 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)));
1940 FOR_UINT32_INPUTS(i) {
1941 FOR_UINT32_INPUTS(j) {
1942 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001943 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001944 }
1945 }
1946 }
1947 {
1948 RawMachineAssemblerTester<int32_t> m;
1949 Uint32BinopTester bt(&m);
1950 bt.AddReturn(
1951 m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1)));
1952 FOR_UINT32_INPUTS(i) {
1953 FOR_UINT32_INPUTS(j) {
1954 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001955 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001956 }
1957 }
1958 }
1959 {
1960 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001961 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001962 m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1963 m.Int32Constant(0)));
1964 FOR_UINT32_INPUTS(j) {
1965 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001966 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001967 }
1968 }
1969 }
1970 {
1971 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001972 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001973 m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
1974 m.Int32Constant(0)));
1975 FOR_UINT32_INPUTS(j) {
1976 uint32_t expected = (*j - *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001977 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001978 }
1979 }
1980 }
1981 {
1982 RawMachineAssemblerTester<void> m;
1983 const Operator* shops[] = {m.machine()->Word32Sar(),
1984 m.machine()->Word32Shl(),
1985 m.machine()->Word32Shr()};
1986 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001987 RawMachineAssemblerTester<int32_t> m(
1988 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001989 m.Return(m.Word32Equal(
1990 m.Int32Sub(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001991 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001992 m.Int32Constant(0)));
1993 FOR_UINT32_INPUTS(i) {
1994 FOR_INT32_INPUTS(j) {
1995 FOR_UINT32_SHIFTS(shift) {
1996 int32_t right;
1997 switch (shops[n]->opcode()) {
1998 default:
1999 UNREACHABLE();
2000 case IrOpcode::kWord32Sar:
2001 right = *j >> shift;
2002 break;
2003 case IrOpcode::kWord32Shl:
2004 right = *j << shift;
2005 break;
2006 case IrOpcode::kWord32Shr:
2007 right = static_cast<uint32_t>(*j) >> shift;
2008 break;
2009 }
2010 int32_t expected = (*i - right) == 0;
2011 CHECK_EQ(expected, m.Call(*i, *j, shift));
2012 }
2013 }
2014 }
2015 }
2016 }
2017}
2018
2019
2020TEST(RunInt32MulP) {
2021 {
2022 RawMachineAssemblerTester<int32_t> m;
2023 Int32BinopTester bt(&m);
2024 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2025 FOR_INT32_INPUTS(i) {
2026 FOR_INT32_INPUTS(j) {
2027 int expected = static_cast<int32_t>(*i * *j);
2028 CHECK_EQ(expected, bt.call(*i, *j));
2029 }
2030 }
2031 }
2032 {
2033 RawMachineAssemblerTester<int32_t> m;
2034 Uint32BinopTester bt(&m);
2035 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2036 FOR_UINT32_INPUTS(i) {
2037 FOR_UINT32_INPUTS(j) {
2038 uint32_t expected = *i * *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002039 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002040 }
2041 }
2042 }
2043}
2044
2045
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002046TEST(RunInt32MulHighP) {
2047 RawMachineAssemblerTester<int32_t> m;
2048 Int32BinopTester bt(&m);
2049 bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
2050 FOR_INT32_INPUTS(i) {
2051 FOR_INT32_INPUTS(j) {
2052 int32_t expected = static_cast<int32_t>(
2053 (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
2054 CHECK_EQ(expected, bt.call(*i, *j));
2055 }
2056 }
2057}
2058
2059
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002060TEST(RunInt32MulImm) {
2061 {
2062 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002063 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002064 m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
2065 FOR_UINT32_INPUTS(j) {
2066 uint32_t expected = *i * *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002067 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002068 }
2069 }
2070 }
2071 {
2072 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002073 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002074 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
2075 FOR_UINT32_INPUTS(j) {
2076 uint32_t expected = *j * *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002077 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002078 }
2079 }
2080 }
2081}
2082
2083
2084TEST(RunInt32MulAndInt32AddP) {
2085 {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002086 FOR_INT32_INPUTS(i) {
2087 FOR_INT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002088 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002089 int32_t p0 = *i;
2090 int32_t p1 = *j;
2091 m.Return(m.Int32Add(m.Int32Constant(p0),
2092 m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
2093 FOR_INT32_INPUTS(k) {
2094 int32_t p2 = *k;
2095 int expected = p0 + static_cast<int32_t>(p1 * p2);
2096 CHECK_EQ(expected, m.Call(p2));
2097 }
2098 }
2099 }
2100 }
2101 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002102 RawMachineAssemblerTester<int32_t> m(
2103 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002104 m.Return(
2105 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2106 FOR_INT32_INPUTS(i) {
2107 FOR_INT32_INPUTS(j) {
2108 FOR_INT32_INPUTS(k) {
2109 int32_t p0 = *i;
2110 int32_t p1 = *j;
2111 int32_t p2 = *k;
2112 int expected = p0 + static_cast<int32_t>(p1 * p2);
2113 CHECK_EQ(expected, m.Call(p0, p1, p2));
2114 }
2115 }
2116 }
2117 }
2118 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002119 RawMachineAssemblerTester<int32_t> m(
2120 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002121 m.Return(
2122 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
2123 FOR_INT32_INPUTS(i) {
2124 FOR_INT32_INPUTS(j) {
2125 FOR_INT32_INPUTS(k) {
2126 int32_t p0 = *i;
2127 int32_t p1 = *j;
2128 int32_t p2 = *k;
2129 int expected = static_cast<int32_t>(p0 * p1) + p2;
2130 CHECK_EQ(expected, m.Call(p0, p1, p2));
2131 }
2132 }
2133 }
2134 }
2135 {
2136 FOR_INT32_INPUTS(i) {
2137 RawMachineAssemblerTester<int32_t> m;
2138 Int32BinopTester bt(&m);
2139 bt.AddReturn(
2140 m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2141 FOR_INT32_INPUTS(j) {
2142 FOR_INT32_INPUTS(k) {
2143 int32_t p0 = *j;
2144 int32_t p1 = *k;
2145 int expected = *i + static_cast<int32_t>(p0 * p1);
2146 CHECK_EQ(expected, bt.call(p0, p1));
2147 }
2148 }
2149 }
2150 }
2151}
2152
2153
2154TEST(RunInt32MulAndInt32SubP) {
2155 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002156 RawMachineAssemblerTester<int32_t> m(
2157 MachineType::Uint32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002158 m.Return(
2159 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2160 FOR_UINT32_INPUTS(i) {
2161 FOR_INT32_INPUTS(j) {
2162 FOR_INT32_INPUTS(k) {
2163 uint32_t p0 = *i;
2164 int32_t p1 = *j;
2165 int32_t p2 = *k;
2166 // Use uint32_t because signed overflow is UB in C.
2167 int expected = p0 - static_cast<uint32_t>(p1 * p2);
2168 CHECK_EQ(expected, m.Call(p0, p1, p2));
2169 }
2170 }
2171 }
2172 }
2173 {
2174 FOR_UINT32_INPUTS(i) {
2175 RawMachineAssemblerTester<int32_t> m;
2176 Int32BinopTester bt(&m);
2177 bt.AddReturn(
2178 m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2179 FOR_INT32_INPUTS(j) {
2180 FOR_INT32_INPUTS(k) {
2181 int32_t p0 = *j;
2182 int32_t p1 = *k;
2183 // Use uint32_t because signed overflow is UB in C.
2184 int expected = *i - static_cast<uint32_t>(p0 * p1);
2185 CHECK_EQ(expected, bt.call(p0, p1));
2186 }
2187 }
2188 }
2189 }
2190}
2191
2192
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002193TEST(RunUint32MulHighP) {
2194 RawMachineAssemblerTester<int32_t> m;
2195 Int32BinopTester bt(&m);
2196 bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
2197 FOR_UINT32_INPUTS(i) {
2198 FOR_UINT32_INPUTS(j) {
2199 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
2200 (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
2201 CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
2202 }
2203 }
2204}
2205
2206
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002207TEST(RunInt32DivP) {
2208 {
2209 RawMachineAssemblerTester<int32_t> m;
2210 Int32BinopTester bt(&m);
2211 bt.AddReturn(m.Int32Div(bt.param0, bt.param1));
2212 FOR_INT32_INPUTS(i) {
2213 FOR_INT32_INPUTS(j) {
2214 int p0 = *i;
2215 int p1 = *j;
2216 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2217 int expected = static_cast<int32_t>(p0 / p1);
2218 CHECK_EQ(expected, bt.call(p0, p1));
2219 }
2220 }
2221 }
2222 }
2223 {
2224 RawMachineAssemblerTester<int32_t> m;
2225 Int32BinopTester bt(&m);
2226 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1)));
2227 FOR_INT32_INPUTS(i) {
2228 FOR_INT32_INPUTS(j) {
2229 int p0 = *i;
2230 int p1 = *j;
2231 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2232 int expected = static_cast<int32_t>(p0 + (p0 / p1));
2233 CHECK_EQ(expected, bt.call(p0, p1));
2234 }
2235 }
2236 }
2237 }
2238}
2239
2240
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002241TEST(RunUint32DivP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002242 {
2243 RawMachineAssemblerTester<int32_t> m;
2244 Int32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002245 bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002246 FOR_UINT32_INPUTS(i) {
2247 FOR_UINT32_INPUTS(j) {
2248 uint32_t p0 = *i;
2249 uint32_t p1 = *j;
2250 if (p1 != 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002251 int32_t expected = bit_cast<int32_t>(p0 / p1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002252 CHECK_EQ(expected, bt.call(p0, p1));
2253 }
2254 }
2255 }
2256 }
2257 {
2258 RawMachineAssemblerTester<int32_t> m;
2259 Int32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002260 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002261 FOR_UINT32_INPUTS(i) {
2262 FOR_UINT32_INPUTS(j) {
2263 uint32_t p0 = *i;
2264 uint32_t p1 = *j;
2265 if (p1 != 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002266 int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002267 CHECK_EQ(expected, bt.call(p0, p1));
2268 }
2269 }
2270 }
2271 }
2272}
2273
2274
2275TEST(RunInt32ModP) {
2276 {
2277 RawMachineAssemblerTester<int32_t> m;
2278 Int32BinopTester bt(&m);
2279 bt.AddReturn(m.Int32Mod(bt.param0, bt.param1));
2280 FOR_INT32_INPUTS(i) {
2281 FOR_INT32_INPUTS(j) {
2282 int p0 = *i;
2283 int p1 = *j;
2284 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2285 int expected = static_cast<int32_t>(p0 % p1);
2286 CHECK_EQ(expected, bt.call(p0, p1));
2287 }
2288 }
2289 }
2290 }
2291 {
2292 RawMachineAssemblerTester<int32_t> m;
2293 Int32BinopTester bt(&m);
2294 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1)));
2295 FOR_INT32_INPUTS(i) {
2296 FOR_INT32_INPUTS(j) {
2297 int p0 = *i;
2298 int p1 = *j;
2299 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2300 int expected = static_cast<int32_t>(p0 + (p0 % p1));
2301 CHECK_EQ(expected, bt.call(p0, p1));
2302 }
2303 }
2304 }
2305 }
2306}
2307
2308
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002309TEST(RunUint32ModP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002310 {
2311 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002312 Uint32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002313 bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002314 FOR_UINT32_INPUTS(i) {
2315 FOR_UINT32_INPUTS(j) {
2316 uint32_t p0 = *i;
2317 uint32_t p1 = *j;
2318 if (p1 != 0) {
2319 uint32_t expected = static_cast<uint32_t>(p0 % p1);
2320 CHECK_EQ(expected, bt.call(p0, p1));
2321 }
2322 }
2323 }
2324 }
2325 {
2326 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002327 Uint32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002328 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002329 FOR_UINT32_INPUTS(i) {
2330 FOR_UINT32_INPUTS(j) {
2331 uint32_t p0 = *i;
2332 uint32_t p1 = *j;
2333 if (p1 != 0) {
2334 uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1));
2335 CHECK_EQ(expected, bt.call(p0, p1));
2336 }
2337 }
2338 }
2339 }
2340}
2341
2342
2343TEST(RunWord32AndP) {
2344 {
2345 RawMachineAssemblerTester<int32_t> m;
2346 Int32BinopTester bt(&m);
2347 bt.AddReturn(m.Word32And(bt.param0, bt.param1));
2348 FOR_UINT32_INPUTS(i) {
2349 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002350 int32_t expected = *i & *j;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002351 CHECK_EQ(expected, bt.call(*i, *j));
2352 }
2353 }
2354 }
2355 {
2356 RawMachineAssemblerTester<int32_t> m;
2357 Int32BinopTester bt(&m);
2358 bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
2359 FOR_UINT32_INPUTS(i) {
2360 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002361 int32_t expected = *i & ~(*j);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002362 CHECK_EQ(expected, bt.call(*i, *j));
2363 }
2364 }
2365 }
2366 {
2367 RawMachineAssemblerTester<int32_t> m;
2368 Int32BinopTester bt(&m);
2369 bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
2370 FOR_UINT32_INPUTS(i) {
2371 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002372 int32_t expected = ~(*i) & *j;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002373 CHECK_EQ(expected, bt.call(*i, *j));
2374 }
2375 }
2376 }
2377}
2378
2379
2380TEST(RunWord32AndAndWord32ShlP) {
2381 {
2382 RawMachineAssemblerTester<int32_t> m;
2383 Uint32BinopTester bt(&m);
2384 bt.AddReturn(
2385 m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2386 FOR_UINT32_INPUTS(i) {
2387 FOR_UINT32_INPUTS(j) {
2388 uint32_t expected = *i << (*j & 0x1f);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002389 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002390 }
2391 }
2392 }
2393 {
2394 RawMachineAssemblerTester<int32_t> m;
2395 Uint32BinopTester bt(&m);
2396 bt.AddReturn(
2397 m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2398 FOR_UINT32_INPUTS(i) {
2399 FOR_UINT32_INPUTS(j) {
2400 uint32_t expected = *i << (0x1f & *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002401 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002402 }
2403 }
2404 }
2405}
2406
2407
2408TEST(RunWord32AndAndWord32ShrP) {
2409 {
2410 RawMachineAssemblerTester<int32_t> m;
2411 Uint32BinopTester bt(&m);
2412 bt.AddReturn(
2413 m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2414 FOR_UINT32_INPUTS(i) {
2415 FOR_UINT32_INPUTS(j) {
2416 uint32_t expected = *i >> (*j & 0x1f);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002417 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002418 }
2419 }
2420 }
2421 {
2422 RawMachineAssemblerTester<int32_t> m;
2423 Uint32BinopTester bt(&m);
2424 bt.AddReturn(
2425 m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2426 FOR_UINT32_INPUTS(i) {
2427 FOR_UINT32_INPUTS(j) {
2428 uint32_t expected = *i >> (0x1f & *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002430 }
2431 }
2432 }
2433}
2434
2435
2436TEST(RunWord32AndAndWord32SarP) {
2437 {
2438 RawMachineAssemblerTester<int32_t> m;
2439 Int32BinopTester bt(&m);
2440 bt.AddReturn(
2441 m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2442 FOR_INT32_INPUTS(i) {
2443 FOR_INT32_INPUTS(j) {
2444 int32_t expected = *i >> (*j & 0x1f);
2445 CHECK_EQ(expected, bt.call(*i, *j));
2446 }
2447 }
2448 }
2449 {
2450 RawMachineAssemblerTester<int32_t> m;
2451 Int32BinopTester bt(&m);
2452 bt.AddReturn(
2453 m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2454 FOR_INT32_INPUTS(i) {
2455 FOR_INT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002456 int32_t expected = *i >> (0x1f & *j);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002457 CHECK_EQ(expected, bt.call(*i, *j));
2458 }
2459 }
2460 }
2461}
2462
2463
2464TEST(RunWord32AndImm) {
2465 {
2466 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002467 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002468 m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
2469 FOR_UINT32_INPUTS(j) {
2470 uint32_t expected = *i & *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002471 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002472 }
2473 }
2474 }
2475 {
2476 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002477 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002478 m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2479 FOR_UINT32_INPUTS(j) {
2480 uint32_t expected = *i & ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002481 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002482 }
2483 }
2484 }
2485}
2486
2487
2488TEST(RunWord32AndInBranch) {
2489 static const int constant = 987654321;
2490 {
2491 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002492 Int32BinopTester bt(&m);
2493 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002494 m.Branch(
2495 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
2496 &blocka, &blockb);
2497 m.Bind(&blocka);
2498 bt.AddReturn(m.Int32Constant(constant));
2499 m.Bind(&blockb);
2500 bt.AddReturn(m.Int32Constant(0 - constant));
2501 FOR_UINT32_INPUTS(i) {
2502 FOR_UINT32_INPUTS(j) {
2503 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
2504 CHECK_EQ(expected, bt.call(*i, *j));
2505 }
2506 }
2507 }
2508 {
2509 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002510 Int32BinopTester bt(&m);
2511 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002512 m.Branch(
2513 m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
2514 &blocka, &blockb);
2515 m.Bind(&blocka);
2516 bt.AddReturn(m.Int32Constant(constant));
2517 m.Bind(&blockb);
2518 bt.AddReturn(m.Int32Constant(0 - constant));
2519 FOR_UINT32_INPUTS(i) {
2520 FOR_UINT32_INPUTS(j) {
2521 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2522 CHECK_EQ(expected, bt.call(*i, *j));
2523 }
2524 }
2525 }
2526 {
2527 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002528 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2529 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002530 m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2531 m.Int32Constant(0)),
2532 &blocka, &blockb);
2533 m.Bind(&blocka);
2534 m.Return(m.Int32Constant(constant));
2535 m.Bind(&blockb);
2536 m.Return(m.Int32Constant(0 - constant));
2537 FOR_UINT32_INPUTS(j) {
2538 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant;
2539 CHECK_EQ(expected, m.Call(*j));
2540 }
2541 }
2542 }
2543 {
2544 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002545 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2546 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002547 m.Branch(
2548 m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2549 m.Int32Constant(0)),
2550 &blocka, &blockb);
2551 m.Bind(&blocka);
2552 m.Return(m.Int32Constant(constant));
2553 m.Bind(&blockb);
2554 m.Return(m.Int32Constant(0 - constant));
2555 FOR_UINT32_INPUTS(j) {
2556 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2557 CHECK_EQ(expected, m.Call(*j));
2558 }
2559 }
2560 }
2561 {
2562 RawMachineAssemblerTester<void> m;
2563 const Operator* shops[] = {m.machine()->Word32Sar(),
2564 m.machine()->Word32Shl(),
2565 m.machine()->Word32Shr()};
2566 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002567 RawMachineAssemblerTester<int32_t> m(
2568 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2569 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002570 m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002571 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002572 m.Parameter(2))),
2573 m.Int32Constant(0)),
2574 &blocka, &blockb);
2575 m.Bind(&blocka);
2576 m.Return(m.Int32Constant(constant));
2577 m.Bind(&blockb);
2578 m.Return(m.Int32Constant(0 - constant));
2579 FOR_UINT32_INPUTS(i) {
2580 FOR_INT32_INPUTS(j) {
2581 FOR_UINT32_SHIFTS(shift) {
2582 int32_t right;
2583 switch (shops[n]->opcode()) {
2584 default:
2585 UNREACHABLE();
2586 case IrOpcode::kWord32Sar:
2587 right = *j >> shift;
2588 break;
2589 case IrOpcode::kWord32Shl:
2590 right = *j << shift;
2591 break;
2592 case IrOpcode::kWord32Shr:
2593 right = static_cast<uint32_t>(*j) >> shift;
2594 break;
2595 }
2596 int32_t expected = ((*i & right) == 0) ? constant : 0 - constant;
2597 CHECK_EQ(expected, m.Call(*i, *j, shift));
2598 }
2599 }
2600 }
2601 }
2602 }
2603}
2604
2605
2606TEST(RunWord32AndInComparison) {
2607 {
2608 RawMachineAssemblerTester<int32_t> m;
2609 Uint32BinopTester bt(&m);
2610 bt.AddReturn(
2611 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)));
2612 FOR_UINT32_INPUTS(i) {
2613 FOR_UINT32_INPUTS(j) {
2614 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002615 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002616 }
2617 }
2618 }
2619 {
2620 RawMachineAssemblerTester<int32_t> m;
2621 Uint32BinopTester bt(&m);
2622 bt.AddReturn(
2623 m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1)));
2624 FOR_UINT32_INPUTS(i) {
2625 FOR_UINT32_INPUTS(j) {
2626 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002627 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002628 }
2629 }
2630 }
2631 {
2632 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002633 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002634 m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2635 m.Int32Constant(0)));
2636 FOR_UINT32_INPUTS(j) {
2637 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002638 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002639 }
2640 }
2641 }
2642 {
2643 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002644 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002645 m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
2646 m.Int32Constant(0)));
2647 FOR_UINT32_INPUTS(j) {
2648 uint32_t expected = (*j & *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002649 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002650 }
2651 }
2652 }
2653}
2654
2655
2656TEST(RunWord32OrP) {
2657 {
2658 RawMachineAssemblerTester<int32_t> m;
2659 Uint32BinopTester bt(&m);
2660 bt.AddReturn(m.Word32Or(bt.param0, bt.param1));
2661 FOR_UINT32_INPUTS(i) {
2662 FOR_UINT32_INPUTS(j) {
2663 uint32_t expected = *i | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002664 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665 }
2666 }
2667 }
2668 {
2669 RawMachineAssemblerTester<int32_t> m;
2670 Uint32BinopTester bt(&m);
2671 bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1)));
2672 FOR_UINT32_INPUTS(i) {
2673 FOR_UINT32_INPUTS(j) {
2674 uint32_t expected = *i | ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002675 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002676 }
2677 }
2678 }
2679 {
2680 RawMachineAssemblerTester<int32_t> m;
2681 Uint32BinopTester bt(&m);
2682 bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1));
2683 FOR_UINT32_INPUTS(i) {
2684 FOR_UINT32_INPUTS(j) {
2685 uint32_t expected = ~(*i) | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002686 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002687 }
2688 }
2689 }
2690}
2691
2692
2693TEST(RunWord32OrImm) {
2694 {
2695 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002696 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002697 m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
2698 FOR_UINT32_INPUTS(j) {
2699 uint32_t expected = *i | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002700 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002701 }
2702 }
2703 }
2704 {
2705 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002706 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002707 m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2708 FOR_UINT32_INPUTS(j) {
2709 uint32_t expected = *i | ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002710 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002711 }
2712 }
2713 }
2714}
2715
2716
2717TEST(RunWord32OrInBranch) {
2718 static const int constant = 987654321;
2719 {
2720 RawMachineAssemblerTester<int32_t> m;
2721 Int32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002722 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002723 m.Branch(
2724 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2725 &blocka, &blockb);
2726 m.Bind(&blocka);
2727 bt.AddReturn(m.Int32Constant(constant));
2728 m.Bind(&blockb);
2729 bt.AddReturn(m.Int32Constant(0 - constant));
2730 FOR_INT32_INPUTS(i) {
2731 FOR_INT32_INPUTS(j) {
2732 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2733 CHECK_EQ(expected, bt.call(*i, *j));
2734 }
2735 }
2736 }
2737 {
2738 RawMachineAssemblerTester<int32_t> m;
2739 Int32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002740 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002741 m.Branch(
2742 m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2743 &blocka, &blockb);
2744 m.Bind(&blocka);
2745 bt.AddReturn(m.Int32Constant(constant));
2746 m.Bind(&blockb);
2747 bt.AddReturn(m.Int32Constant(0 - constant));
2748 FOR_INT32_INPUTS(i) {
2749 FOR_INT32_INPUTS(j) {
2750 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2751 CHECK_EQ(expected, bt.call(*i, *j));
2752 }
2753 }
2754 }
2755 {
2756 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002757 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2758 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002759 m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2760 m.Int32Constant(0)),
2761 &blocka, &blockb);
2762 m.Bind(&blocka);
2763 m.Return(m.Int32Constant(constant));
2764 m.Bind(&blockb);
2765 m.Return(m.Int32Constant(0 - constant));
2766 FOR_INT32_INPUTS(j) {
2767 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2768 CHECK_EQ(expected, m.Call(*j));
2769 }
2770 }
2771 }
2772 {
2773 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002774 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2775 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002776 m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2777 m.Int32Constant(0)),
2778 &blocka, &blockb);
2779 m.Bind(&blocka);
2780 m.Return(m.Int32Constant(constant));
2781 m.Bind(&blockb);
2782 m.Return(m.Int32Constant(0 - constant));
2783 FOR_INT32_INPUTS(j) {
2784 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2785 CHECK_EQ(expected, m.Call(*j));
2786 }
2787 }
2788 }
2789 {
2790 RawMachineAssemblerTester<void> m;
2791 const Operator* shops[] = {m.machine()->Word32Sar(),
2792 m.machine()->Word32Shl(),
2793 m.machine()->Word32Shr()};
2794 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002795 RawMachineAssemblerTester<int32_t> m(
2796 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2797 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002798 m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002799 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002800 m.Parameter(2))),
2801 m.Int32Constant(0)),
2802 &blocka, &blockb);
2803 m.Bind(&blocka);
2804 m.Return(m.Int32Constant(constant));
2805 m.Bind(&blockb);
2806 m.Return(m.Int32Constant(0 - constant));
2807 FOR_UINT32_INPUTS(i) {
2808 FOR_INT32_INPUTS(j) {
2809 FOR_UINT32_SHIFTS(shift) {
2810 int32_t right;
2811 switch (shops[n]->opcode()) {
2812 default:
2813 UNREACHABLE();
2814 case IrOpcode::kWord32Sar:
2815 right = *j >> shift;
2816 break;
2817 case IrOpcode::kWord32Shl:
2818 right = *j << shift;
2819 break;
2820 case IrOpcode::kWord32Shr:
2821 right = static_cast<uint32_t>(*j) >> shift;
2822 break;
2823 }
2824 int32_t expected = ((*i | right) == 0) ? constant : 0 - constant;
2825 CHECK_EQ(expected, m.Call(*i, *j, shift));
2826 }
2827 }
2828 }
2829 }
2830 }
2831}
2832
2833
2834TEST(RunWord32OrInComparison) {
2835 {
2836 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002837 Int32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002838 bt.AddReturn(
2839 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
2840 FOR_UINT32_INPUTS(i) {
2841 FOR_UINT32_INPUTS(j) {
2842 int32_t expected = (*i | *j) == 0;
2843 CHECK_EQ(expected, bt.call(*i, *j));
2844 }
2845 }
2846 }
2847 {
2848 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002849 Int32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002850 bt.AddReturn(
2851 m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
2852 FOR_UINT32_INPUTS(i) {
2853 FOR_UINT32_INPUTS(j) {
2854 int32_t expected = (*i | *j) == 0;
2855 CHECK_EQ(expected, bt.call(*i, *j));
2856 }
2857 }
2858 }
2859 {
2860 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002861 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002862 m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2863 m.Int32Constant(0)));
2864 FOR_UINT32_INPUTS(j) {
2865 uint32_t expected = (*i | *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002866 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002867 }
2868 }
2869 }
2870 {
2871 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002872 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002873 m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
2874 m.Int32Constant(0)));
2875 FOR_UINT32_INPUTS(j) {
2876 uint32_t expected = (*j | *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002877 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002878 }
2879 }
2880 }
2881}
2882
2883
2884TEST(RunWord32XorP) {
2885 {
2886 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002887 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002888 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
2889 FOR_UINT32_INPUTS(j) {
2890 uint32_t expected = *i ^ *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002891 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002892 }
2893 }
2894 }
2895 {
2896 RawMachineAssemblerTester<int32_t> m;
2897 Uint32BinopTester bt(&m);
2898 bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
2899 FOR_UINT32_INPUTS(i) {
2900 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002901 uint32_t expected = *i ^ *j;
2902 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002903 }
2904 }
2905 }
2906 {
2907 RawMachineAssemblerTester<int32_t> m;
2908 Int32BinopTester bt(&m);
2909 bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1)));
2910 FOR_INT32_INPUTS(i) {
2911 FOR_INT32_INPUTS(j) {
2912 int32_t expected = *i ^ ~(*j);
2913 CHECK_EQ(expected, bt.call(*i, *j));
2914 }
2915 }
2916 }
2917 {
2918 RawMachineAssemblerTester<int32_t> m;
2919 Int32BinopTester bt(&m);
2920 bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1));
2921 FOR_INT32_INPUTS(i) {
2922 FOR_INT32_INPUTS(j) {
2923 int32_t expected = ~(*i) ^ *j;
2924 CHECK_EQ(expected, bt.call(*i, *j));
2925 }
2926 }
2927 }
2928 {
2929 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002930 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002931 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2932 FOR_UINT32_INPUTS(j) {
2933 uint32_t expected = *i ^ ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002934 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002935 }
2936 }
2937 }
2938}
2939
2940
2941TEST(RunWord32XorInBranch) {
2942 static const uint32_t constant = 987654321;
2943 {
2944 RawMachineAssemblerTester<int32_t> m;
2945 Uint32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002946 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002947 m.Branch(
2948 m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2949 &blocka, &blockb);
2950 m.Bind(&blocka);
2951 bt.AddReturn(m.Int32Constant(constant));
2952 m.Bind(&blockb);
2953 bt.AddReturn(m.Int32Constant(0 - constant));
2954 FOR_UINT32_INPUTS(i) {
2955 FOR_UINT32_INPUTS(j) {
2956 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002957 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002958 }
2959 }
2960 }
2961 {
2962 RawMachineAssemblerTester<int32_t> m;
2963 Uint32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002964 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002965 m.Branch(
2966 m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2967 &blocka, &blockb);
2968 m.Bind(&blocka);
2969 bt.AddReturn(m.Int32Constant(constant));
2970 m.Bind(&blockb);
2971 bt.AddReturn(m.Int32Constant(0 - constant));
2972 FOR_UINT32_INPUTS(i) {
2973 FOR_UINT32_INPUTS(j) {
2974 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002975 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002976 }
2977 }
2978 }
2979 {
2980 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002981 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2982 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002983 m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
2984 m.Int32Constant(0)),
2985 &blocka, &blockb);
2986 m.Bind(&blocka);
2987 m.Return(m.Int32Constant(constant));
2988 m.Bind(&blockb);
2989 m.Return(m.Int32Constant(0 - constant));
2990 FOR_UINT32_INPUTS(j) {
2991 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002992 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002993 }
2994 }
2995 }
2996 {
2997 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002998 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
2999 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003000 m.Branch(
3001 m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
3002 m.Int32Constant(0)),
3003 &blocka, &blockb);
3004 m.Bind(&blocka);
3005 m.Return(m.Int32Constant(constant));
3006 m.Bind(&blockb);
3007 m.Return(m.Int32Constant(0 - constant));
3008 FOR_UINT32_INPUTS(j) {
3009 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003010 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003011 }
3012 }
3013 }
3014 {
3015 RawMachineAssemblerTester<void> m;
3016 const Operator* shops[] = {m.machine()->Word32Sar(),
3017 m.machine()->Word32Shl(),
3018 m.machine()->Word32Shr()};
3019 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003020 RawMachineAssemblerTester<int32_t> m(
3021 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
3022 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003023 m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003024 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003025 m.Parameter(2))),
3026 m.Int32Constant(0)),
3027 &blocka, &blockb);
3028 m.Bind(&blocka);
3029 m.Return(m.Int32Constant(constant));
3030 m.Bind(&blockb);
3031 m.Return(m.Int32Constant(0 - constant));
3032 FOR_UINT32_INPUTS(i) {
3033 FOR_INT32_INPUTS(j) {
3034 FOR_UINT32_SHIFTS(shift) {
3035 int32_t right;
3036 switch (shops[n]->opcode()) {
3037 default:
3038 UNREACHABLE();
3039 case IrOpcode::kWord32Sar:
3040 right = *j >> shift;
3041 break;
3042 case IrOpcode::kWord32Shl:
3043 right = *j << shift;
3044 break;
3045 case IrOpcode::kWord32Shr:
3046 right = static_cast<uint32_t>(*j) >> shift;
3047 break;
3048 }
3049 int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant;
3050 CHECK_EQ(expected, m.Call(*i, *j, shift));
3051 }
3052 }
3053 }
3054 }
3055 }
3056}
3057
3058
3059TEST(RunWord32ShlP) {
3060 {
3061 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003062 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003063 m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
3064 FOR_UINT32_INPUTS(j) {
3065 uint32_t expected = *j << shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003066 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003067 }
3068 }
3069 }
3070 {
3071 RawMachineAssemblerTester<int32_t> m;
3072 Uint32BinopTester bt(&m);
3073 bt.AddReturn(m.Word32Shl(bt.param0, bt.param1));
3074 FOR_UINT32_INPUTS(i) {
3075 FOR_UINT32_SHIFTS(shift) {
3076 uint32_t expected = *i << shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003077 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003078 }
3079 }
3080 }
3081}
3082
3083
3084TEST(RunWord32ShlInComparison) {
3085 {
3086 RawMachineAssemblerTester<int32_t> m;
3087 Uint32BinopTester bt(&m);
3088 bt.AddReturn(
3089 m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0)));
3090 FOR_UINT32_INPUTS(i) {
3091 FOR_UINT32_SHIFTS(shift) {
3092 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003093 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003094 }
3095 }
3096 }
3097 {
3098 RawMachineAssemblerTester<int32_t> m;
3099 Uint32BinopTester bt(&m);
3100 bt.AddReturn(
3101 m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1)));
3102 FOR_UINT32_INPUTS(i) {
3103 FOR_UINT32_SHIFTS(shift) {
3104 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003105 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003106 }
3107 }
3108 }
3109 {
3110 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003111 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003112 m.Return(
3113 m.Word32Equal(m.Int32Constant(0),
3114 m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))));
3115 FOR_UINT32_INPUTS(i) {
3116 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003117 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003118 }
3119 }
3120 }
3121 {
3122 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003123 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003124 m.Return(
3125 m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)),
3126 m.Int32Constant(0)));
3127 FOR_UINT32_INPUTS(i) {
3128 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003129 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003130 }
3131 }
3132 }
3133}
3134
3135
3136TEST(RunWord32ShrP) {
3137 {
3138 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003139 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003140 m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
3141 FOR_UINT32_INPUTS(j) {
3142 uint32_t expected = *j >> shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003143 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003144 }
3145 }
3146 }
3147 {
3148 RawMachineAssemblerTester<int32_t> m;
3149 Uint32BinopTester bt(&m);
3150 bt.AddReturn(m.Word32Shr(bt.param0, bt.param1));
3151 FOR_UINT32_INPUTS(i) {
3152 FOR_UINT32_SHIFTS(shift) {
3153 uint32_t expected = *i >> shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003154 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003155 }
3156 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003157 CHECK_EQ(0x00010000u, bt.call(0x80000000, 15));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003158 }
3159}
3160
3161
3162TEST(RunWord32ShrInComparison) {
3163 {
3164 RawMachineAssemblerTester<int32_t> m;
3165 Uint32BinopTester bt(&m);
3166 bt.AddReturn(
3167 m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0)));
3168 FOR_UINT32_INPUTS(i) {
3169 FOR_UINT32_SHIFTS(shift) {
3170 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003171 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003172 }
3173 }
3174 }
3175 {
3176 RawMachineAssemblerTester<int32_t> m;
3177 Uint32BinopTester bt(&m);
3178 bt.AddReturn(
3179 m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1)));
3180 FOR_UINT32_INPUTS(i) {
3181 FOR_UINT32_SHIFTS(shift) {
3182 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003183 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003184 }
3185 }
3186 }
3187 {
3188 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003189 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003190 m.Return(
3191 m.Word32Equal(m.Int32Constant(0),
3192 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
3193 FOR_UINT32_INPUTS(i) {
3194 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003195 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003196 }
3197 }
3198 }
3199 {
3200 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003201 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003202 m.Return(
3203 m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
3204 m.Int32Constant(0)));
3205 FOR_UINT32_INPUTS(i) {
3206 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003207 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208 }
3209 }
3210 }
3211}
3212
3213
3214TEST(RunWord32SarP) {
3215 {
3216 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003217 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003218 m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
3219 FOR_INT32_INPUTS(j) {
3220 int32_t expected = *j >> shift;
3221 CHECK_EQ(expected, m.Call(*j));
3222 }
3223 }
3224 }
3225 {
3226 RawMachineAssemblerTester<int32_t> m;
3227 Int32BinopTester bt(&m);
3228 bt.AddReturn(m.Word32Sar(bt.param0, bt.param1));
3229 FOR_INT32_INPUTS(i) {
3230 FOR_INT32_SHIFTS(shift) {
3231 int32_t expected = *i >> shift;
3232 CHECK_EQ(expected, bt.call(*i, shift));
3233 }
3234 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003235 CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003236 }
3237}
3238
3239
3240TEST(RunWord32SarInComparison) {
3241 {
3242 RawMachineAssemblerTester<int32_t> m;
3243 Int32BinopTester bt(&m);
3244 bt.AddReturn(
3245 m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0)));
3246 FOR_INT32_INPUTS(i) {
3247 FOR_INT32_SHIFTS(shift) {
3248 int32_t expected = 0 == (*i >> shift);
3249 CHECK_EQ(expected, bt.call(*i, shift));
3250 }
3251 }
3252 }
3253 {
3254 RawMachineAssemblerTester<int32_t> m;
3255 Int32BinopTester bt(&m);
3256 bt.AddReturn(
3257 m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1)));
3258 FOR_INT32_INPUTS(i) {
3259 FOR_INT32_SHIFTS(shift) {
3260 int32_t expected = 0 == (*i >> shift);
3261 CHECK_EQ(expected, bt.call(*i, shift));
3262 }
3263 }
3264 }
3265 {
3266 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003267 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003268 m.Return(
3269 m.Word32Equal(m.Int32Constant(0),
3270 m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))));
3271 FOR_INT32_INPUTS(i) {
3272 int32_t expected = 0 == (*i >> shift);
3273 CHECK_EQ(expected, m.Call(*i));
3274 }
3275 }
3276 }
3277 {
3278 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003279 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003280 m.Return(
3281 m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)),
3282 m.Int32Constant(0)));
3283 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003284 int32_t expected = 0 == (*i >> shift);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003285 CHECK_EQ(expected, m.Call(*i));
3286 }
3287 }
3288 }
3289}
3290
3291
3292TEST(RunWord32RorP) {
3293 {
3294 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003295 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003296 m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)));
3297 FOR_UINT32_INPUTS(j) {
3298 int32_t expected = bits::RotateRight32(*j, shift);
3299 CHECK_EQ(expected, m.Call(*j));
3300 }
3301 }
3302 }
3303 {
3304 RawMachineAssemblerTester<int32_t> m;
3305 Uint32BinopTester bt(&m);
3306 bt.AddReturn(m.Word32Ror(bt.param0, bt.param1));
3307 FOR_UINT32_INPUTS(i) {
3308 FOR_UINT32_SHIFTS(shift) {
3309 uint32_t expected = bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003310 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003311 }
3312 }
3313 }
3314}
3315
3316
3317TEST(RunWord32RorInComparison) {
3318 {
3319 RawMachineAssemblerTester<int32_t> m;
3320 Uint32BinopTester bt(&m);
3321 bt.AddReturn(
3322 m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0)));
3323 FOR_UINT32_INPUTS(i) {
3324 FOR_UINT32_SHIFTS(shift) {
3325 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003326 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003327 }
3328 }
3329 }
3330 {
3331 RawMachineAssemblerTester<int32_t> m;
3332 Uint32BinopTester bt(&m);
3333 bt.AddReturn(
3334 m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1)));
3335 FOR_UINT32_INPUTS(i) {
3336 FOR_UINT32_SHIFTS(shift) {
3337 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003338 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003339 }
3340 }
3341 }
3342 {
3343 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003344 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003345 m.Return(
3346 m.Word32Equal(m.Int32Constant(0),
3347 m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))));
3348 FOR_UINT32_INPUTS(i) {
3349 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003350 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003351 }
3352 }
3353 }
3354 {
3355 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003356 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003357 m.Return(
3358 m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)),
3359 m.Int32Constant(0)));
3360 FOR_UINT32_INPUTS(i) {
3361 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003362 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 }
3364 }
3365 }
3366}
3367
3368
3369TEST(RunWord32NotP) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003370 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003371 m.Return(m.Word32Not(m.Parameter(0)));
3372 FOR_INT32_INPUTS(i) {
3373 int expected = ~(*i);
3374 CHECK_EQ(expected, m.Call(*i));
3375 }
3376}
3377
3378
3379TEST(RunInt32NegP) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003380 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003381 m.Return(m.Int32Neg(m.Parameter(0)));
3382 FOR_INT32_INPUTS(i) {
3383 int expected = -*i;
3384 CHECK_EQ(expected, m.Call(*i));
3385 }
3386}
3387
3388
3389TEST(RunWord32EqualAndWord32SarP) {
3390 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003391 RawMachineAssemblerTester<int32_t> m(
3392 MachineType::Int32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003393 m.Return(m.Word32Equal(m.Parameter(0),
3394 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
3395 FOR_INT32_INPUTS(i) {
3396 FOR_INT32_INPUTS(j) {
3397 FOR_UINT32_SHIFTS(shift) {
3398 int32_t expected = (*i == (*j >> shift));
3399 CHECK_EQ(expected, m.Call(*i, *j, shift));
3400 }
3401 }
3402 }
3403 }
3404 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003405 RawMachineAssemblerTester<int32_t> m(
3406 MachineType::Int32(), MachineType::Uint32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003407 m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
3408 m.Parameter(2)));
3409 FOR_INT32_INPUTS(i) {
3410 FOR_UINT32_SHIFTS(shift) {
3411 FOR_INT32_INPUTS(k) {
3412 int32_t expected = ((*i >> shift) == *k);
3413 CHECK_EQ(expected, m.Call(*i, shift, *k));
3414 }
3415 }
3416 }
3417 }
3418}
3419
3420
3421TEST(RunWord32EqualAndWord32ShlP) {
3422 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003423 RawMachineAssemblerTester<int32_t> m(
3424 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003425 m.Return(m.Word32Equal(m.Parameter(0),
3426 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
3427 FOR_UINT32_INPUTS(i) {
3428 FOR_UINT32_INPUTS(j) {
3429 FOR_UINT32_SHIFTS(shift) {
3430 int32_t expected = (*i == (*j << shift));
3431 CHECK_EQ(expected, m.Call(*i, *j, shift));
3432 }
3433 }
3434 }
3435 }
3436 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003437 RawMachineAssemblerTester<int32_t> m(
3438 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003439 m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
3440 m.Parameter(2)));
3441 FOR_UINT32_INPUTS(i) {
3442 FOR_UINT32_SHIFTS(shift) {
3443 FOR_UINT32_INPUTS(k) {
3444 int32_t expected = ((*i << shift) == *k);
3445 CHECK_EQ(expected, m.Call(*i, shift, *k));
3446 }
3447 }
3448 }
3449 }
3450}
3451
3452
3453TEST(RunWord32EqualAndWord32ShrP) {
3454 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003455 RawMachineAssemblerTester<int32_t> m(
3456 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003457 m.Return(m.Word32Equal(m.Parameter(0),
3458 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
3459 FOR_UINT32_INPUTS(i) {
3460 FOR_UINT32_INPUTS(j) {
3461 FOR_UINT32_SHIFTS(shift) {
3462 int32_t expected = (*i == (*j >> shift));
3463 CHECK_EQ(expected, m.Call(*i, *j, shift));
3464 }
3465 }
3466 }
3467 }
3468 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003469 RawMachineAssemblerTester<int32_t> m(
3470 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003471 m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
3472 m.Parameter(2)));
3473 FOR_UINT32_INPUTS(i) {
3474 FOR_UINT32_SHIFTS(shift) {
3475 FOR_UINT32_INPUTS(k) {
3476 int32_t expected = ((*i >> shift) == *k);
3477 CHECK_EQ(expected, m.Call(*i, shift, *k));
3478 }
3479 }
3480 }
3481 }
3482}
3483
3484
3485TEST(RunDeadNodes) {
3486 for (int i = 0; true; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003487 RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32()
3488 : MachineType::None());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003489 int constant = 0x55 + i;
3490 switch (i) {
3491 case 0:
3492 m.Int32Constant(44);
3493 break;
3494 case 1:
3495 m.StringConstant("unused");
3496 break;
3497 case 2:
3498 m.NumberConstant(11.1);
3499 break;
3500 case 3:
3501 m.PointerConstant(&constant);
3502 break;
3503 case 4:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003504 m.LoadFromPointer(&constant, MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003505 break;
3506 case 5:
3507 m.Parameter(0);
3508 break;
3509 default:
3510 return;
3511 }
3512 m.Return(m.Int32Constant(constant));
3513 if (i != 5) {
3514 CHECK_EQ(constant, m.Call());
3515 } else {
3516 CHECK_EQ(constant, m.Call(0));
3517 }
3518 }
3519}
3520
3521
3522TEST(RunDeadInt32Binops) {
3523 RawMachineAssemblerTester<int32_t> m;
3524
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003525 const Operator* kOps[] = {
3526 m.machine()->Word32And(), m.machine()->Word32Or(),
3527 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
3528 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
3529 m.machine()->Word32Ror(), m.machine()->Word32Equal(),
3530 m.machine()->Int32Add(), m.machine()->Int32Sub(),
3531 m.machine()->Int32Mul(), m.machine()->Int32MulHigh(),
3532 m.machine()->Int32Div(), m.machine()->Uint32Div(),
3533 m.machine()->Int32Mod(), m.machine()->Uint32Mod(),
3534 m.machine()->Uint32MulHigh(), m.machine()->Int32LessThan(),
3535 m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
3536 m.machine()->Uint32LessThanOrEqual()};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003537
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003538 for (size_t i = 0; i < arraysize(kOps); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003539 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
3540 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003541 int32_t constant = static_cast<int32_t>(0x55555 + i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003542 m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003543 m.Return(m.Int32Constant(constant));
3544
3545 CHECK_EQ(constant, m.Call(1, 1));
3546 }
3547}
3548
3549
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003550TEST(RunFloat32Add) {
3551 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3552 MachineType::Float32());
3553 m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1)));
3554
3555 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003556 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i + *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003557 }
3558}
3559
3560
3561TEST(RunFloat32Sub) {
3562 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3563 MachineType::Float32());
3564 m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1)));
3565
3566 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003567 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003568 }
3569}
3570
3571
3572TEST(RunFloat32Mul) {
3573 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3574 MachineType::Float32());
3575 m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1)));
3576
3577 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003578 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i * *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003579 }
3580}
3581
3582
3583TEST(RunFloat32Div) {
3584 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3585 MachineType::Float32());
3586 m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1)));
3587
3588 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003589 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i / *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003590 }
3591}
3592
3593
3594TEST(RunFloat64Add) {
3595 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3596 MachineType::Float64());
3597 m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1)));
3598
3599 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003600 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i + *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003601 }
3602}
3603
3604
3605TEST(RunFloat64Sub) {
3606 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3607 MachineType::Float64());
3608 m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1)));
3609
3610 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003611 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i - *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003612 }
3613}
3614
3615
3616TEST(RunFloat64Mul) {
3617 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3618 MachineType::Float64());
3619 m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1)));
3620
3621 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003622 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i * *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003623 }
3624}
3625
3626
3627TEST(RunFloat64Div) {
3628 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3629 MachineType::Float64());
3630 m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1)));
3631
3632 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003633 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i / *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003634 }
3635}
3636
3637
3638TEST(RunFloat64Mod) {
3639 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3640 MachineType::Float64());
3641 m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
3642
3643 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003644 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003645 }
3646}
3647
3648
3649TEST(RunDeadFloat32Binops) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003650 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003651
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003652 const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(),
3653 m.machine()->Float32Mul(), m.machine()->Float32Div(),
3654 NULL};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003655
3656 for (int i = 0; ops[i] != NULL; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003657 RawMachineAssemblerTester<int32_t> m;
3658 int constant = 0x53355 + i;
3659 m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f));
3660 m.Return(m.Int32Constant(constant));
3661 CHECK_EQ(constant, m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003662 }
3663}
3664
3665
3666TEST(RunDeadFloat64Binops) {
3667 RawMachineAssemblerTester<int32_t> m;
3668
3669 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3670 m.machine()->Float64Mul(), m.machine()->Float64Div(),
3671 m.machine()->Float64Mod(), NULL};
3672
3673 for (int i = 0; ops[i] != NULL; i++) {
3674 RawMachineAssemblerTester<int32_t> m;
3675 int constant = 0x53355 + i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003676 m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003677 m.Return(m.Int32Constant(constant));
3678 CHECK_EQ(constant, m.Call());
3679 }
3680}
3681
3682
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003683TEST(RunFloat32AddP) {
3684 RawMachineAssemblerTester<int32_t> m;
3685 Float32BinopTester bt(&m);
3686
3687 bt.AddReturn(m.Float32Add(bt.param0, bt.param1));
3688
3689 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003690 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl + *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003691 }
3692}
3693
3694
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003695TEST(RunFloat64AddP) {
3696 RawMachineAssemblerTester<int32_t> m;
3697 Float64BinopTester bt(&m);
3698
3699 bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
3700
3701 FOR_FLOAT64_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003702 FOR_FLOAT64_INPUTS(pr) { CHECK_DOUBLE_EQ(*pl + *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003703 }
3704}
3705
3706
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003707TEST(RunFloa32MaxP) {
3708 RawMachineAssemblerTester<int32_t> m;
3709 Float32BinopTester bt(&m);
3710 if (!m.machine()->Float32Max().IsSupported()) return;
3711
3712 bt.AddReturn(m.Float32Max(bt.param0, bt.param1));
3713
3714 FOR_FLOAT32_INPUTS(pl) {
3715 FOR_FLOAT32_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003716 CHECK_DOUBLE_EQ(*pl > *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003717 }
3718 }
3719}
3720
3721
3722TEST(RunFloat64MaxP) {
3723 RawMachineAssemblerTester<int32_t> m;
3724 Float64BinopTester bt(&m);
3725 if (!m.machine()->Float64Max().IsSupported()) return;
3726
3727 bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
3728
3729 FOR_FLOAT64_INPUTS(pl) {
3730 FOR_FLOAT64_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003731 CHECK_DOUBLE_EQ(*pl > *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003732 }
3733 }
3734}
3735
3736
3737TEST(RunFloat32MinP) {
3738 RawMachineAssemblerTester<int32_t> m;
3739 Float32BinopTester bt(&m);
3740 if (!m.machine()->Float32Min().IsSupported()) return;
3741
3742 bt.AddReturn(m.Float32Min(bt.param0, bt.param1));
3743
3744 FOR_FLOAT32_INPUTS(pl) {
3745 FOR_FLOAT32_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003746 CHECK_DOUBLE_EQ(*pl < *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003747 }
3748 }
3749}
3750
3751
3752TEST(RunFloat64MinP) {
3753 RawMachineAssemblerTester<int32_t> m;
3754 Float64BinopTester bt(&m);
3755 if (!m.machine()->Float64Min().IsSupported()) return;
3756
3757 bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
3758
3759 FOR_FLOAT64_INPUTS(pl) {
3760 FOR_FLOAT64_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003761 CHECK_DOUBLE_EQ(*pl < *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003762 }
3763 }
3764}
3765
3766
3767TEST(RunFloat32SubP) {
3768 RawMachineAssemblerTester<int32_t> m;
3769 Float32BinopTester bt(&m);
3770
3771 bt.AddReturn(m.Float32Sub(bt.param0, bt.param1));
3772
3773 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003774 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl - *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003775 }
3776}
3777
3778
3779TEST(RunFloat32SubImm1) {
3780 FOR_FLOAT32_INPUTS(i) {
3781 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3782 m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0)));
3783
Ben Murdochda12d292016-06-02 14:46:10 +01003784 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003785 }
3786}
3787
3788
3789TEST(RunFloat32SubImm2) {
3790 FOR_FLOAT32_INPUTS(i) {
3791 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3792 m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i)));
3793
Ben Murdochda12d292016-06-02 14:46:10 +01003794 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*j - *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003795 }
3796}
3797
3798
3799TEST(RunFloat64SubImm1) {
3800 FOR_FLOAT64_INPUTS(i) {
3801 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3802 m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
3803
Ben Murdochda12d292016-06-02 14:46:10 +01003804 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003805 }
3806}
3807
3808
3809TEST(RunFloat64SubImm2) {
3810 FOR_FLOAT64_INPUTS(i) {
3811 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3812 m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
3813
Ben Murdochda12d292016-06-02 14:46:10 +01003814 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j - *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003815 }
3816}
3817
3818
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003819TEST(RunFloat64SubP) {
3820 RawMachineAssemblerTester<int32_t> m;
3821 Float64BinopTester bt(&m);
3822
3823 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
3824
3825 FOR_FLOAT64_INPUTS(pl) {
3826 FOR_FLOAT64_INPUTS(pr) {
3827 double expected = *pl - *pr;
Ben Murdochda12d292016-06-02 14:46:10 +01003828 CHECK_DOUBLE_EQ(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003829 }
3830 }
3831}
3832
3833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003834TEST(RunFloat32MulP) {
3835 RawMachineAssemblerTester<int32_t> m;
3836 Float32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003838 bt.AddReturn(m.Float32Mul(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003839
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003840 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003841 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl * *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003842 }
3843}
3844
3845
3846TEST(RunFloat64MulP) {
3847 RawMachineAssemblerTester<int32_t> m;
3848 Float64BinopTester bt(&m);
3849
3850 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
3851
3852 FOR_FLOAT64_INPUTS(pl) {
3853 FOR_FLOAT64_INPUTS(pr) {
3854 double expected = *pl * *pr;
Ben Murdochda12d292016-06-02 14:46:10 +01003855 CHECK_DOUBLE_EQ(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003856 }
3857 }
3858}
3859
3860
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003861TEST(RunFloat64MulAndFloat64Add1) {
3862 BufferedRawMachineAssemblerTester<double> m(
3863 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3864 m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
3865 m.Parameter(2)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003866
3867 FOR_FLOAT64_INPUTS(i) {
3868 FOR_FLOAT64_INPUTS(j) {
3869 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003870 CHECK_DOUBLE_EQ((*i * *j) + *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003871 }
3872 }
3873 }
3874}
3875
3876
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003877TEST(RunFloat64MulAndFloat64Add2) {
3878 BufferedRawMachineAssemblerTester<double> m(
3879 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3880 m.Return(m.Float64Add(m.Parameter(0),
3881 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003882
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003883 FOR_FLOAT64_INPUTS(i) {
3884 FOR_FLOAT64_INPUTS(j) {
3885 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003886 CHECK_DOUBLE_EQ(*i + (*j * *k), m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003887 }
3888 }
3889 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003890}
3891
3892
3893TEST(RunFloat64MulAndFloat64Sub1) {
3894 BufferedRawMachineAssemblerTester<double> m(
3895 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3896 m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
3897 m.Parameter(2)));
3898
3899 FOR_FLOAT64_INPUTS(i) {
3900 FOR_FLOAT64_INPUTS(j) {
3901 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003902 CHECK_DOUBLE_EQ((*i * *j) - *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003903 }
3904 }
3905 }
3906}
3907
3908
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003909TEST(RunFloat64MulAndFloat64Sub2) {
3910 BufferedRawMachineAssemblerTester<double> m(
3911 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3912 m.Return(m.Float64Sub(m.Parameter(0),
3913 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
3914
3915 FOR_FLOAT64_INPUTS(i) {
3916 FOR_FLOAT64_INPUTS(j) {
3917 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003918 CHECK_DOUBLE_EQ(*i - (*j * *k), m.Call(*i, *j, *k));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003919 }
3920 }
3921 }
3922}
3923
3924
3925TEST(RunFloat64MulImm1) {
3926 FOR_FLOAT64_INPUTS(i) {
3927 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3928 m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
3929
Ben Murdochda12d292016-06-02 14:46:10 +01003930 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i * *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003931 }
3932}
3933
3934
3935TEST(RunFloat64MulImm2) {
3936 FOR_FLOAT64_INPUTS(i) {
3937 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3938 m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
3939
Ben Murdochda12d292016-06-02 14:46:10 +01003940 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j * *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003941 }
3942}
3943
3944
3945TEST(RunFloat32DivP) {
3946 RawMachineAssemblerTester<int32_t> m;
3947 Float32BinopTester bt(&m);
3948
3949 bt.AddReturn(m.Float32Div(bt.param0, bt.param1));
3950
3951 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003952 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl / *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003953 }
3954}
3955
3956
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003957TEST(RunFloat64DivP) {
3958 RawMachineAssemblerTester<int32_t> m;
3959 Float64BinopTester bt(&m);
3960
3961 bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
3962
3963 FOR_FLOAT64_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003964 FOR_FLOAT64_INPUTS(pr) { CHECK_DOUBLE_EQ(*pl / *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003965 }
3966}
3967
3968
3969TEST(RunFloat64ModP) {
3970 RawMachineAssemblerTester<int32_t> m;
3971 Float64BinopTester bt(&m);
3972
3973 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
3974
3975 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003976 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), bt.call(*i, *j)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003977 }
3978}
3979
3980
3981TEST(RunChangeInt32ToFloat64_A) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003982 int32_t magic = 0x986234;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003983 BufferedRawMachineAssemblerTester<double> m;
3984 m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic)));
Ben Murdochda12d292016-06-02 14:46:10 +01003985 CHECK_DOUBLE_EQ(static_cast<double>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003986}
3987
3988
3989TEST(RunChangeInt32ToFloat64_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003990 BufferedRawMachineAssemblerTester<double> m(MachineType::Int32());
3991 m.Return(m.ChangeInt32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003992
Ben Murdochda12d292016-06-02 14:46:10 +01003993 FOR_INT32_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003994}
3995
3996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003997TEST(RunChangeUint32ToFloat64) {
3998 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32());
3999 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004000
Ben Murdochda12d292016-06-02 14:46:10 +01004001 FOR_UINT32_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004002}
4003
4004
Ben Murdoch097c5b22016-05-18 11:27:45 +01004005TEST(RunTruncateFloat32ToInt32) {
4006 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float32());
4007 m.Return(m.TruncateFloat32ToInt32(m.Parameter(0)));
4008 FOR_FLOAT32_INPUTS(i) {
4009 if (*i <= static_cast<float>(std::numeric_limits<int32_t>::max()) &&
4010 *i >= static_cast<float>(std::numeric_limits<int32_t>::min())) {
Ben Murdochda12d292016-06-02 14:46:10 +01004011 CHECK_FLOAT_EQ(static_cast<int32_t>(*i), m.Call(*i));
Ben Murdoch097c5b22016-05-18 11:27:45 +01004012 }
4013 }
4014}
4015
4016
4017TEST(RunTruncateFloat32ToUint32) {
4018 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float32());
4019 m.Return(m.TruncateFloat32ToUint32(m.Parameter(0)));
4020 {
4021 FOR_UINT32_INPUTS(i) {
Ben Murdochc5610432016-08-08 18:44:38 +01004022 volatile float input = static_cast<float>(*i);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004023 // This condition on 'input' is required because
4024 // static_cast<float>(std::numeric_limits<uint32_t>::max()) results in a
4025 // value outside uint32 range.
4026 if (input < static_cast<float>(std::numeric_limits<uint32_t>::max())) {
4027 CHECK_EQ(static_cast<uint32_t>(input), m.Call(input));
4028 }
4029 }
4030 }
4031 {
4032 FOR_FLOAT32_INPUTS(i) {
4033 if (*i <= static_cast<float>(std::numeric_limits<uint32_t>::max()) &&
4034 *i >= static_cast<float>(std::numeric_limits<uint32_t>::min())) {
Ben Murdochda12d292016-06-02 14:46:10 +01004035 CHECK_FLOAT_EQ(static_cast<uint32_t>(*i), m.Call(*i));
Ben Murdoch097c5b22016-05-18 11:27:45 +01004036 }
4037 }
4038 }
4039}
4040
4041
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004042TEST(RunChangeFloat64ToInt32_A) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004043 BufferedRawMachineAssemblerTester<int32_t> m;
4044 double magic = 11.1;
4045 m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic)));
4046 CHECK_EQ(static_cast<int32_t>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004047}
4048
4049
4050TEST(RunChangeFloat64ToInt32_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004051 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64());
4052 m.Return(m.ChangeFloat64ToInt32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004053
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004054 // Note we don't check fractional inputs, or inputs outside the range of
4055 // int32, because these Convert operators really should be Change operators.
4056 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
4057
4058 for (int32_t n = 1; n < 31; ++n) {
4059 CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n)));
4060 }
4061
4062 for (int32_t n = 1; n < 31; ++n) {
4063 CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n)));
4064 }
4065}
4066
4067
4068TEST(RunChangeFloat64ToUint32) {
4069 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
4070 m.Return(m.ChangeFloat64ToUint32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004071
4072 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004073 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004074 }
4075
4076 // Check various powers of 2.
4077 for (int32_t n = 1; n < 31; ++n) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004078 { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004079
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004080 { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004081 }
4082 // Note we don't check fractional inputs, because these Convert operators
4083 // really should be Change operators.
4084}
4085
4086
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004087TEST(RunTruncateFloat64ToFloat32) {
4088 BufferedRawMachineAssemblerTester<float> m(MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004089
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004090 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004091
Ben Murdochda12d292016-06-02 14:46:10 +01004092 FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(DoubleToFloat32(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004093}
4094
Ben Murdochda12d292016-06-02 14:46:10 +01004095uint64_t ToInt64(uint32_t low, uint32_t high) {
4096 return (static_cast<uint64_t>(high) << 32) | static_cast<uint64_t>(low);
4097}
4098
Ben Murdochc5610432016-08-08 18:44:38 +01004099#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X87
Ben Murdochda12d292016-06-02 14:46:10 +01004100TEST(RunInt32PairAdd) {
4101 BufferedRawMachineAssemblerTester<int32_t> m(
4102 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4103 MachineType::Uint32());
4104
4105 uint32_t high;
4106 uint32_t low;
4107
4108 Node* PairAdd = m.Int32PairAdd(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4109 m.Parameter(3));
4110
4111 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4112 m.Projection(0, PairAdd));
4113 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4114 m.Projection(1, PairAdd));
4115 m.Return(m.Int32Constant(74));
4116
4117 FOR_UINT64_INPUTS(i) {
4118 FOR_UINT64_INPUTS(j) {
4119 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4120 static_cast<uint32_t>(*i >> 32),
4121 static_cast<uint32_t>(*j & 0xffffffff),
4122 static_cast<uint32_t>(*j >> 32));
4123 CHECK_EQ(*i + *j, ToInt64(low, high));
4124 }
4125 }
4126}
4127
4128void TestInt32PairAddWithSharedInput(int a, int b, int c, int d) {
4129 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4130 MachineType::Uint32());
4131
4132 uint32_t high;
4133 uint32_t low;
4134
4135 Node* PairAdd = m.Int32PairAdd(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4136 m.Parameter(d));
4137
4138 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4139 m.Projection(0, PairAdd));
4140 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4141 m.Projection(1, PairAdd));
4142 m.Return(m.Int32Constant(74));
4143
4144 FOR_UINT32_INPUTS(i) {
4145 FOR_UINT32_INPUTS(j) {
4146 m.Call(*i, *j);
4147 uint32_t inputs[] = {*i, *j};
4148 CHECK_EQ(ToInt64(inputs[a], inputs[b]) + ToInt64(inputs[c], inputs[d]),
4149 ToInt64(low, high));
4150 }
4151 }
4152}
4153
4154TEST(RunInt32PairAddWithSharedInput) {
4155 TestInt32PairAddWithSharedInput(0, 0, 0, 0);
4156 TestInt32PairAddWithSharedInput(1, 0, 0, 0);
4157 TestInt32PairAddWithSharedInput(0, 1, 0, 0);
4158 TestInt32PairAddWithSharedInput(0, 0, 1, 0);
4159 TestInt32PairAddWithSharedInput(0, 0, 0, 1);
4160 TestInt32PairAddWithSharedInput(1, 1, 0, 0);
4161}
4162
4163TEST(RunInt32PairSub) {
4164 BufferedRawMachineAssemblerTester<int32_t> m(
4165 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4166 MachineType::Uint32());
4167
4168 uint32_t high;
4169 uint32_t low;
4170
4171 Node* PairSub = m.Int32PairSub(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4172 m.Parameter(3));
4173
4174 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4175 m.Projection(0, PairSub));
4176 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4177 m.Projection(1, PairSub));
4178 m.Return(m.Int32Constant(74));
4179
4180 FOR_UINT64_INPUTS(i) {
4181 FOR_UINT64_INPUTS(j) {
4182 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4183 static_cast<uint32_t>(*i >> 32),
4184 static_cast<uint32_t>(*j & 0xffffffff),
4185 static_cast<uint32_t>(*j >> 32));
4186 CHECK_EQ(*i - *j, ToInt64(low, high));
4187 }
4188 }
4189}
4190
4191void TestInt32PairSubWithSharedInput(int a, int b, int c, int d) {
4192 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4193 MachineType::Uint32());
4194
4195 uint32_t high;
4196 uint32_t low;
4197
4198 Node* PairSub = m.Int32PairSub(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4199 m.Parameter(d));
4200
4201 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4202 m.Projection(0, PairSub));
4203 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4204 m.Projection(1, PairSub));
4205 m.Return(m.Int32Constant(74));
4206
4207 FOR_UINT32_INPUTS(i) {
4208 FOR_UINT32_INPUTS(j) {
4209 m.Call(*i, *j);
4210 uint32_t inputs[] = {*i, *j};
4211 CHECK_EQ(ToInt64(inputs[a], inputs[b]) - ToInt64(inputs[c], inputs[d]),
4212 ToInt64(low, high));
4213 }
4214 }
4215}
4216
4217TEST(RunInt32PairSubWithSharedInput) {
4218 TestInt32PairSubWithSharedInput(0, 0, 0, 0);
4219 TestInt32PairSubWithSharedInput(1, 0, 0, 0);
4220 TestInt32PairSubWithSharedInput(0, 1, 0, 0);
4221 TestInt32PairSubWithSharedInput(0, 0, 1, 0);
4222 TestInt32PairSubWithSharedInput(0, 0, 0, 1);
4223 TestInt32PairSubWithSharedInput(1, 1, 0, 0);
4224}
4225
4226TEST(RunInt32PairMul) {
4227 BufferedRawMachineAssemblerTester<int32_t> m(
4228 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4229 MachineType::Uint32());
4230
4231 uint32_t high;
4232 uint32_t low;
4233
4234 Node* PairMul = m.Int32PairMul(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4235 m.Parameter(3));
4236
4237 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4238 m.Projection(0, PairMul));
4239 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4240 m.Projection(1, PairMul));
4241 m.Return(m.Int32Constant(74));
4242
4243 FOR_UINT64_INPUTS(i) {
4244 FOR_UINT64_INPUTS(j) {
4245 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4246 static_cast<uint32_t>(*i >> 32),
4247 static_cast<uint32_t>(*j & 0xffffffff),
4248 static_cast<uint32_t>(*j >> 32));
4249 CHECK_EQ(*i * *j, ToInt64(low, high));
4250 }
4251 }
4252}
4253
4254void TestInt32PairMulWithSharedInput(int a, int b, int c, int d) {
4255 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4256 MachineType::Uint32());
4257
4258 uint32_t high;
4259 uint32_t low;
4260
4261 Node* PairMul = m.Int32PairMul(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4262 m.Parameter(d));
4263
4264 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4265 m.Projection(0, PairMul));
4266 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4267 m.Projection(1, PairMul));
4268 m.Return(m.Int32Constant(74));
4269
4270 FOR_UINT32_INPUTS(i) {
4271 FOR_UINT32_INPUTS(j) {
4272 m.Call(*i, *j);
4273 uint32_t inputs[] = {*i, *j};
4274 CHECK_EQ(ToInt64(inputs[a], inputs[b]) * ToInt64(inputs[c], inputs[d]),
4275 ToInt64(low, high));
4276 }
4277 }
4278}
4279
4280TEST(RunInt32PairMulWithSharedInput) {
4281 TestInt32PairMulWithSharedInput(0, 0, 0, 0);
4282 TestInt32PairMulWithSharedInput(1, 0, 0, 0);
4283 TestInt32PairMulWithSharedInput(0, 1, 0, 0);
4284 TestInt32PairMulWithSharedInput(0, 0, 1, 0);
4285 TestInt32PairMulWithSharedInput(0, 0, 0, 1);
4286 TestInt32PairMulWithSharedInput(1, 1, 0, 0);
4287 TestInt32PairMulWithSharedInput(0, 1, 1, 0);
4288}
4289
4290TEST(RunWord32PairShl) {
4291 BufferedRawMachineAssemblerTester<int32_t> m(
4292 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
4293
4294 uint32_t high;
4295 uint32_t low;
4296
4297 Node* PairAdd =
4298 m.Word32PairShl(m.Parameter(0), m.Parameter(1), m.Parameter(2));
4299
4300 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4301 m.Projection(0, PairAdd));
4302 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4303 m.Projection(1, PairAdd));
4304 m.Return(m.Int32Constant(74));
4305
4306 FOR_UINT64_INPUTS(i) {
4307 for (uint32_t j = 0; j < 64; j++) {
4308 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4309 static_cast<uint32_t>(*i >> 32), j);
4310 CHECK_EQ(*i << j, ToInt64(low, high));
4311 }
4312 }
4313}
4314
4315void TestWord32PairShlWithSharedInput(int a, int b) {
4316 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4317 MachineType::Uint32());
4318
4319 uint32_t high;
4320 uint32_t low;
4321
4322 Node* PairAdd =
4323 m.Word32PairShl(m.Parameter(a), m.Parameter(b), m.Parameter(1));
4324
4325 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4326 m.Projection(0, PairAdd));
4327 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4328 m.Projection(1, PairAdd));
4329 m.Return(m.Int32Constant(74));
4330
4331 FOR_UINT32_INPUTS(i) {
4332 for (uint32_t j = 0; j < 64; j++) {
4333 m.Call(*i, j);
4334 uint32_t inputs[] = {*i, j};
4335 CHECK_EQ(ToInt64(inputs[a], inputs[b]) << j, ToInt64(low, high));
4336 }
4337 }
4338}
4339
4340TEST(RunWord32PairShlWithSharedInput) {
4341 TestWord32PairShlWithSharedInput(0, 0);
4342 TestWord32PairShlWithSharedInput(0, 1);
4343 TestWord32PairShlWithSharedInput(1, 0);
4344 TestWord32PairShlWithSharedInput(1, 1);
4345}
4346
Ben Murdochc5610432016-08-08 18:44:38 +01004347TEST(RunWord32PairShr) {
4348 BufferedRawMachineAssemblerTester<int32_t> m(
4349 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
4350
4351 uint32_t high;
4352 uint32_t low;
4353
4354 Node* PairAdd =
4355 m.Word32PairShr(m.Parameter(0), m.Parameter(1), m.Parameter(2));
4356
4357 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4358 m.Projection(0, PairAdd));
4359 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4360 m.Projection(1, PairAdd));
4361 m.Return(m.Int32Constant(74));
4362
4363 FOR_UINT64_INPUTS(i) {
4364 for (uint32_t j = 0; j < 64; j++) {
4365 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4366 static_cast<uint32_t>(*i >> 32), j);
4367 CHECK_EQ(*i >> j, ToInt64(low, high));
4368 }
4369 }
4370}
4371
4372TEST(RunWord32PairSar) {
4373 BufferedRawMachineAssemblerTester<int32_t> m(
4374 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
4375
4376 uint32_t high;
4377 uint32_t low;
4378
4379 Node* PairAdd =
4380 m.Word32PairSar(m.Parameter(0), m.Parameter(1), m.Parameter(2));
4381
4382 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4383 m.Projection(0, PairAdd));
4384 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4385 m.Projection(1, PairAdd));
4386 m.Return(m.Int32Constant(74));
4387
4388 FOR_INT64_INPUTS(i) {
4389 for (uint32_t j = 0; j < 64; j++) {
4390 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4391 static_cast<uint32_t>(*i >> 32), j);
4392 CHECK_EQ(*i >> j, ToInt64(low, high));
4393 }
4394 }
4395}
4396
Ben Murdochda12d292016-06-02 14:46:10 +01004397#endif
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004398
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004399TEST(RunDeadChangeFloat64ToInt32) {
4400 RawMachineAssemblerTester<int32_t> m;
4401 const int magic = 0x88abcda4;
4402 m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
4403 m.Return(m.Int32Constant(magic));
4404 CHECK_EQ(magic, m.Call());
4405}
4406
4407
4408TEST(RunDeadChangeInt32ToFloat64) {
4409 RawMachineAssemblerTester<int32_t> m;
4410 const int magic = 0x8834abcd;
4411 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
4412 m.Return(m.Int32Constant(magic));
4413 CHECK_EQ(magic, m.Call());
4414}
4415
4416
4417TEST(RunLoopPhiInduction2) {
4418 RawMachineAssemblerTester<int32_t> m;
4419
4420 int false_val = 0x10777;
4421
4422 // x = false_val; while(false) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004423 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004424 Node* false_node = m.Int32Constant(false_val);
4425 m.Goto(&header);
4426 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004427 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004428 m.Branch(m.Int32Constant(0), &body, &end);
4429 m.Bind(&body);
4430 Node* add = m.Int32Add(phi, m.Int32Constant(1));
4431 phi->ReplaceInput(1, add);
4432 m.Goto(&header);
4433 m.Bind(&end);
4434 m.Return(phi);
4435
4436 CHECK_EQ(false_val, m.Call());
4437}
4438
4439
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004440TEST(RunFloatDiamond) {
4441 RawMachineAssemblerTester<int32_t> m;
4442
4443 const int magic = 99645;
4444 float buffer = 0.1f;
4445 float constant = 99.99f;
4446
4447 RawMachineLabel blocka, blockb, end;
4448 Node* k1 = m.Float32Constant(constant);
4449 Node* k2 = m.Float32Constant(0 - constant);
4450 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4451 m.Bind(&blocka);
4452 m.Goto(&end);
4453 m.Bind(&blockb);
4454 m.Goto(&end);
4455 m.Bind(&end);
4456 Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1);
4457 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer),
4458 m.IntPtrConstant(0), phi, kNoWriteBarrier);
4459 m.Return(m.Int32Constant(magic));
4460
4461 CHECK_EQ(magic, m.Call());
4462 CHECK(constant == buffer);
4463}
4464
4465
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004466TEST(RunDoubleDiamond) {
4467 RawMachineAssemblerTester<int32_t> m;
4468
4469 const int magic = 99645;
4470 double buffer = 0.1;
4471 double constant = 99.99;
4472
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004473 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004474 Node* k1 = m.Float64Constant(constant);
4475 Node* k2 = m.Float64Constant(0 - constant);
4476 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4477 m.Bind(&blocka);
4478 m.Goto(&end);
4479 m.Bind(&blockb);
4480 m.Goto(&end);
4481 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004482 Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1);
4483 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4484 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004485 m.Return(m.Int32Constant(magic));
4486
4487 CHECK_EQ(magic, m.Call());
4488 CHECK_EQ(constant, buffer);
4489}
4490
4491
4492TEST(RunRefDiamond) {
4493 RawMachineAssemblerTester<int32_t> m;
4494
4495 const int magic = 99644;
4496 Handle<String> rexpected =
4497 CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
4498 String* buffer;
4499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004500 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004501 Node* k1 = m.StringConstant("A");
4502 Node* k2 = m.StringConstant("B");
4503 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4504 m.Bind(&blocka);
4505 m.Goto(&end);
4506 m.Bind(&blockb);
4507 m.Goto(&end);
4508 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004509 Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1);
4510 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer),
4511 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004512 m.Return(m.Int32Constant(magic));
4513
4514 CHECK_EQ(magic, m.Call());
4515 CHECK(rexpected->SameValue(buffer));
4516}
4517
4518
4519TEST(RunDoubleRefDiamond) {
4520 RawMachineAssemblerTester<int32_t> m;
4521
4522 const int magic = 99648;
4523 double dbuffer = 0.1;
4524 double dconstant = 99.99;
4525 Handle<String> rexpected =
4526 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
4527 String* rbuffer;
4528
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004529 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004530 Node* d1 = m.Float64Constant(dconstant);
4531 Node* d2 = m.Float64Constant(0 - dconstant);
4532 Node* r1 = m.StringConstant("AX");
4533 Node* r2 = m.StringConstant("BX");
4534 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4535 m.Bind(&blocka);
4536 m.Goto(&end);
4537 m.Bind(&blockb);
4538 m.Goto(&end);
4539 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004540 Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4541 Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1);
4542 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4543 m.Int32Constant(0), dphi, kNoWriteBarrier);
4544 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4545 m.Int32Constant(0), rphi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004546 m.Return(m.Int32Constant(magic));
4547
4548 CHECK_EQ(magic, m.Call());
4549 CHECK_EQ(dconstant, dbuffer);
4550 CHECK(rexpected->SameValue(rbuffer));
4551}
4552
4553
4554TEST(RunDoubleRefDoubleDiamond) {
4555 RawMachineAssemblerTester<int32_t> m;
4556
4557 const int magic = 99649;
4558 double dbuffer = 0.1;
4559 double dconstant = 99.997;
4560 Handle<String> rexpected =
4561 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
4562 String* rbuffer;
4563
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004564 RawMachineLabel blocka, blockb, mid, blockd, blocke, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004565 Node* d1 = m.Float64Constant(dconstant);
4566 Node* d2 = m.Float64Constant(0 - dconstant);
4567 Node* r1 = m.StringConstant("AD");
4568 Node* r2 = m.StringConstant("BD");
4569 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4570 m.Bind(&blocka);
4571 m.Goto(&mid);
4572 m.Bind(&blockb);
4573 m.Goto(&mid);
4574 m.Bind(&mid);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004575 Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4576 Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004577 m.Branch(m.Int32Constant(0), &blockd, &blocke);
4578
4579 m.Bind(&blockd);
4580 m.Goto(&end);
4581 m.Bind(&blocke);
4582 m.Goto(&end);
4583 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004584 Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1);
4585 Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004587 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4588 m.Int32Constant(0), dphi2, kNoWriteBarrier);
4589 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4590 m.Int32Constant(0), rphi2, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004591 m.Return(m.Int32Constant(magic));
4592
4593 CHECK_EQ(magic, m.Call());
4594 CHECK_EQ(dconstant, dbuffer);
4595 CHECK(rexpected->SameValue(rbuffer));
4596}
4597
4598
4599TEST(RunDoubleLoopPhi) {
4600 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004601 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004602
4603 int magic = 99773;
4604 double buffer = 0.99;
4605 double dconstant = 777.1;
4606
4607 Node* zero = m.Int32Constant(0);
4608 Node* dk = m.Float64Constant(dconstant);
4609
4610 m.Goto(&header);
4611 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004612 Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004613 phi->ReplaceInput(1, phi);
4614 m.Branch(zero, &body, &end);
4615 m.Bind(&body);
4616 m.Goto(&header);
4617 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004618 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4619 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004620 m.Return(m.Int32Constant(magic));
4621
4622 CHECK_EQ(magic, m.Call());
4623}
4624
4625
4626TEST(RunCountToTenAccRaw) {
4627 RawMachineAssemblerTester<int32_t> m;
4628
4629 Node* zero = m.Int32Constant(0);
4630 Node* ten = m.Int32Constant(10);
4631 Node* one = m.Int32Constant(1);
4632
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004633 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004634
4635 m.Goto(&header);
4636
4637 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004638 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4639 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004640 m.Goto(&body);
4641
4642 m.Bind(&body);
4643 Node* next_i = m.Int32Add(i, one);
4644 Node* next_j = m.Int32Add(j, one);
4645 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4646
4647 m.Bind(&body_cont);
4648 i->ReplaceInput(1, next_i);
4649 j->ReplaceInput(1, next_j);
4650 m.Goto(&header);
4651
4652 m.Bind(&end);
4653 m.Return(ten);
4654
4655 CHECK_EQ(10, m.Call());
4656}
4657
4658
4659TEST(RunCountToTenAccRaw2) {
4660 RawMachineAssemblerTester<int32_t> m;
4661
4662 Node* zero = m.Int32Constant(0);
4663 Node* ten = m.Int32Constant(10);
4664 Node* one = m.Int32Constant(1);
4665
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004666 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004667
4668 m.Goto(&header);
4669
4670 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004671 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4672 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
4673 Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004674 m.Goto(&body);
4675
4676 m.Bind(&body);
4677 Node* next_i = m.Int32Add(i, one);
4678 Node* next_j = m.Int32Add(j, one);
4679 Node* next_k = m.Int32Add(j, one);
4680 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4681
4682 m.Bind(&body_cont);
4683 i->ReplaceInput(1, next_i);
4684 j->ReplaceInput(1, next_j);
4685 k->ReplaceInput(1, next_k);
4686 m.Goto(&header);
4687
4688 m.Bind(&end);
4689 m.Return(ten);
4690
4691 CHECK_EQ(10, m.Call());
4692}
4693
4694
4695TEST(RunAddTree) {
4696 RawMachineAssemblerTester<int32_t> m;
4697 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
4698
4699 Node* base = m.PointerConstant(inputs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004700 Node* n0 =
4701 m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t)));
4702 Node* n1 =
4703 m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t)));
4704 Node* n2 =
4705 m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t)));
4706 Node* n3 =
4707 m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t)));
4708 Node* n4 =
4709 m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t)));
4710 Node* n5 =
4711 m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t)));
4712 Node* n6 =
4713 m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t)));
4714 Node* n7 =
4715 m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004716
4717 Node* i1 = m.Int32Add(n0, n1);
4718 Node* i2 = m.Int32Add(n2, n3);
4719 Node* i3 = m.Int32Add(n4, n5);
4720 Node* i4 = m.Int32Add(n6, n7);
4721
4722 Node* i5 = m.Int32Add(i1, i2);
4723 Node* i6 = m.Int32Add(i3, i4);
4724
4725 Node* i7 = m.Int32Add(i5, i6);
4726
4727 m.Return(i7);
4728
4729 CHECK_EQ(116, m.Call());
4730}
4731
4732
4733static const int kFloat64CompareHelperTestCases = 15;
4734static const int kFloat64CompareHelperNodeType = 4;
4735
4736static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
4737 int test_case, int node_type, double x,
4738 double y) {
4739 static double buffer[2];
4740 buffer[0] = x;
4741 buffer[1] = y;
4742 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
4743 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
4744 CHECK(x < y);
4745 bool load_a = node_type / 2 == 1;
4746 bool load_b = node_type % 2 == 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004747 Node* a =
4748 load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0]))
4749 : m->Float64Constant(x);
4750 Node* b =
4751 load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1]))
4752 : m->Float64Constant(y);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004753 Node* cmp = NULL;
4754 bool expected = false;
4755 switch (test_case) {
4756 // Equal tests.
4757 case 0:
4758 cmp = m->Float64Equal(a, b);
4759 expected = false;
4760 break;
4761 case 1:
4762 cmp = m->Float64Equal(a, a);
4763 expected = true;
4764 break;
4765 // LessThan tests.
4766 case 2:
4767 cmp = m->Float64LessThan(a, b);
4768 expected = true;
4769 break;
4770 case 3:
4771 cmp = m->Float64LessThan(b, a);
4772 expected = false;
4773 break;
4774 case 4:
4775 cmp = m->Float64LessThan(a, a);
4776 expected = false;
4777 break;
4778 // LessThanOrEqual tests.
4779 case 5:
4780 cmp = m->Float64LessThanOrEqual(a, b);
4781 expected = true;
4782 break;
4783 case 6:
4784 cmp = m->Float64LessThanOrEqual(b, a);
4785 expected = false;
4786 break;
4787 case 7:
4788 cmp = m->Float64LessThanOrEqual(a, a);
4789 expected = true;
4790 break;
4791 // NotEqual tests.
4792 case 8:
4793 cmp = m->Float64NotEqual(a, b);
4794 expected = true;
4795 break;
4796 case 9:
4797 cmp = m->Float64NotEqual(b, a);
4798 expected = true;
4799 break;
4800 case 10:
4801 cmp = m->Float64NotEqual(a, a);
4802 expected = false;
4803 break;
4804 // GreaterThan tests.
4805 case 11:
4806 cmp = m->Float64GreaterThan(a, a);
4807 expected = false;
4808 break;
4809 case 12:
4810 cmp = m->Float64GreaterThan(a, b);
4811 expected = false;
4812 break;
4813 // GreaterThanOrEqual tests.
4814 case 13:
4815 cmp = m->Float64GreaterThanOrEqual(a, a);
4816 expected = true;
4817 break;
4818 case 14:
4819 cmp = m->Float64GreaterThanOrEqual(b, a);
4820 expected = true;
4821 break;
4822 default:
4823 UNREACHABLE();
4824 }
4825 m->Return(cmp);
4826 return expected;
4827}
4828
4829
4830TEST(RunFloat64Compare) {
4831 double inf = V8_INFINITY;
4832 // All pairs (a1, a2) are of the form a1 < a2.
4833 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22,
4834 -inf, 0.22, 0.22, inf, -inf, inf};
4835
4836 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
4837 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
4838 node_type++) {
4839 for (size_t input = 0; input < arraysize(inputs); input += 2) {
4840 RawMachineAssemblerTester<int32_t> m;
4841 int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
4842 inputs[input + 1]);
4843 CHECK_EQ(expected, m.Call());
4844 }
4845 }
4846 }
4847}
4848
4849
4850TEST(RunFloat64UnorderedCompare) {
4851 RawMachineAssemblerTester<int32_t> m;
4852
4853 const Operator* operators[] = {m.machine()->Float64Equal(),
4854 m.machine()->Float64LessThan(),
4855 m.machine()->Float64LessThanOrEqual()};
4856
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004857 double nan = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004858
4859 FOR_FLOAT64_INPUTS(i) {
4860 for (size_t o = 0; o < arraysize(operators); ++o) {
4861 for (int j = 0; j < 2; j++) {
4862 RawMachineAssemblerTester<int32_t> m;
4863 Node* a = m.Float64Constant(*i);
4864 Node* b = m.Float64Constant(nan);
4865 if (j == 1) std::swap(a, b);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004866 m.Return(m.AddNode(operators[o], a, b));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004867 CHECK_EQ(0, m.Call());
4868 }
4869 }
4870 }
4871}
4872
4873
4874TEST(RunFloat64Equal) {
4875 double input_a = 0.0;
4876 double input_b = 0.0;
4877
4878 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004879 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4880 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004881 m.Return(m.Float64Equal(a, b));
4882
4883 CompareWrapper cmp(IrOpcode::kFloat64Equal);
4884 FOR_FLOAT64_INPUTS(pl) {
4885 FOR_FLOAT64_INPUTS(pr) {
4886 input_a = *pl;
4887 input_b = *pr;
4888 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4889 CHECK_EQ(expected, m.Call());
4890 }
4891 }
4892}
4893
4894
4895TEST(RunFloat64LessThan) {
4896 double input_a = 0.0;
4897 double input_b = 0.0;
4898
4899 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004900 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4901 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004902 m.Return(m.Float64LessThan(a, b));
4903
4904 CompareWrapper cmp(IrOpcode::kFloat64LessThan);
4905 FOR_FLOAT64_INPUTS(pl) {
4906 FOR_FLOAT64_INPUTS(pr) {
4907 input_a = *pl;
4908 input_b = *pr;
4909 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4910 CHECK_EQ(expected, m.Call());
4911 }
4912 }
4913}
4914
4915
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004916static void IntPtrCompare(intptr_t left, intptr_t right) {
4917 for (int test = 0; test < 7; test++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004918 RawMachineAssemblerTester<bool> m(MachineType::Pointer(),
4919 MachineType::Pointer());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004920 Node* p0 = m.Parameter(0);
4921 Node* p1 = m.Parameter(1);
4922 Node* res = NULL;
4923 bool expected = false;
4924 switch (test) {
4925 case 0:
4926 res = m.IntPtrLessThan(p0, p1);
4927 expected = true;
4928 break;
4929 case 1:
4930 res = m.IntPtrLessThanOrEqual(p0, p1);
4931 expected = true;
4932 break;
4933 case 2:
4934 res = m.IntPtrEqual(p0, p1);
4935 expected = false;
4936 break;
4937 case 3:
4938 res = m.IntPtrGreaterThanOrEqual(p0, p1);
4939 expected = false;
4940 break;
4941 case 4:
4942 res = m.IntPtrGreaterThan(p0, p1);
4943 expected = false;
4944 break;
4945 case 5:
4946 res = m.IntPtrEqual(p0, p0);
4947 expected = true;
4948 break;
4949 case 6:
4950 res = m.IntPtrNotEqual(p0, p1);
4951 expected = true;
4952 break;
4953 default:
4954 UNREACHABLE();
4955 break;
4956 }
4957 m.Return(res);
4958 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
4959 reinterpret_cast<int32_t*>(right)));
4960 }
4961}
4962
4963
4964TEST(RunIntPtrCompare) {
4965 intptr_t min = std::numeric_limits<intptr_t>::min();
4966 intptr_t max = std::numeric_limits<intptr_t>::max();
4967 // An ascending chain of intptr_t
4968 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
4969 for (size_t i = 0; i < arraysize(inputs) - 1; i++) {
4970 IntPtrCompare(inputs[i], inputs[i + 1]);
4971 }
4972}
4973
4974
4975TEST(RunTestIntPtrArithmetic) {
4976 static const int kInputSize = 10;
4977 int32_t inputs[kInputSize];
4978 int32_t outputs[kInputSize];
4979 for (int i = 0; i < kInputSize; i++) {
4980 inputs[i] = i;
4981 outputs[i] = -1;
4982 }
4983 RawMachineAssemblerTester<int32_t*> m;
4984 Node* input = m.PointerConstant(&inputs[0]);
4985 Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004986 Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004987 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004988 m.Store(MachineRepresentation::kWord32, output,
4989 m.Load(MachineType::Int32(), input), kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004990 input = m.IntPtrAdd(input, elem_size);
4991 output = m.IntPtrSub(output, elem_size);
4992 }
4993 m.Return(input);
4994 CHECK_EQ(&inputs[kInputSize], m.Call());
4995 for (int i = 0; i < kInputSize; i++) {
4996 CHECK_EQ(i, inputs[i]);
4997 CHECK_EQ(kInputSize - i - 1, outputs[i]);
4998 }
4999}
5000
5001
5002TEST(RunSpillLotsOfThings) {
5003 static const int kInputSize = 1000;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005004 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005005 Node* accs[kInputSize];
5006 int32_t outputs[kInputSize];
5007 Node* one = m.Int32Constant(1);
5008 Node* acc = one;
5009 for (int i = 0; i < kInputSize; i++) {
5010 acc = m.Int32Add(acc, one);
5011 accs[i] = acc;
5012 }
5013 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005014 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005015 }
5016 m.Return(one);
5017 m.Call();
5018 for (int i = 0; i < kInputSize; i++) {
5019 CHECK_EQ(outputs[i], i + 2);
5020 }
5021}
5022
5023
5024TEST(RunSpillConstantsAndParameters) {
5025 static const int kInputSize = 1000;
5026 static const int32_t kBase = 987;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005027 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5028 MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005029 int32_t outputs[kInputSize];
5030 Node* csts[kInputSize];
5031 Node* accs[kInputSize];
5032 Node* acc = m.Int32Constant(0);
5033 for (int i = 0; i < kInputSize; i++) {
5034 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
5035 }
5036 for (int i = 0; i < kInputSize; i++) {
5037 acc = m.Int32Add(acc, csts[i]);
5038 accs[i] = acc;
5039 }
5040 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005041 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005042 }
5043 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
5044 FOR_INT32_INPUTS(i) {
5045 FOR_INT32_INPUTS(j) {
5046 int32_t expected = *i + *j;
5047 for (int k = 0; k < kInputSize; k++) {
5048 expected += kBase + k;
5049 }
5050 CHECK_EQ(expected, m.Call(*i, *j));
5051 expected = 0;
5052 for (int k = 0; k < kInputSize; k++) {
5053 expected += kBase + k;
5054 CHECK_EQ(expected, outputs[k]);
5055 }
5056 }
5057 }
5058}
5059
5060
5061TEST(RunNewSpaceConstantsInPhi) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005062 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005063
5064 Isolate* isolate = CcTest::i_isolate();
5065 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
5066 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
5067 Node* true_node = m.HeapConstant(true_val);
5068 Node* false_node = m.HeapConstant(false_val);
5069
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005070 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005071 m.Branch(m.Parameter(0), &blocka, &blockb);
5072 m.Bind(&blocka);
5073 m.Goto(&end);
5074 m.Bind(&blockb);
5075 m.Goto(&end);
5076
5077 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005078 Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005079 m.Return(phi);
5080
5081 CHECK_EQ(*false_val, m.Call(0));
5082 CHECK_EQ(*true_val, m.Call(1));
5083}
5084
5085
5086TEST(RunInt32AddWithOverflowP) {
5087 int32_t actual_val = -1;
5088 RawMachineAssemblerTester<int32_t> m;
5089 Int32BinopTester bt(&m);
5090 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
5091 Node* val = m.Projection(0, add);
5092 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005093 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005094 bt.AddReturn(ovf);
5095 FOR_INT32_INPUTS(i) {
5096 FOR_INT32_INPUTS(j) {
5097 int32_t expected_val;
5098 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5099 CHECK_EQ(expected_ovf, bt.call(*i, *j));
5100 CHECK_EQ(expected_val, actual_val);
5101 }
5102 }
5103}
5104
5105
5106TEST(RunInt32AddWithOverflowImm) {
5107 int32_t actual_val = -1, expected_val = 0;
5108 FOR_INT32_INPUTS(i) {
5109 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005110 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5112 Node* val = m.Projection(0, add);
5113 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005114 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005115 m.Return(ovf);
5116 FOR_INT32_INPUTS(j) {
5117 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5118 CHECK_EQ(expected_ovf, m.Call(*j));
5119 CHECK_EQ(expected_val, actual_val);
5120 }
5121 }
5122 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005123 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005124 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5125 Node* val = m.Projection(0, add);
5126 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005127 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005128 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 FOR_INT32_INPUTS(j) {
5136 RawMachineAssemblerTester<int32_t> m;
5137 Node* add =
5138 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5139 Node* val = m.Projection(0, add);
5140 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005141 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005142 m.Return(ovf);
5143 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5144 CHECK_EQ(expected_ovf, m.Call());
5145 CHECK_EQ(expected_val, actual_val);
5146 }
5147 }
5148}
5149
5150
5151TEST(RunInt32AddWithOverflowInBranchP) {
5152 int constant = 911777;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005153 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005154 RawMachineAssemblerTester<int32_t> m;
5155 Int32BinopTester bt(&m);
5156 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
5157 Node* ovf = m.Projection(1, add);
5158 m.Branch(ovf, &blocka, &blockb);
5159 m.Bind(&blocka);
5160 bt.AddReturn(m.Int32Constant(constant));
5161 m.Bind(&blockb);
5162 Node* val = m.Projection(0, add);
5163 bt.AddReturn(val);
5164 FOR_INT32_INPUTS(i) {
5165 FOR_INT32_INPUTS(j) {
5166 int32_t expected;
5167 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant;
5168 CHECK_EQ(expected, bt.call(*i, *j));
5169 }
5170 }
5171}
5172
5173
5174TEST(RunInt32SubWithOverflowP) {
5175 int32_t actual_val = -1;
5176 RawMachineAssemblerTester<int32_t> m;
5177 Int32BinopTester bt(&m);
5178 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
5179 Node* val = m.Projection(0, add);
5180 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005181 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005182 bt.AddReturn(ovf);
5183 FOR_INT32_INPUTS(i) {
5184 FOR_INT32_INPUTS(j) {
5185 int32_t expected_val;
5186 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5187 CHECK_EQ(expected_ovf, bt.call(*i, *j));
5188 CHECK_EQ(expected_val, actual_val);
5189 }
5190 }
5191}
5192
5193
5194TEST(RunInt32SubWithOverflowImm) {
5195 int32_t actual_val = -1, expected_val = 0;
5196 FOR_INT32_INPUTS(i) {
5197 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005198 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005199 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5200 Node* val = m.Projection(0, add);
5201 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005202 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005203 m.Return(ovf);
5204 FOR_INT32_INPUTS(j) {
5205 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5206 CHECK_EQ(expected_ovf, m.Call(*j));
5207 CHECK_EQ(expected_val, actual_val);
5208 }
5209 }
5210 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005211 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005212 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5213 Node* val = m.Projection(0, add);
5214 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005215 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005216 m.Return(ovf);
5217 FOR_INT32_INPUTS(j) {
5218 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
5219 CHECK_EQ(expected_ovf, m.Call(*j));
5220 CHECK_EQ(expected_val, actual_val);
5221 }
5222 }
5223 FOR_INT32_INPUTS(j) {
5224 RawMachineAssemblerTester<int32_t> m;
5225 Node* add =
5226 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5227 Node* val = m.Projection(0, add);
5228 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005229 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005230 m.Return(ovf);
5231 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5232 CHECK_EQ(expected_ovf, m.Call());
5233 CHECK_EQ(expected_val, actual_val);
5234 }
5235 }
5236}
5237
5238
5239TEST(RunInt32SubWithOverflowInBranchP) {
5240 int constant = 911999;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005241 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005242 RawMachineAssemblerTester<int32_t> m;
5243 Int32BinopTester bt(&m);
5244 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
5245 Node* ovf = m.Projection(1, sub);
5246 m.Branch(ovf, &blocka, &blockb);
5247 m.Bind(&blocka);
5248 bt.AddReturn(m.Int32Constant(constant));
5249 m.Bind(&blockb);
5250 Node* val = m.Projection(0, sub);
5251 bt.AddReturn(val);
5252 FOR_INT32_INPUTS(i) {
5253 FOR_INT32_INPUTS(j) {
5254 int32_t expected;
5255 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant;
5256 CHECK_EQ(expected, bt.call(*i, *j));
5257 }
5258 }
5259}
5260
5261
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005262TEST(RunWord64EqualInBranchP) {
5263 int64_t input;
5264 RawMachineLabel blocka, blockb;
5265 RawMachineAssemblerTester<int64_t> m;
5266 if (!m.machine()->Is64()) return;
5267 Node* value = m.LoadFromPointer(&input, MachineType::Int64());
5268 m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
5269 m.Bind(&blocka);
5270 m.Return(m.Int32Constant(1));
5271 m.Bind(&blockb);
5272 m.Return(m.Int32Constant(2));
5273 input = V8_INT64_C(0);
5274 CHECK_EQ(1, m.Call());
5275 input = V8_INT64_C(1);
5276 CHECK_EQ(2, m.Call());
5277 input = V8_INT64_C(0x100000000);
5278 CHECK_EQ(2, m.Call());
5279}
5280
5281
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005282TEST(RunChangeInt32ToInt64P) {
5283 if (kPointerSize < 8) return;
5284 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005285 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5286 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
5287 m.ChangeInt32ToInt64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005288 m.Return(m.Int32Constant(0));
5289 FOR_INT32_INPUTS(i) {
5290 int64_t expected = *i;
5291 CHECK_EQ(0, m.Call(*i));
5292 CHECK_EQ(expected, actual);
5293 }
5294}
5295
5296
5297TEST(RunChangeUint32ToUint64P) {
5298 if (kPointerSize < 8) return;
5299 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005300 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
5301 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005302 m.ChangeUint32ToUint64(m.Parameter(0)));
5303 m.Return(m.Int32Constant(0));
5304 FOR_UINT32_INPUTS(i) {
5305 int64_t expected = static_cast<uint64_t>(*i);
5306 CHECK_EQ(0, m.Call(*i));
5307 CHECK_EQ(expected, actual);
5308 }
5309}
5310
5311
5312TEST(RunTruncateInt64ToInt32P) {
5313 if (kPointerSize < 8) return;
5314 int64_t expected = -1;
5315 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005316 m.Return(m.TruncateInt64ToInt32(
5317 m.LoadFromPointer(&expected, MachineType::Int64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005318 FOR_UINT32_INPUTS(i) {
5319 FOR_UINT32_INPUTS(j) {
5320 expected = (static_cast<uint64_t>(*j) << 32) | *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005321 CHECK_EQ(static_cast<int32_t>(expected), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005322 }
5323 }
5324}
5325
Ben Murdochc5610432016-08-08 18:44:38 +01005326TEST(RunTruncateFloat64ToWord32P) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005327 struct {
5328 double from;
5329 double raw;
5330 } kValues[] = {{0, 0},
5331 {0.5, 0},
5332 {-0.5, 0},
5333 {1.5, 1},
5334 {-1.5, -1},
5335 {5.5, 5},
5336 {-5.0, -5},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005337 {std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005338 {std::numeric_limits<double>::infinity(), 0},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005339 {-std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005340 {-std::numeric_limits<double>::infinity(), 0},
5341 {4.94065645841e-324, 0},
5342 {-4.94065645841e-324, 0},
5343 {0.9999999999999999, 0},
5344 {-0.9999999999999999, 0},
5345 {4294967296.0, 0},
5346 {-4294967296.0, 0},
5347 {9223372036854775000.0, 4294966272.0},
5348 {-9223372036854775000.0, -4294966272.0},
5349 {4.5036e+15, 372629504},
5350 {-4.5036e+15, -372629504},
5351 {287524199.5377777, 0x11234567},
5352 {-287524199.5377777, -0x11234567},
5353 {2300193596.302222, 2300193596.0},
5354 {-2300193596.302222, -2300193596.0},
5355 {4600387192.604444, 305419896},
5356 {-4600387192.604444, -305419896},
5357 {4823855600872397.0, 1737075661},
5358 {-4823855600872397.0, -1737075661},
5359 {4503603922337791.0, -1},
5360 {-4503603922337791.0, 1},
5361 {4503601774854143.0, 2147483647},
5362 {-4503601774854143.0, -2147483647},
5363 {9007207844675582.0, -2},
5364 {-9007207844675582.0, 2},
5365 {2.4178527921507624e+24, -536870912},
5366 {-2.4178527921507624e+24, 536870912},
5367 {2.417853945072267e+24, -536870912},
5368 {-2.417853945072267e+24, 536870912},
5369 {4.8357055843015248e+24, -1073741824},
5370 {-4.8357055843015248e+24, 1073741824},
5371 {4.8357078901445341e+24, -1073741824},
5372 {-4.8357078901445341e+24, 1073741824},
5373 {2147483647.0, 2147483647.0},
5374 {-2147483648.0, -2147483648.0},
5375 {9.6714111686030497e+24, -2147483648.0},
5376 {-9.6714111686030497e+24, -2147483648.0},
5377 {9.6714157802890681e+24, -2147483648.0},
5378 {-9.6714157802890681e+24, -2147483648.0},
5379 {1.9342813113834065e+25, 2147483648.0},
5380 {-1.9342813113834065e+25, 2147483648.0},
5381 {3.868562622766813e+25, 0},
5382 {-3.868562622766813e+25, 0},
5383 {1.7976931348623157e+308, 0},
5384 {-1.7976931348623157e+308, 0}};
5385 double input = -1.0;
5386 RawMachineAssemblerTester<int32_t> m;
Ben Murdochc5610432016-08-08 18:44:38 +01005387 m.Return(m.TruncateFloat64ToWord32(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005388 m.LoadFromPointer(&input, MachineType::Float64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005389 for (size_t i = 0; i < arraysize(kValues); ++i) {
5390 input = kValues[i].from;
5391 uint64_t expected = static_cast<int64_t>(kValues[i].raw);
5392 CHECK_EQ(static_cast<int>(expected), m.Call());
5393 }
5394}
5395
Ben Murdochc5610432016-08-08 18:44:38 +01005396TEST(RunTruncateFloat64ToWord32SignExtension) {
5397 BufferedRawMachineAssemblerTester<int32_t> r;
5398 r.Return(r.Int32Sub(r.TruncateFloat64ToWord32(r.Float64Constant(-1.0)),
5399 r.Int32Constant(0)));
5400 CHECK_EQ(-1, r.Call());
5401}
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005402
5403TEST(RunChangeFloat32ToFloat64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005404 BufferedRawMachineAssemblerTester<double> m(MachineType::Float32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005405
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005406 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005407
Ben Murdochda12d292016-06-02 14:46:10 +01005408 FOR_FLOAT32_INPUTS(i) {
5409 CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i));
5410 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005411}
5412
5413
5414TEST(RunFloat32Constant) {
5415 FOR_FLOAT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005416 BufferedRawMachineAssemblerTester<float> m;
5417 m.Return(m.Float32Constant(*i));
Ben Murdochda12d292016-06-02 14:46:10 +01005418 CHECK_FLOAT_EQ(*i, m.Call());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005419 }
5420}
5421
5422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005423TEST(RunFloat64ExtractLowWord32) {
5424 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5425 m.Return(m.Float64ExtractLowWord32(m.Parameter(0)));
5426 FOR_FLOAT64_INPUTS(i) {
5427 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i));
5428 CHECK_EQ(expected, m.Call(*i));
5429 }
5430}
5431
5432
5433TEST(RunFloat64ExtractHighWord32) {
5434 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5435 m.Return(m.Float64ExtractHighWord32(m.Parameter(0)));
5436 FOR_FLOAT64_INPUTS(i) {
5437 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32);
5438 CHECK_EQ(expected, m.Call(*i));
5439 }
5440}
5441
5442
5443TEST(RunFloat64InsertLowWord32) {
5444 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5445 MachineType::Int32());
5446 m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1)));
5447 FOR_FLOAT64_INPUTS(i) {
5448 FOR_INT32_INPUTS(j) {
5449 double expected = bit_cast<double>(
5450 (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) |
5451 (static_cast<uint64_t>(bit_cast<uint32_t>(*j))));
Ben Murdochda12d292016-06-02 14:46:10 +01005452 CHECK_DOUBLE_EQ(expected, m.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005453 }
5454 }
5455}
5456
5457
5458TEST(RunFloat64InsertHighWord32) {
5459 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5460 MachineType::Uint32());
5461 m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1)));
5462 FOR_FLOAT64_INPUTS(i) {
5463 FOR_UINT32_INPUTS(j) {
5464 uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) |
5465 (static_cast<uint64_t>(*j) << 32);
5466
Ben Murdochda12d292016-06-02 14:46:10 +01005467 CHECK_DOUBLE_EQ(bit_cast<double>(expected), m.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005468 }
5469 }
5470}
5471
5472
5473TEST(RunFloat32Abs) {
5474 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5475 m.Return(m.Float32Abs(m.Parameter(0)));
Ben Murdochda12d292016-06-02 14:46:10 +01005476 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(std::abs(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005477}
5478
5479
5480TEST(RunFloat64Abs) {
5481 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5482 m.Return(m.Float64Abs(m.Parameter(0)));
Ben Murdochda12d292016-06-02 14:46:10 +01005483 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(std::abs(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005484}
5485
5486
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005487static double two_30 = 1 << 30; // 2^30 is a smi boundary.
5488static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary.
5489static double kValues[] = {0.1,
5490 0.2,
5491 0.49999999999999994,
5492 0.5,
5493 0.7,
5494 1.0 - std::numeric_limits<double>::epsilon(),
5495 -0.1,
5496 -0.49999999999999994,
5497 -0.5,
5498 -0.7,
5499 1.1,
5500 1.0 + std::numeric_limits<double>::epsilon(),
5501 1.5,
5502 1.7,
5503 -1,
5504 -1 + std::numeric_limits<double>::epsilon(),
5505 -1 - std::numeric_limits<double>::epsilon(),
5506 -1.1,
5507 -1.5,
5508 -1.7,
5509 std::numeric_limits<double>::min(),
5510 -std::numeric_limits<double>::min(),
5511 std::numeric_limits<double>::max(),
5512 -std::numeric_limits<double>::max(),
5513 std::numeric_limits<double>::infinity(),
5514 -std::numeric_limits<double>::infinity(),
5515 two_30,
5516 two_30 + 0.1,
5517 two_30 + 0.5,
5518 two_30 + 0.7,
5519 two_30 - 1,
5520 two_30 - 1 + 0.1,
5521 two_30 - 1 + 0.5,
5522 two_30 - 1 + 0.7,
5523 -two_30,
5524 -two_30 + 0.1,
5525 -two_30 + 0.5,
5526 -two_30 + 0.7,
5527 -two_30 + 1,
5528 -two_30 + 1 + 0.1,
5529 -two_30 + 1 + 0.5,
5530 -two_30 + 1 + 0.7,
5531 two_52,
5532 two_52 + 0.1,
5533 two_52 + 0.5,
5534 two_52 + 0.5,
5535 two_52 + 0.7,
5536 two_52 + 0.7,
5537 two_52 - 1,
5538 two_52 - 1 + 0.1,
5539 two_52 - 1 + 0.5,
5540 two_52 - 1 + 0.7,
5541 -two_52,
5542 -two_52 + 0.1,
5543 -two_52 + 0.5,
5544 -two_52 + 0.7,
5545 -two_52 + 1,
5546 -two_52 + 1 + 0.1,
5547 -two_52 + 1 + 0.5,
5548 -two_52 + 1 + 0.7,
5549 two_30,
5550 two_30 - 0.1,
5551 two_30 - 0.5,
5552 two_30 - 0.7,
5553 two_30 - 1,
5554 two_30 - 1 - 0.1,
5555 two_30 - 1 - 0.5,
5556 two_30 - 1 - 0.7,
5557 -two_30,
5558 -two_30 - 0.1,
5559 -two_30 - 0.5,
5560 -two_30 - 0.7,
5561 -two_30 + 1,
5562 -two_30 + 1 - 0.1,
5563 -two_30 + 1 - 0.5,
5564 -two_30 + 1 - 0.7,
5565 two_52,
5566 two_52 - 0.1,
5567 two_52 - 0.5,
5568 two_52 - 0.5,
5569 two_52 - 0.7,
5570 two_52 - 0.7,
5571 two_52 - 1,
5572 two_52 - 1 - 0.1,
5573 two_52 - 1 - 0.5,
5574 two_52 - 1 - 0.7,
5575 -two_52,
5576 -two_52 - 0.1,
5577 -two_52 - 0.5,
5578 -two_52 - 0.7,
5579 -two_52 + 1,
5580 -two_52 + 1 - 0.1,
5581 -two_52 + 1 - 0.5,
5582 -two_52 + 1 - 0.7};
5583
5584
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005585TEST(RunFloat32RoundDown) {
5586 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5587 if (!m.machine()->Float32RoundDown().IsSupported()) return;
5588
5589 m.Return(m.Float32RoundDown(m.Parameter(0)));
5590
Ben Murdochda12d292016-06-02 14:46:10 +01005591 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(floorf(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005592}
5593
5594
5595TEST(RunFloat64RoundDown1) {
5596 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5597 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5598
5599 m.Return(m.Float64RoundDown(m.Parameter(0)));
5600
Ben Murdochda12d292016-06-02 14:46:10 +01005601 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(floor(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005602}
5603
5604
5605TEST(RunFloat64RoundDown2) {
5606 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5607 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5608 m.Return(m.Float64Sub(m.Float64Constant(-0.0),
5609 m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
5610 m.Parameter(0)))));
5611
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005612 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005613 CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005614 }
5615}
5616
5617
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005618TEST(RunFloat32RoundUp) {
5619 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5620 if (!m.machine()->Float32RoundUp().IsSupported()) return;
5621 m.Return(m.Float32RoundUp(m.Parameter(0)));
5622
Ben Murdochda12d292016-06-02 14:46:10 +01005623 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(ceilf(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005624}
5625
5626
5627TEST(RunFloat64RoundUp) {
5628 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5629 if (!m.machine()->Float64RoundUp().IsSupported()) return;
5630 m.Return(m.Float64RoundUp(m.Parameter(0)));
5631
Ben Murdochda12d292016-06-02 14:46:10 +01005632 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(ceil(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005633}
5634
5635
5636TEST(RunFloat32RoundTiesEven) {
5637 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5638 if (!m.machine()->Float32RoundTiesEven().IsSupported()) return;
5639 m.Return(m.Float32RoundTiesEven(m.Parameter(0)));
5640
Ben Murdochda12d292016-06-02 14:46:10 +01005641 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyint(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005642}
5643
5644
5645TEST(RunFloat64RoundTiesEven) {
5646 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5647 if (!m.machine()->Float64RoundTiesEven().IsSupported()) return;
5648 m.Return(m.Float64RoundTiesEven(m.Parameter(0)));
5649
Ben Murdochda12d292016-06-02 14:46:10 +01005650 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005651}
5652
5653
5654TEST(RunFloat32RoundTruncate) {
5655 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5656 if (!m.machine()->Float32RoundTruncate().IsSupported()) return;
5657
5658 m.Return(m.Float32RoundTruncate(m.Parameter(0)));
5659
Ben Murdochda12d292016-06-02 14:46:10 +01005660 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(truncf(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005661}
5662
5663
5664TEST(RunFloat64RoundTruncate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005665 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5666 if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
5667 m.Return(m.Float64RoundTruncate(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005668 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005669 CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005670 }
5671}
5672
5673
5674TEST(RunFloat64RoundTiesAway) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005675 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5676 if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
5677 m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005678 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005679 CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005680 }
5681}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005682
5683
5684#if !USE_SIMULATOR
5685
5686namespace {
5687
5688int32_t const kMagicFoo0 = 0xdeadbeef;
5689
5690
5691int32_t foo0() { return kMagicFoo0; }
5692
5693
5694int32_t foo1(int32_t x) { return x; }
5695
5696
5697int32_t foo2(int32_t x, int32_t y) { return x - y; }
5698
5699
5700int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
5701 int32_t g, int32_t h) {
5702 return a + b + c + d + e + f + g + h;
5703}
5704
5705} // namespace
5706
5707
5708TEST(RunCallCFunction0) {
5709 auto* foo0_ptr = &foo0;
5710 RawMachineAssemblerTester<int32_t> m;
5711 Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer());
5712 m.Return(m.CallCFunction0(MachineType::Int32(), function));
5713 CHECK_EQ(kMagicFoo0, m.Call());
5714}
5715
5716
5717TEST(RunCallCFunction1) {
5718 auto* foo1_ptr = &foo1;
5719 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5720 Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer());
5721 m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(),
5722 function, m.Parameter(0)));
5723 FOR_INT32_INPUTS(i) {
5724 int32_t const expected = *i;
5725 CHECK_EQ(expected, m.Call(expected));
5726 }
5727}
5728
5729
5730TEST(RunCallCFunction2) {
5731 auto* foo2_ptr = &foo2;
5732 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5733 MachineType::Int32());
5734 Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer());
5735 m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(),
5736 MachineType::Int32(), function, m.Parameter(0),
5737 m.Parameter(1)));
5738 FOR_INT32_INPUTS(i) {
5739 int32_t const x = *i;
5740 FOR_INT32_INPUTS(j) {
5741 int32_t const y = *j;
5742 CHECK_EQ(x - y, m.Call(x, y));
5743 }
5744 }
5745}
5746
5747
5748TEST(RunCallCFunction8) {
5749 auto* foo8_ptr = &foo8;
5750 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5751 Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer());
5752 Node* param = m.Parameter(0);
5753 m.Return(m.CallCFunction8(
5754 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5755 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5756 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5757 function, param, param, param, param, param, param, param, param));
5758 FOR_INT32_INPUTS(i) {
5759 int32_t const x = *i;
5760 CHECK_EQ(x * 8, m.Call(x));
5761 }
5762}
5763#endif // USE_SIMULATOR
5764
5765#if V8_TARGET_ARCH_64_BIT
5766// TODO(titzer): run int64 tests on all platforms when supported.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005767
5768TEST(RunBitcastInt64ToFloat64) {
5769 int64_t input = 1;
5770 double output = 0.0;
5771 RawMachineAssemblerTester<int32_t> m;
5772 m.StoreToPointer(
5773 &output, MachineRepresentation::kFloat64,
5774 m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64())));
5775 m.Return(m.Int32Constant(11));
5776 FOR_INT64_INPUTS(i) {
5777 input = *i;
5778 CHECK_EQ(11, m.Call());
5779 double expected = bit_cast<double>(input);
5780 CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output));
5781 }
5782}
5783
5784
5785TEST(RunBitcastFloat64ToInt64) {
5786 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5787
5788 m.Return(m.BitcastFloat64ToInt64(m.Parameter(0)));
5789 FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); }
5790}
5791
5792
5793TEST(RunTryTruncateFloat32ToInt64WithoutCheck) {
5794 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5795 m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0)));
5796
5797 FOR_INT64_INPUTS(i) {
5798 float input = static_cast<float>(*i);
5799 if (input < static_cast<float>(INT64_MAX) &&
5800 input >= static_cast<float>(INT64_MIN)) {
5801 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5802 }
5803 }
5804}
5805
5806
5807TEST(RunTryTruncateFloat32ToInt64WithCheck) {
5808 int64_t success = 0;
5809 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5810 Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0));
5811 Node* val = m.Projection(0, trunc);
5812 Node* check = m.Projection(1, trunc);
5813 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5814 m.Return(val);
5815
5816 FOR_FLOAT32_INPUTS(i) {
5817 if (*i < static_cast<float>(INT64_MAX) &&
5818 *i >= static_cast<float>(INT64_MIN)) {
5819 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5820 CHECK_NE(0, success);
5821 } else {
5822 m.Call(*i);
5823 CHECK_EQ(0, success);
5824 }
5825 }
5826}
5827
5828
5829TEST(RunTryTruncateFloat64ToInt64WithoutCheck) {
5830 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5831 m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0)));
5832
5833 FOR_INT64_INPUTS(i) {
5834 double input = static_cast<double>(*i);
5835 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5836 }
5837}
5838
5839
5840TEST(RunTryTruncateFloat64ToInt64WithCheck) {
5841 int64_t success = 0;
5842 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5843 Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0));
5844 Node* val = m.Projection(0, trunc);
5845 Node* check = m.Projection(1, trunc);
5846 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5847 m.Return(val);
5848
5849 FOR_FLOAT64_INPUTS(i) {
5850 if (*i < static_cast<double>(INT64_MAX) &&
5851 *i >= static_cast<double>(INT64_MIN)) {
5852 // Conversions within this range should succeed.
5853 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5854 CHECK_NE(0, success);
5855 } else {
5856 m.Call(*i);
5857 CHECK_EQ(0, success);
5858 }
5859 }
5860}
5861
5862
5863TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
5864 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5865 m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
5866
5867 FOR_UINT64_INPUTS(i) {
5868 float input = static_cast<float>(*i);
5869 // This condition on 'input' is required because
5870 // static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
5871 if (input < static_cast<float>(UINT64_MAX)) {
5872 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5873 }
5874 }
5875}
5876
5877
5878TEST(RunTryTruncateFloat32ToUint64WithCheck) {
5879 int64_t success = 0;
5880 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5881 Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0));
5882 Node* val = m.Projection(0, trunc);
5883 Node* check = m.Projection(1, trunc);
5884 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5885 m.Return(val);
5886
5887 FOR_FLOAT32_INPUTS(i) {
5888 if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
5889 // Conversions within this range should succeed.
5890 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5891 CHECK_NE(0, success);
5892 } else {
5893 m.Call(*i);
5894 CHECK_EQ(0, success);
5895 }
5896 }
5897}
5898
5899
5900TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
5901 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64());
Ben Murdochda12d292016-06-02 14:46:10 +01005902 m.Return(m.TryTruncateFloat64ToUint64(m.Parameter(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005903
5904 FOR_UINT64_INPUTS(j) {
5905 double input = static_cast<double>(*j);
5906
5907 if (input < static_cast<float>(UINT64_MAX)) {
5908 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5909 }
5910 }
5911}
5912
5913
5914TEST(RunTryTruncateFloat64ToUint64WithCheck) {
5915 int64_t success = 0;
5916 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5917 Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0));
5918 Node* val = m.Projection(0, trunc);
5919 Node* check = m.Projection(1, trunc);
5920 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5921 m.Return(val);
5922
5923 FOR_FLOAT64_INPUTS(i) {
5924 if (*i < 18446744073709551616.0 && *i > -1) {
5925 // Conversions within this range should succeed.
5926 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5927 CHECK_NE(0, success);
5928 } else {
5929 m.Call(*i);
5930 CHECK_EQ(0, success);
5931 }
5932 }
5933}
5934
5935
5936TEST(RunRoundInt64ToFloat32) {
5937 BufferedRawMachineAssemblerTester<float> m(MachineType::Int64());
5938 m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
5939 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
5940}
5941
5942
5943TEST(RunRoundInt64ToFloat64) {
5944 BufferedRawMachineAssemblerTester<double> m(MachineType::Int64());
5945 m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
5946 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); }
5947}
5948
5949
5950TEST(RunRoundUint64ToFloat64) {
5951 struct {
5952 uint64_t input;
5953 uint64_t expected;
5954 } values[] = {{0x0, 0x0},
5955 {0x1, 0x3ff0000000000000},
5956 {0xffffffff, 0x41efffffffe00000},
5957 {0x1b09788b, 0x41bb09788b000000},
5958 {0x4c5fce8, 0x419317f3a0000000},
5959 {0xcc0de5bf, 0x41e981bcb7e00000},
5960 {0x2, 0x4000000000000000},
5961 {0x3, 0x4008000000000000},
5962 {0x4, 0x4010000000000000},
5963 {0x5, 0x4014000000000000},
5964 {0x8, 0x4020000000000000},
5965 {0x9, 0x4022000000000000},
5966 {0xffffffffffffffff, 0x43f0000000000000},
5967 {0xfffffffffffffffe, 0x43f0000000000000},
5968 {0xfffffffffffffffd, 0x43f0000000000000},
5969 {0x100000000, 0x41f0000000000000},
5970 {0xffffffff00000000, 0x43efffffffe00000},
5971 {0x1b09788b00000000, 0x43bb09788b000000},
5972 {0x4c5fce800000000, 0x439317f3a0000000},
5973 {0xcc0de5bf00000000, 0x43e981bcb7e00000},
5974 {0x200000000, 0x4200000000000000},
5975 {0x300000000, 0x4208000000000000},
5976 {0x400000000, 0x4210000000000000},
5977 {0x500000000, 0x4214000000000000},
5978 {0x800000000, 0x4220000000000000},
5979 {0x900000000, 0x4222000000000000},
5980 {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
5981 {0xece3af835495a16b, 0x43ed9c75f06a92b4},
5982 {0xb668ecc11223344, 0x43a6cd1d98224467},
5983 {0x9e, 0x4063c00000000000},
5984 {0x43, 0x4050c00000000000},
5985 {0xaf73, 0x40e5ee6000000000},
5986 {0x116b, 0x40b16b0000000000},
5987 {0x658ecc, 0x415963b300000000},
5988 {0x2b3b4c, 0x41459da600000000},
5989 {0x88776655, 0x41e10eeccaa00000},
5990 {0x70000000, 0x41dc000000000000},
5991 {0x7200000, 0x419c800000000000},
5992 {0x7fffffff, 0x41dfffffffc00000},
5993 {0x56123761, 0x41d5848dd8400000},
5994 {0x7fffff00, 0x41dfffffc0000000},
5995 {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
5996 {0x80000000eeeeeeee, 0x43e00000001dddde},
5997 {0x88888888dddddddd, 0x43e11111111bbbbc},
5998 {0xa0000000dddddddd, 0x43e40000001bbbbc},
5999 {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
6000 {0xe0000000aaaaaaaa, 0x43ec000000155555},
6001 {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
6002 {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
6003 {0xf0000000dddddddd, 0x43ee0000001bbbbc},
6004 {0x7fffffdddddddd, 0x435ffffff7777777},
6005 {0x3fffffaaaaaaaa, 0x434fffffd5555555},
6006 {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
6007 {0xfffff, 0x412ffffe00000000},
6008 {0x7ffff, 0x411ffffc00000000},
6009 {0x3ffff, 0x410ffff800000000},
6010 {0x1ffff, 0x40fffff000000000},
6011 {0xffff, 0x40efffe000000000},
6012 {0x7fff, 0x40dfffc000000000},
6013 {0x3fff, 0x40cfff8000000000},
6014 {0x1fff, 0x40bfff0000000000},
6015 {0xfff, 0x40affe0000000000},
6016 {0x7ff, 0x409ffc0000000000},
6017 {0x3ff, 0x408ff80000000000},
6018 {0x1ff, 0x407ff00000000000},
6019 {0x3fffffffffff, 0x42cfffffffffff80},
6020 {0x1fffffffffff, 0x42bfffffffffff00},
6021 {0xfffffffffff, 0x42affffffffffe00},
6022 {0x7ffffffffff, 0x429ffffffffffc00},
6023 {0x3ffffffffff, 0x428ffffffffff800},
6024 {0x1ffffffffff, 0x427ffffffffff000},
6025 {0x8000008000000000, 0x43e0000010000000},
6026 {0x8000008000000001, 0x43e0000010000000},
6027 {0x8000000000000400, 0x43e0000000000000},
6028 {0x8000000000000401, 0x43e0000000000001}};
6029
6030 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64());
6031 m.Return(m.RoundUint64ToFloat64(m.Parameter(0)));
6032
6033 for (size_t i = 0; i < arraysize(values); i++) {
6034 CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input));
6035 }
6036}
6037
6038
6039TEST(RunRoundUint64ToFloat32) {
6040 struct {
6041 uint64_t input;
6042 uint32_t expected;
6043 } values[] = {{0x0, 0x0},
6044 {0x1, 0x3f800000},
6045 {0xffffffff, 0x4f800000},
6046 {0x1b09788b, 0x4dd84bc4},
6047 {0x4c5fce8, 0x4c98bf9d},
6048 {0xcc0de5bf, 0x4f4c0de6},
6049 {0x2, 0x40000000},
6050 {0x3, 0x40400000},
6051 {0x4, 0x40800000},
6052 {0x5, 0x40a00000},
6053 {0x8, 0x41000000},
6054 {0x9, 0x41100000},
6055 {0xffffffffffffffff, 0x5f800000},
6056 {0xfffffffffffffffe, 0x5f800000},
6057 {0xfffffffffffffffd, 0x5f800000},
6058 {0x0, 0x0},
6059 {0x100000000, 0x4f800000},
6060 {0xffffffff00000000, 0x5f800000},
6061 {0x1b09788b00000000, 0x5dd84bc4},
6062 {0x4c5fce800000000, 0x5c98bf9d},
6063 {0xcc0de5bf00000000, 0x5f4c0de6},
6064 {0x200000000, 0x50000000},
6065 {0x300000000, 0x50400000},
6066 {0x400000000, 0x50800000},
6067 {0x500000000, 0x50a00000},
6068 {0x800000000, 0x51000000},
6069 {0x900000000, 0x51100000},
6070 {0x273a798e187937a3, 0x5e1ce9e6},
6071 {0xece3af835495a16b, 0x5f6ce3b0},
6072 {0xb668ecc11223344, 0x5d3668ed},
6073 {0x9e, 0x431e0000},
6074 {0x43, 0x42860000},
6075 {0xaf73, 0x472f7300},
6076 {0x116b, 0x458b5800},
6077 {0x658ecc, 0x4acb1d98},
6078 {0x2b3b4c, 0x4a2ced30},
6079 {0x88776655, 0x4f087766},
6080 {0x70000000, 0x4ee00000},
6081 {0x7200000, 0x4ce40000},
6082 {0x7fffffff, 0x4f000000},
6083 {0x56123761, 0x4eac246f},
6084 {0x7fffff00, 0x4efffffe},
6085 {0x761c4761eeeeeeee, 0x5eec388f},
6086 {0x80000000eeeeeeee, 0x5f000000},
6087 {0x88888888dddddddd, 0x5f088889},
6088 {0xa0000000dddddddd, 0x5f200000},
6089 {0xddddddddaaaaaaaa, 0x5f5dddde},
6090 {0xe0000000aaaaaaaa, 0x5f600000},
6091 {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
6092 {0xfffffffdeeeeeeee, 0x5f800000},
6093 {0xf0000000dddddddd, 0x5f700000},
6094 {0x7fffffdddddddd, 0x5b000000},
6095 {0x3fffffaaaaaaaa, 0x5a7fffff},
6096 {0x1fffffaaaaaaaa, 0x59fffffd},
6097 {0xfffff, 0x497ffff0},
6098 {0x7ffff, 0x48ffffe0},
6099 {0x3ffff, 0x487fffc0},
6100 {0x1ffff, 0x47ffff80},
6101 {0xffff, 0x477fff00},
6102 {0x7fff, 0x46fffe00},
6103 {0x3fff, 0x467ffc00},
6104 {0x1fff, 0x45fff800},
6105 {0xfff, 0x457ff000},
6106 {0x7ff, 0x44ffe000},
6107 {0x3ff, 0x447fc000},
6108 {0x1ff, 0x43ff8000},
6109 {0x3fffffffffff, 0x56800000},
6110 {0x1fffffffffff, 0x56000000},
6111 {0xfffffffffff, 0x55800000},
6112 {0x7ffffffffff, 0x55000000},
6113 {0x3ffffffffff, 0x54800000},
6114 {0x1ffffffffff, 0x54000000},
6115 {0x8000008000000000, 0x5f000000},
6116 {0x8000008000000001, 0x5f000001},
6117 {0x8000000000000400, 0x5f000000},
6118 {0x8000000000000401, 0x5f000000}};
6119
6120 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64());
6121 m.Return(m.RoundUint64ToFloat32(m.Parameter(0)));
6122
6123 for (size_t i = 0; i < arraysize(values); i++) {
6124 CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input));
6125 }
6126}
6127
6128
6129#endif
6130
6131
6132TEST(RunBitcastFloat32ToInt32) {
6133 float input = 32.25;
6134 RawMachineAssemblerTester<int32_t> m;
6135 m.Return(m.BitcastFloat32ToInt32(
6136 m.LoadFromPointer(&input, MachineType::Float32())));
6137 FOR_FLOAT32_INPUTS(i) {
6138 input = *i;
6139 int32_t expected = bit_cast<int32_t>(input);
6140 CHECK_EQ(expected, m.Call());
6141 }
6142}
6143
6144
Ben Murdoch097c5b22016-05-18 11:27:45 +01006145TEST(RunRoundInt32ToFloat32) {
6146 BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
6147 m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
6148 FOR_INT32_INPUTS(i) {
6149 volatile float expected = static_cast<float>(*i);
6150 CHECK_EQ(expected, m.Call(*i));
6151 }
6152}
6153
6154
6155TEST(RunRoundUint32ToFloat32) {
6156 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint32());
6157 m.Return(m.RoundUint32ToFloat32(m.Parameter(0)));
6158 FOR_UINT32_INPUTS(i) {
6159 volatile float expected = static_cast<float>(*i);
6160 CHECK_EQ(expected, m.Call(*i));
6161 }
6162}
6163
6164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006165TEST(RunBitcastInt32ToFloat32) {
6166 int32_t input = 1;
6167 float output = 0.0;
6168 RawMachineAssemblerTester<int32_t> m;
6169 m.StoreToPointer(
6170 &output, MachineRepresentation::kFloat32,
6171 m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32())));
6172 m.Return(m.Int32Constant(11));
6173 FOR_INT32_INPUTS(i) {
6174 input = *i;
6175 CHECK_EQ(11, m.Call());
6176 float expected = bit_cast<float>(input);
6177 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output));
6178 }
6179}
6180
6181
6182TEST(RunComputedCodeObject) {
6183 GraphBuilderTester<int32_t> a;
6184 a.Return(a.Int32Constant(33));
6185 a.End();
6186 Handle<Code> code_a = a.GetCode();
6187
6188 GraphBuilderTester<int32_t> b;
6189 b.Return(b.Int32Constant(44));
6190 b.End();
6191 Handle<Code> code_b = b.GetCode();
6192
6193 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6194 RawMachineLabel tlabel;
6195 RawMachineLabel flabel;
6196 RawMachineLabel merge;
6197 r.Branch(r.Parameter(0), &tlabel, &flabel);
6198 r.Bind(&tlabel);
6199 Node* fa = r.HeapConstant(code_a);
6200 r.Goto(&merge);
6201 r.Bind(&flabel);
6202 Node* fb = r.HeapConstant(code_b);
6203 r.Goto(&merge);
6204 r.Bind(&merge);
6205 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6206
6207 // TODO(titzer): all this descriptor hackery is just to call the above
6208 // functions as code objects instead of direct addresses.
6209 CSignature0<int32_t> sig;
6210 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig);
6211 LinkageLocation ret[] = {c->GetReturnLocation(0)};
6212 Signature<LinkageLocation> loc(1, 0, ret);
6213 CallDescriptor* desc = new (r.zone()) CallDescriptor( // --
6214 CallDescriptor::kCallCodeObject, // kind
6215 MachineType::AnyTagged(), // target_type
6216 c->GetInputLocation(0), // target_loc
6217 &sig, // machine_sig
6218 &loc, // location_sig
6219 0, // stack count
6220 Operator::kNoProperties, // properties
6221 c->CalleeSavedRegisters(), // callee saved
6222 c->CalleeSavedFPRegisters(), // callee saved FP
6223 CallDescriptor::kNoFlags, // flags
6224 "c-call-as-code");
6225 Node* call = r.AddNode(r.common()->Call(desc), phi);
6226 r.Return(call);
6227
6228 CHECK_EQ(33, r.Call(1));
6229 CHECK_EQ(44, r.Call(0));
6230}
6231
Ben Murdoch097c5b22016-05-18 11:27:45 +01006232TEST(ParentFramePointer) {
6233 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6234 RawMachineLabel tlabel;
6235 RawMachineLabel flabel;
6236 RawMachineLabel merge;
6237 Node* frame = r.LoadFramePointer();
6238 Node* parent_frame = r.LoadParentFramePointer();
6239 frame = r.Load(MachineType::IntPtr(), frame);
6240 r.Branch(r.WordEqual(frame, parent_frame), &tlabel, &flabel);
6241 r.Bind(&tlabel);
6242 Node* fa = r.Int32Constant(1);
6243 r.Goto(&merge);
6244 r.Bind(&flabel);
6245 Node* fb = r.Int32Constant(0);
6246 r.Goto(&merge);
6247 r.Bind(&merge);
6248 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6249 r.Return(phi);
6250 CHECK_EQ(1, r.Call(1));
6251}
6252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006253} // namespace compiler
6254} // namespace internal
6255} // namespace v8