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