blob: 2bfe1244beed38b15c6b7cb27fa0073503f3ac2d [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2014 the V8 project authors. All rights reserved. Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include <cmath>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006#include <functional>
7#include <limits>
8
9#include "src/base/bits.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/base/utils/random-number-generator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040011#include "src/codegen.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "test/cctest/cctest.h"
13#include "test/cctest/compiler/codegen-tester.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "test/cctest/compiler/graph-builder-tester.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#include "test/cctest/compiler/value-helper.h"
16
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017using namespace v8::base;
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019namespace v8 {
20namespace internal {
21namespace compiler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023
24TEST(RunInt32Add) {
25 RawMachineAssemblerTester<int32_t> m;
26 Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1));
27 m.Return(add);
28 CHECK_EQ(1, m.Call());
29}
30
31
Ben Murdoch097c5b22016-05-18 11:27:45 +010032TEST(RunWord32ReverseBits) {
33 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
34 if (!m.machine()->Word32ReverseBits().IsSupported()) {
35 // We can only test the operator if it exists on the testing platform.
36 return;
37 }
38 m.Return(m.AddNode(m.machine()->Word32ReverseBits().op(), m.Parameter(0)));
39
40 CHECK_EQ(uint32_t(0x00000000), m.Call(uint32_t(0x00000000)));
41 CHECK_EQ(uint32_t(0x12345678), m.Call(uint32_t(0x1e6a2c48)));
42 CHECK_EQ(uint32_t(0xfedcba09), m.Call(uint32_t(0x905d3b7f)));
43 CHECK_EQ(uint32_t(0x01010101), m.Call(uint32_t(0x80808080)));
44 CHECK_EQ(uint32_t(0x01020408), m.Call(uint32_t(0x10204080)));
45 CHECK_EQ(uint32_t(0xf0703010), m.Call(uint32_t(0x080c0e0f)));
46 CHECK_EQ(uint32_t(0x1f8d0a3a), m.Call(uint32_t(0x5c50b1f8)));
47 CHECK_EQ(uint32_t(0xffffffff), m.Call(uint32_t(0xffffffff)));
48}
49
50
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051TEST(RunWord32Ctz) {
52 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
53 if (!m.machine()->Word32Ctz().IsSupported()) {
54 // We can only test the operator if it exists on the testing platform.
55 return;
56 }
57 m.Return(m.AddNode(m.machine()->Word32Ctz().op(), m.Parameter(0)));
58
59 CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
60 CHECK_EQ(31, m.Call(uint32_t(0x80000000)));
61 CHECK_EQ(30, m.Call(uint32_t(0x40000000)));
62 CHECK_EQ(29, m.Call(uint32_t(0x20000000)));
63 CHECK_EQ(28, m.Call(uint32_t(0x10000000)));
64 CHECK_EQ(27, m.Call(uint32_t(0xa8000000)));
65 CHECK_EQ(26, m.Call(uint32_t(0xf4000000)));
66 CHECK_EQ(25, m.Call(uint32_t(0x62000000)));
67 CHECK_EQ(24, m.Call(uint32_t(0x91000000)));
68 CHECK_EQ(23, m.Call(uint32_t(0xcd800000)));
69 CHECK_EQ(22, m.Call(uint32_t(0x09400000)));
70 CHECK_EQ(21, m.Call(uint32_t(0xaf200000)));
71 CHECK_EQ(20, m.Call(uint32_t(0xac100000)));
72 CHECK_EQ(19, m.Call(uint32_t(0xe0b80000)));
73 CHECK_EQ(18, m.Call(uint32_t(0x9ce40000)));
74 CHECK_EQ(17, m.Call(uint32_t(0xc7920000)));
75 CHECK_EQ(16, m.Call(uint32_t(0xb8f10000)));
76 CHECK_EQ(15, m.Call(uint32_t(0x3b9f8000)));
77 CHECK_EQ(14, m.Call(uint32_t(0xdb4c4000)));
78 CHECK_EQ(13, m.Call(uint32_t(0xe9a32000)));
79 CHECK_EQ(12, m.Call(uint32_t(0xfca61000)));
80 CHECK_EQ(11, m.Call(uint32_t(0x6c8a7800)));
81 CHECK_EQ(10, m.Call(uint32_t(0x8ce5a400)));
82 CHECK_EQ(9, m.Call(uint32_t(0xcb7d0200)));
83 CHECK_EQ(8, m.Call(uint32_t(0xcb4dc100)));
84 CHECK_EQ(7, m.Call(uint32_t(0xdfbec580)));
85 CHECK_EQ(6, m.Call(uint32_t(0x27a9db40)));
86 CHECK_EQ(5, m.Call(uint32_t(0xde3bcb20)));
87 CHECK_EQ(4, m.Call(uint32_t(0xd7e8a610)));
88 CHECK_EQ(3, m.Call(uint32_t(0x9afdbc88)));
89 CHECK_EQ(2, m.Call(uint32_t(0x9afdbc84)));
90 CHECK_EQ(1, m.Call(uint32_t(0x9afdbc82)));
91 CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
92}
93
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000094TEST(RunWord32Clz) {
95 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
96 m.Return(m.Word32Clz(m.Parameter(0)));
97
98 CHECK_EQ(0, m.Call(uint32_t(0x80001000)));
99 CHECK_EQ(1, m.Call(uint32_t(0x40000500)));
100 CHECK_EQ(2, m.Call(uint32_t(0x20000300)));
101 CHECK_EQ(3, m.Call(uint32_t(0x10000003)));
102 CHECK_EQ(4, m.Call(uint32_t(0x08050000)));
103 CHECK_EQ(5, m.Call(uint32_t(0x04006000)));
104 CHECK_EQ(6, m.Call(uint32_t(0x02000000)));
105 CHECK_EQ(7, m.Call(uint32_t(0x010000a0)));
106 CHECK_EQ(8, m.Call(uint32_t(0x00800c00)));
107 CHECK_EQ(9, m.Call(uint32_t(0x00400000)));
108 CHECK_EQ(10, m.Call(uint32_t(0x0020000d)));
109 CHECK_EQ(11, m.Call(uint32_t(0x00100f00)));
110 CHECK_EQ(12, m.Call(uint32_t(0x00080000)));
111 CHECK_EQ(13, m.Call(uint32_t(0x00041000)));
112 CHECK_EQ(14, m.Call(uint32_t(0x00020020)));
113 CHECK_EQ(15, m.Call(uint32_t(0x00010300)));
114 CHECK_EQ(16, m.Call(uint32_t(0x00008040)));
115 CHECK_EQ(17, m.Call(uint32_t(0x00004005)));
116 CHECK_EQ(18, m.Call(uint32_t(0x00002050)));
117 CHECK_EQ(19, m.Call(uint32_t(0x00001700)));
118 CHECK_EQ(20, m.Call(uint32_t(0x00000870)));
119 CHECK_EQ(21, m.Call(uint32_t(0x00000405)));
120 CHECK_EQ(22, m.Call(uint32_t(0x00000203)));
121 CHECK_EQ(23, m.Call(uint32_t(0x00000101)));
122 CHECK_EQ(24, m.Call(uint32_t(0x00000089)));
123 CHECK_EQ(25, m.Call(uint32_t(0x00000041)));
124 CHECK_EQ(26, m.Call(uint32_t(0x00000022)));
125 CHECK_EQ(27, m.Call(uint32_t(0x00000013)));
126 CHECK_EQ(28, m.Call(uint32_t(0x00000008)));
127 CHECK_EQ(29, m.Call(uint32_t(0x00000004)));
128 CHECK_EQ(30, m.Call(uint32_t(0x00000002)));
129 CHECK_EQ(31, m.Call(uint32_t(0x00000001)));
130 CHECK_EQ(32, m.Call(uint32_t(0x00000000)));
131}
132
133
134TEST(RunWord32Popcnt) {
135 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
136 if (!m.machine()->Word32Popcnt().IsSupported()) {
137 // We can only test the operator if it exists on the testing platform.
138 return;
139 }
140 m.Return(m.AddNode(m.machine()->Word32Popcnt().op(), m.Parameter(0)));
141
142 CHECK_EQ(0, m.Call(uint32_t(0x00000000)));
143 CHECK_EQ(1, m.Call(uint32_t(0x00000001)));
144 CHECK_EQ(1, m.Call(uint32_t(0x80000000)));
145 CHECK_EQ(32, m.Call(uint32_t(0xffffffff)));
146 CHECK_EQ(6, m.Call(uint32_t(0x000dc100)));
147 CHECK_EQ(9, m.Call(uint32_t(0xe00dc100)));
148 CHECK_EQ(11, m.Call(uint32_t(0xe00dc103)));
149 CHECK_EQ(9, m.Call(uint32_t(0x000dc107)));
150}
151
152
153#if V8_TARGET_ARCH_64_BIT
Ben Murdoch097c5b22016-05-18 11:27:45 +0100154TEST(RunWord64ReverseBits) {
155 RawMachineAssemblerTester<uint64_t> m(MachineType::Uint64());
156 if (!m.machine()->Word64ReverseBits().IsSupported()) {
157 return;
158 }
159
160 m.Return(m.AddNode(m.machine()->Word64ReverseBits().op(), m.Parameter(0)));
161
162 CHECK_EQ(uint64_t(0x0000000000000000), m.Call(uint64_t(0x0000000000000000)));
163 CHECK_EQ(uint64_t(0x1234567890abcdef), m.Call(uint64_t(0xf7b3d5091e6a2c48)));
164 CHECK_EQ(uint64_t(0xfedcba0987654321), m.Call(uint64_t(0x84c2a6e1905d3b7f)));
165 CHECK_EQ(uint64_t(0x0101010101010101), m.Call(uint64_t(0x8080808080808080)));
166 CHECK_EQ(uint64_t(0x0102040803060c01), m.Call(uint64_t(0x803060c010204080)));
167 CHECK_EQ(uint64_t(0xf0703010e060200f), m.Call(uint64_t(0xf0040607080c0e0f)));
168 CHECK_EQ(uint64_t(0x2f8a6df01c21fa3b), m.Call(uint64_t(0xdc5f84380fb651f4)));
169 CHECK_EQ(uint64_t(0xffffffffffffffff), m.Call(uint64_t(0xffffffffffffffff)));
170}
171
172
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000173TEST(RunWord64Clz) {
174 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
175 m.Return(m.Word64Clz(m.Parameter(0)));
176
177 CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000)));
178 CHECK_EQ(1, m.Call(uint64_t(0x4000050000000000)));
179 CHECK_EQ(2, m.Call(uint64_t(0x2000030000000000)));
180 CHECK_EQ(3, m.Call(uint64_t(0x1000000300000000)));
181 CHECK_EQ(4, m.Call(uint64_t(0x0805000000000000)));
182 CHECK_EQ(5, m.Call(uint64_t(0x0400600000000000)));
183 CHECK_EQ(6, m.Call(uint64_t(0x0200000000000000)));
184 CHECK_EQ(7, m.Call(uint64_t(0x010000a000000000)));
185 CHECK_EQ(8, m.Call(uint64_t(0x00800c0000000000)));
186 CHECK_EQ(9, m.Call(uint64_t(0x0040000000000000)));
187 CHECK_EQ(10, m.Call(uint64_t(0x0020000d00000000)));
188 CHECK_EQ(11, m.Call(uint64_t(0x00100f0000000000)));
189 CHECK_EQ(12, m.Call(uint64_t(0x0008000000000000)));
190 CHECK_EQ(13, m.Call(uint64_t(0x0004100000000000)));
191 CHECK_EQ(14, m.Call(uint64_t(0x0002002000000000)));
192 CHECK_EQ(15, m.Call(uint64_t(0x0001030000000000)));
193 CHECK_EQ(16, m.Call(uint64_t(0x0000804000000000)));
194 CHECK_EQ(17, m.Call(uint64_t(0x0000400500000000)));
195 CHECK_EQ(18, m.Call(uint64_t(0x0000205000000000)));
196 CHECK_EQ(19, m.Call(uint64_t(0x0000170000000000)));
197 CHECK_EQ(20, m.Call(uint64_t(0x0000087000000000)));
198 CHECK_EQ(21, m.Call(uint64_t(0x0000040500000000)));
199 CHECK_EQ(22, m.Call(uint64_t(0x0000020300000000)));
200 CHECK_EQ(23, m.Call(uint64_t(0x0000010100000000)));
201 CHECK_EQ(24, m.Call(uint64_t(0x0000008900000000)));
202 CHECK_EQ(25, m.Call(uint64_t(0x0000004100000000)));
203 CHECK_EQ(26, m.Call(uint64_t(0x0000002200000000)));
204 CHECK_EQ(27, m.Call(uint64_t(0x0000001300000000)));
205 CHECK_EQ(28, m.Call(uint64_t(0x0000000800000000)));
206 CHECK_EQ(29, m.Call(uint64_t(0x0000000400000000)));
207 CHECK_EQ(30, m.Call(uint64_t(0x0000000200000000)));
208 CHECK_EQ(31, m.Call(uint64_t(0x0000000100000000)));
209 CHECK_EQ(32, m.Call(uint64_t(0x0000000080001000)));
210 CHECK_EQ(33, m.Call(uint64_t(0x0000000040000500)));
211 CHECK_EQ(34, m.Call(uint64_t(0x0000000020000300)));
212 CHECK_EQ(35, m.Call(uint64_t(0x0000000010000003)));
213 CHECK_EQ(36, m.Call(uint64_t(0x0000000008050000)));
214 CHECK_EQ(37, m.Call(uint64_t(0x0000000004006000)));
215 CHECK_EQ(38, m.Call(uint64_t(0x0000000002000000)));
216 CHECK_EQ(39, m.Call(uint64_t(0x00000000010000a0)));
217 CHECK_EQ(40, m.Call(uint64_t(0x0000000000800c00)));
218 CHECK_EQ(41, m.Call(uint64_t(0x0000000000400000)));
219 CHECK_EQ(42, m.Call(uint64_t(0x000000000020000d)));
220 CHECK_EQ(43, m.Call(uint64_t(0x0000000000100f00)));
221 CHECK_EQ(44, m.Call(uint64_t(0x0000000000080000)));
222 CHECK_EQ(45, m.Call(uint64_t(0x0000000000041000)));
223 CHECK_EQ(46, m.Call(uint64_t(0x0000000000020020)));
224 CHECK_EQ(47, m.Call(uint64_t(0x0000000000010300)));
225 CHECK_EQ(48, m.Call(uint64_t(0x0000000000008040)));
226 CHECK_EQ(49, m.Call(uint64_t(0x0000000000004005)));
227 CHECK_EQ(50, m.Call(uint64_t(0x0000000000002050)));
228 CHECK_EQ(51, m.Call(uint64_t(0x0000000000001700)));
229 CHECK_EQ(52, m.Call(uint64_t(0x0000000000000870)));
230 CHECK_EQ(53, m.Call(uint64_t(0x0000000000000405)));
231 CHECK_EQ(54, m.Call(uint64_t(0x0000000000000203)));
232 CHECK_EQ(55, m.Call(uint64_t(0x0000000000000101)));
233 CHECK_EQ(56, m.Call(uint64_t(0x0000000000000089)));
234 CHECK_EQ(57, m.Call(uint64_t(0x0000000000000041)));
235 CHECK_EQ(58, m.Call(uint64_t(0x0000000000000022)));
236 CHECK_EQ(59, m.Call(uint64_t(0x0000000000000013)));
237 CHECK_EQ(60, m.Call(uint64_t(0x0000000000000008)));
238 CHECK_EQ(61, m.Call(uint64_t(0x0000000000000004)));
239 CHECK_EQ(62, m.Call(uint64_t(0x0000000000000002)));
240 CHECK_EQ(63, m.Call(uint64_t(0x0000000000000001)));
241 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
242}
243
244
245TEST(RunWord64Ctz) {
246 RawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
247 if (!m.machine()->Word64Ctz().IsSupported()) {
248 return;
249 }
250
251 m.Return(m.AddNode(m.machine()->Word64Ctz().op(), m.Parameter(0)));
252
253 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000)));
254 CHECK_EQ(63, m.Call(uint64_t(0x8000000000000000)));
255 CHECK_EQ(62, m.Call(uint64_t(0x4000000000000000)));
256 CHECK_EQ(61, m.Call(uint64_t(0x2000000000000000)));
257 CHECK_EQ(60, m.Call(uint64_t(0x1000000000000000)));
258 CHECK_EQ(59, m.Call(uint64_t(0xa800000000000000)));
259 CHECK_EQ(58, m.Call(uint64_t(0xf400000000000000)));
260 CHECK_EQ(57, m.Call(uint64_t(0x6200000000000000)));
261 CHECK_EQ(56, m.Call(uint64_t(0x9100000000000000)));
262 CHECK_EQ(55, m.Call(uint64_t(0xcd80000000000000)));
263 CHECK_EQ(54, m.Call(uint64_t(0x0940000000000000)));
264 CHECK_EQ(53, m.Call(uint64_t(0xaf20000000000000)));
265 CHECK_EQ(52, m.Call(uint64_t(0xac10000000000000)));
266 CHECK_EQ(51, m.Call(uint64_t(0xe0b8000000000000)));
267 CHECK_EQ(50, m.Call(uint64_t(0x9ce4000000000000)));
268 CHECK_EQ(49, m.Call(uint64_t(0xc792000000000000)));
269 CHECK_EQ(48, m.Call(uint64_t(0xb8f1000000000000)));
270 CHECK_EQ(47, m.Call(uint64_t(0x3b9f800000000000)));
271 CHECK_EQ(46, m.Call(uint64_t(0xdb4c400000000000)));
272 CHECK_EQ(45, m.Call(uint64_t(0xe9a3200000000000)));
273 CHECK_EQ(44, m.Call(uint64_t(0xfca6100000000000)));
274 CHECK_EQ(43, m.Call(uint64_t(0x6c8a780000000000)));
275 CHECK_EQ(42, m.Call(uint64_t(0x8ce5a40000000000)));
276 CHECK_EQ(41, m.Call(uint64_t(0xcb7d020000000000)));
277 CHECK_EQ(40, m.Call(uint64_t(0xcb4dc10000000000)));
278 CHECK_EQ(39, m.Call(uint64_t(0xdfbec58000000000)));
279 CHECK_EQ(38, m.Call(uint64_t(0x27a9db4000000000)));
280 CHECK_EQ(37, m.Call(uint64_t(0xde3bcb2000000000)));
281 CHECK_EQ(36, m.Call(uint64_t(0xd7e8a61000000000)));
282 CHECK_EQ(35, m.Call(uint64_t(0x9afdbc8800000000)));
283 CHECK_EQ(34, m.Call(uint64_t(0x9afdbc8400000000)));
284 CHECK_EQ(33, m.Call(uint64_t(0x9afdbc8200000000)));
285 CHECK_EQ(32, m.Call(uint64_t(0x9afdbc8100000000)));
286 CHECK_EQ(31, m.Call(uint64_t(0x0000000080000000)));
287 CHECK_EQ(30, m.Call(uint64_t(0x0000000040000000)));
288 CHECK_EQ(29, m.Call(uint64_t(0x0000000020000000)));
289 CHECK_EQ(28, m.Call(uint64_t(0x0000000010000000)));
290 CHECK_EQ(27, m.Call(uint64_t(0x00000000a8000000)));
291 CHECK_EQ(26, m.Call(uint64_t(0x00000000f4000000)));
292 CHECK_EQ(25, m.Call(uint64_t(0x0000000062000000)));
293 CHECK_EQ(24, m.Call(uint64_t(0x0000000091000000)));
294 CHECK_EQ(23, m.Call(uint64_t(0x00000000cd800000)));
295 CHECK_EQ(22, m.Call(uint64_t(0x0000000009400000)));
296 CHECK_EQ(21, m.Call(uint64_t(0x00000000af200000)));
297 CHECK_EQ(20, m.Call(uint64_t(0x00000000ac100000)));
298 CHECK_EQ(19, m.Call(uint64_t(0x00000000e0b80000)));
299 CHECK_EQ(18, m.Call(uint64_t(0x000000009ce40000)));
300 CHECK_EQ(17, m.Call(uint64_t(0x00000000c7920000)));
301 CHECK_EQ(16, m.Call(uint64_t(0x00000000b8f10000)));
302 CHECK_EQ(15, m.Call(uint64_t(0x000000003b9f8000)));
303 CHECK_EQ(14, m.Call(uint64_t(0x00000000db4c4000)));
304 CHECK_EQ(13, m.Call(uint64_t(0x00000000e9a32000)));
305 CHECK_EQ(12, m.Call(uint64_t(0x00000000fca61000)));
306 CHECK_EQ(11, m.Call(uint64_t(0x000000006c8a7800)));
307 CHECK_EQ(10, m.Call(uint64_t(0x000000008ce5a400)));
308 CHECK_EQ(9, m.Call(uint64_t(0x00000000cb7d0200)));
309 CHECK_EQ(8, m.Call(uint64_t(0x00000000cb4dc100)));
310 CHECK_EQ(7, m.Call(uint64_t(0x00000000dfbec580)));
311 CHECK_EQ(6, m.Call(uint64_t(0x0000000027a9db40)));
312 CHECK_EQ(5, m.Call(uint64_t(0x00000000de3bcb20)));
313 CHECK_EQ(4, m.Call(uint64_t(0x00000000d7e8a610)));
314 CHECK_EQ(3, m.Call(uint64_t(0x000000009afdbc88)));
315 CHECK_EQ(2, m.Call(uint64_t(0x000000009afdbc84)));
316 CHECK_EQ(1, m.Call(uint64_t(0x000000009afdbc82)));
317 CHECK_EQ(0, m.Call(uint64_t(0x000000009afdbc81)));
318}
319
320
321TEST(RunWord64Popcnt) {
322 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
323 if (!m.machine()->Word64Popcnt().IsSupported()) {
324 return;
325 }
326
327 m.Return(m.AddNode(m.machine()->Word64Popcnt().op(), m.Parameter(0)));
328
329 CHECK_EQ(0, m.Call(uint64_t(0x0000000000000000)));
330 CHECK_EQ(1, m.Call(uint64_t(0x0000000000000001)));
331 CHECK_EQ(1, m.Call(uint64_t(0x8000000000000000)));
332 CHECK_EQ(64, m.Call(uint64_t(0xffffffffffffffff)));
333 CHECK_EQ(12, m.Call(uint64_t(0x000dc100000dc100)));
334 CHECK_EQ(18, m.Call(uint64_t(0xe00dc100e00dc100)));
335 CHECK_EQ(22, m.Call(uint64_t(0xe00dc103e00dc103)));
336 CHECK_EQ(18, m.Call(uint64_t(0x000dc107000dc107)));
337}
338#endif // V8_TARGET_ARCH_64_BIT
339
340
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) {
342 switch (index) {
343 case 0:
344 return m->Parameter(0);
345 case 1:
346 return m->Parameter(1);
347 case 2:
348 return m->Int32Constant(0);
349 case 3:
350 return m->Int32Constant(1);
351 case 4:
352 return m->Int32Constant(-1);
353 case 5:
354 return m->Int32Constant(0xff);
355 case 6:
356 return m->Int32Constant(0x01234567);
357 case 7:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358 return m->Load(MachineType::Int32(), m->PointerConstant(NULL));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 default:
360 return NULL;
361 }
362}
363
364
365TEST(CodeGenInt32Binop) {
366 RawMachineAssemblerTester<void> m;
367
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400368 const Operator* kOps[] = {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369 m.machine()->Word32And(), m.machine()->Word32Or(),
370 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
371 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
372 m.machine()->Word32Equal(), m.machine()->Int32Add(),
373 m.machine()->Int32Sub(), m.machine()->Int32Mul(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400374 m.machine()->Int32MulHigh(), m.machine()->Int32Div(),
375 m.machine()->Uint32Div(), m.machine()->Int32Mod(),
376 m.machine()->Uint32Mod(), m.machine()->Uint32MulHigh(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000377 m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400378 m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000379
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400380 for (size_t i = 0; i < arraysize(kOps); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000381 for (int j = 0; j < 8; j++) {
382 for (int k = 0; k < 8; k++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
384 MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 Node* a = Int32Input(&m, j);
386 Node* b = Int32Input(&m, k);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000387 m.Return(m.AddNode(kOps[i], a, b));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388 m.GenerateCode();
389 }
390 }
391 }
392}
393
394
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395TEST(CodeGenNop) {
396 RawMachineAssemblerTester<void> m;
397 m.Return(m.Int32Constant(0));
398 m.GenerateCode();
399}
400
401
402#if V8_TARGET_ARCH_64_BIT
403static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
404 switch (index) {
405 case 0:
406 return m->Parameter(0);
407 case 1:
408 return m->Parameter(1);
409 case 2:
410 return m->Int64Constant(0);
411 case 3:
412 return m->Int64Constant(1);
413 case 4:
414 return m->Int64Constant(-1);
415 case 5:
416 return m->Int64Constant(0xff);
417 case 6:
418 return m->Int64Constant(0x0123456789abcdefLL);
419 case 7:
420 return m->Load(MachineType::Int64(), m->PointerConstant(NULL));
421 default:
422 return NULL;
423 }
424}
425
426
427TEST(CodeGenInt64Binop) {
428 RawMachineAssemblerTester<void> m;
429
430 const Operator* kOps[] = {
431 m.machine()->Word64And(), m.machine()->Word64Or(),
432 m.machine()->Word64Xor(), m.machine()->Word64Shl(),
433 m.machine()->Word64Shr(), m.machine()->Word64Sar(),
434 m.machine()->Word64Equal(), m.machine()->Int64Add(),
435 m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
436 m.machine()->Uint64Div(), m.machine()->Int64Mod(),
437 m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
438 m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
439 m.machine()->Uint64LessThanOrEqual()};
440
441 for (size_t i = 0; i < arraysize(kOps); ++i) {
442 for (int j = 0; j < 8; j++) {
443 for (int k = 0; k < 8; k++) {
444 RawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
445 MachineType::Int64());
446 Node* a = Int64Input(&m, j);
447 Node* b = Int64Input(&m, k);
448 m.Return(m.AddNode(kOps[i], a, b));
449 m.GenerateCode();
450 }
451 }
452 }
453}
454
455
456TEST(RunInt64AddWithOverflowP) {
457 int64_t actual_val = -1;
458 RawMachineAssemblerTester<int32_t> m;
459 Int64BinopTester bt(&m);
460 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
461 Node* val = m.Projection(0, add);
462 Node* ovf = m.Projection(1, add);
463 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
464 bt.AddReturn(ovf);
465 FOR_INT64_INPUTS(i) {
466 FOR_INT64_INPUTS(j) {
467 int64_t expected_val;
468 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
469 CHECK_EQ(expected_ovf, bt.call(*i, *j));
470 CHECK_EQ(expected_val, actual_val);
471 }
472 }
473}
474
475
476TEST(RunInt64AddWithOverflowImm) {
477 int64_t actual_val = -1, expected_val = 0;
478 FOR_INT64_INPUTS(i) {
479 {
480 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
481 Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0));
482 Node* val = m.Projection(0, add);
483 Node* ovf = m.Projection(1, add);
484 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
485 m.Return(ovf);
486 FOR_INT64_INPUTS(j) {
487 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
488 CHECK_EQ(expected_ovf, m.Call(*j));
489 CHECK_EQ(expected_val, actual_val);
490 }
491 }
492 {
493 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
494 Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i));
495 Node* val = m.Projection(0, add);
496 Node* ovf = m.Projection(1, add);
497 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
498 m.Return(ovf);
499 FOR_INT64_INPUTS(j) {
500 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
501 CHECK_EQ(expected_ovf, m.Call(*j));
502 CHECK_EQ(expected_val, actual_val);
503 }
504 }
505 FOR_INT64_INPUTS(j) {
506 RawMachineAssemblerTester<int32_t> m;
507 Node* add =
508 m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
509 Node* val = m.Projection(0, add);
510 Node* ovf = m.Projection(1, add);
511 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
512 m.Return(ovf);
513 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val);
514 CHECK_EQ(expected_ovf, m.Call());
515 CHECK_EQ(expected_val, actual_val);
516 }
517 }
518}
519
520
521TEST(RunInt64AddWithOverflowInBranchP) {
522 int constant = 911777;
523 RawMachineLabel blocka, blockb;
524 RawMachineAssemblerTester<int32_t> m;
525 Int64BinopTester bt(&m);
526 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1);
527 Node* ovf = m.Projection(1, add);
528 m.Branch(ovf, &blocka, &blockb);
529 m.Bind(&blocka);
530 bt.AddReturn(m.Int64Constant(constant));
531 m.Bind(&blockb);
532 Node* val = m.Projection(0, add);
533 Node* truncated = m.TruncateInt64ToInt32(val);
534 bt.AddReturn(truncated);
535 FOR_INT64_INPUTS(i) {
536 FOR_INT64_INPUTS(j) {
537 int32_t expected = constant;
538 int64_t result;
539 if (!bits::SignedAddOverflow64(*i, *j, &result)) {
540 expected = static_cast<int32_t>(result);
541 }
542 CHECK_EQ(expected, bt.call(*i, *j));
543 }
544 }
545}
546
547
548TEST(RunInt64SubWithOverflowP) {
549 int64_t actual_val = -1;
550 RawMachineAssemblerTester<int32_t> m;
551 Int64BinopTester bt(&m);
552 Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1);
553 Node* val = m.Projection(0, add);
554 Node* ovf = m.Projection(1, add);
555 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
556 bt.AddReturn(ovf);
557 FOR_INT64_INPUTS(i) {
558 FOR_INT64_INPUTS(j) {
559 int64_t expected_val;
560 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
561 CHECK_EQ(expected_ovf, bt.call(*i, *j));
562 CHECK_EQ(expected_val, actual_val);
563 }
564 }
565}
566
567
568TEST(RunInt64SubWithOverflowImm) {
569 int64_t actual_val = -1, expected_val = 0;
570 FOR_INT64_INPUTS(i) {
571 {
572 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
573 Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0));
574 Node* val = m.Projection(0, add);
575 Node* ovf = m.Projection(1, add);
576 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
577 m.Return(ovf);
578 FOR_INT64_INPUTS(j) {
579 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
580 CHECK_EQ(expected_ovf, m.Call(*j));
581 CHECK_EQ(expected_val, actual_val);
582 }
583 }
584 {
585 RawMachineAssemblerTester<int32_t> m(MachineType::Int64());
586 Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i));
587 Node* val = m.Projection(0, add);
588 Node* ovf = m.Projection(1, add);
589 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
590 m.Return(ovf);
591 FOR_INT64_INPUTS(j) {
592 int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val);
593 CHECK_EQ(expected_ovf, m.Call(*j));
594 CHECK_EQ(expected_val, actual_val);
595 }
596 }
597 FOR_INT64_INPUTS(j) {
598 RawMachineAssemblerTester<int32_t> m;
599 Node* add =
600 m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j));
601 Node* val = m.Projection(0, add);
602 Node* ovf = m.Projection(1, add);
603 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val);
604 m.Return(ovf);
605 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val);
606 CHECK_EQ(expected_ovf, m.Call());
607 CHECK_EQ(expected_val, actual_val);
608 }
609 }
610}
611
612
613TEST(RunInt64SubWithOverflowInBranchP) {
614 int constant = 911999;
615 RawMachineLabel blocka, blockb;
616 RawMachineAssemblerTester<int32_t> m;
617 Int64BinopTester bt(&m);
618 Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1);
619 Node* ovf = m.Projection(1, sub);
620 m.Branch(ovf, &blocka, &blockb);
621 m.Bind(&blocka);
622 bt.AddReturn(m.Int64Constant(constant));
623 m.Bind(&blockb);
624 Node* val = m.Projection(0, sub);
625 Node* truncated = m.TruncateInt64ToInt32(val);
626 bt.AddReturn(truncated);
627 FOR_INT64_INPUTS(i) {
628 FOR_INT64_INPUTS(j) {
629 int32_t expected = constant;
630 int64_t result;
631 if (!bits::SignedSubOverflow64(*i, *j, &result)) {
632 expected = static_cast<int32_t>(result);
633 }
634 CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j)));
635 }
636 }
637}
638
639
640// TODO(titzer): add tests that run 64-bit integer operations.
641#endif // V8_TARGET_ARCH_64_BIT
642
643
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000644TEST(RunGoto) {
645 RawMachineAssemblerTester<int32_t> m;
646 int constant = 99999;
647
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648 RawMachineLabel next;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000649 m.Goto(&next);
650 m.Bind(&next);
651 m.Return(m.Int32Constant(constant));
652
653 CHECK_EQ(constant, m.Call());
654}
655
656
657TEST(RunGotoMultiple) {
658 RawMachineAssemblerTester<int32_t> m;
659 int constant = 9999977;
660
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 RawMachineLabel labels[10];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000662 for (size_t i = 0; i < arraysize(labels); i++) {
663 m.Goto(&labels[i]);
664 m.Bind(&labels[i]);
665 }
666 m.Return(m.Int32Constant(constant));
667
668 CHECK_EQ(constant, m.Call());
669}
670
671
672TEST(RunBranch) {
673 RawMachineAssemblerTester<int32_t> m;
674 int constant = 999777;
675
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000676 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 m.Branch(m.Int32Constant(0), &blocka, &blockb);
678 m.Bind(&blocka);
679 m.Return(m.Int32Constant(0 - constant));
680 m.Bind(&blockb);
681 m.Return(m.Int32Constant(constant));
682
683 CHECK_EQ(constant, m.Call());
684}
685
686
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687TEST(RunDiamond2) {
688 RawMachineAssemblerTester<int32_t> m;
689
690 int constant = 995666;
691
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000692 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000693 m.Branch(m.Int32Constant(0), &blocka, &blockb);
694 m.Bind(&blocka);
695 m.Goto(&end);
696 m.Bind(&blockb);
697 m.Goto(&end);
698 m.Bind(&end);
699 m.Return(m.Int32Constant(constant));
700
701 CHECK_EQ(constant, m.Call());
702}
703
704
705TEST(RunLoop) {
706 RawMachineAssemblerTester<int32_t> m;
707 int constant = 999555;
708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000709 RawMachineLabel header, body, exit;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000710 m.Goto(&header);
711 m.Bind(&header);
712 m.Branch(m.Int32Constant(0), &body, &exit);
713 m.Bind(&body);
714 m.Goto(&header);
715 m.Bind(&exit);
716 m.Return(m.Int32Constant(constant));
717
718 CHECK_EQ(constant, m.Call());
719}
720
721
722template <typename R>
723static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724 MachineRepresentation rep, Node* true_node,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000725 Node* false_node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000726 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 m->Branch(cond_node, &blocka, &blockb);
728 m->Bind(&blocka);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729 m->Goto(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000730 m->Bind(&blockb);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000731 m->Goto(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000733 m->Bind(&end);
734 Node* phi = m->Phi(rep, true_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 m->Return(phi);
736}
737
738
739TEST(RunDiamondPhiConst) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000740 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000741 int false_val = 0xFF666;
742 int true_val = 0x00DDD;
743 Node* true_node = m.Int32Constant(true_val);
744 Node* false_node = m.Int32Constant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000745 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node,
746 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000747 CHECK_EQ(false_val, m.Call(0));
748 CHECK_EQ(true_val, m.Call(1));
749}
750
751
752TEST(RunDiamondPhiNumber) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000753 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000754 double false_val = -11.1;
755 double true_val = 200.1;
756 Node* true_node = m.NumberConstant(true_val);
757 Node* false_node = m.NumberConstant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000758 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
759 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760 m.CheckNumber(false_val, m.Call(0));
761 m.CheckNumber(true_val, m.Call(1));
762}
763
764
765TEST(RunDiamondPhiString) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000766 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000767 const char* false_val = "false";
768 const char* true_val = "true";
769 Node* true_node = m.StringConstant(true_val);
770 Node* false_node = m.StringConstant(false_val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000771 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node,
772 false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000773 m.CheckString(false_val, m.Call(0));
774 m.CheckString(true_val, m.Call(1));
775}
776
777
778TEST(RunDiamondPhiParam) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000779 RawMachineAssemblerTester<int32_t> m(
780 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
781 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32,
782 m.Parameter(1), m.Parameter(2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000783 int32_t c1 = 0x260cb75a;
784 int32_t c2 = 0xcd3e9c8b;
785 int result = m.Call(0, c1, c2);
786 CHECK_EQ(c2, result);
787 result = m.Call(1, c1, c2);
788 CHECK_EQ(c1, result);
789}
790
791
792TEST(RunLoopPhiConst) {
793 RawMachineAssemblerTester<int32_t> m;
794 int true_val = 0x44000;
795 int false_val = 0x00888;
796
797 Node* cond_node = m.Int32Constant(0);
798 Node* true_node = m.Int32Constant(true_val);
799 Node* false_node = m.Int32Constant(false_val);
800
801 // x = false_val; while(false) { x = true_val; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802 RawMachineLabel body, header, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000803
804 m.Goto(&header);
805 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node);
807 m.Branch(cond_node, &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808 m.Bind(&body);
809 m.Goto(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000811 m.Return(phi);
812
813 CHECK_EQ(false_val, m.Call());
814}
815
816
817TEST(RunLoopPhiParam) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 RawMachineAssemblerTester<int32_t> m(
819 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000820
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000821 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822
823 m.Goto(&blocka);
824
825 m.Bind(&blocka);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000826 Node* phi =
827 m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2));
828 Node* cond =
829 m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0));
830 m.Branch(cond, &blockb, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831
832 m.Bind(&blockb);
833 m.Goto(&blocka);
834
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000835 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000836 m.Return(phi);
837
838 int32_t c1 = 0xa81903b4;
839 int32_t c2 = 0x5a1207da;
840 int result = m.Call(0, c1, c2);
841 CHECK_EQ(c1, result);
842 result = m.Call(1, c1, c2);
843 CHECK_EQ(c2, result);
844}
845
846
847TEST(RunLoopPhiInduction) {
848 RawMachineAssemblerTester<int32_t> m;
849
850 int false_val = 0x10777;
851
852 // x = false_val; while(false) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000854 Node* false_node = m.Int32Constant(false_val);
855
856 m.Goto(&header);
857
858 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000859 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
860 m.Branch(m.Int32Constant(0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861
862 m.Bind(&body);
863 Node* add = m.Int32Add(phi, m.Int32Constant(1));
864 phi->ReplaceInput(1, add);
865 m.Goto(&header);
866
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868 m.Return(phi);
869
870 CHECK_EQ(false_val, m.Call());
871}
872
873
874TEST(RunLoopIncrement) {
875 RawMachineAssemblerTester<int32_t> m;
876 Int32BinopTester bt(&m);
877
878 // x = 0; while(x ^ param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000879 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000880 Node* zero = m.Int32Constant(0);
881
882 m.Goto(&header);
883
884 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000885 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
886 m.Branch(m.WordXor(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887
888 m.Bind(&body);
889 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
890 m.Goto(&header);
891
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000892 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000893 bt.AddReturn(phi);
894
895 CHECK_EQ(11, bt.call(11, 0));
896 CHECK_EQ(110, bt.call(110, 0));
897 CHECK_EQ(176, bt.call(176, 0));
898}
899
900
901TEST(RunLoopIncrement2) {
902 RawMachineAssemblerTester<int32_t> m;
903 Int32BinopTester bt(&m);
904
905 // x = 0; while(x < param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000906 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 Node* zero = m.Int32Constant(0);
908
909 m.Goto(&header);
910
911 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000912 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
913 m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914
915 m.Bind(&body);
916 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
917 m.Goto(&header);
918
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000919 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000920 bt.AddReturn(phi);
921
922 CHECK_EQ(11, bt.call(11, 0));
923 CHECK_EQ(110, bt.call(110, 0));
924 CHECK_EQ(176, bt.call(176, 0));
925 CHECK_EQ(0, bt.call(-200, 0));
926}
927
928
929TEST(RunLoopIncrement3) {
930 RawMachineAssemblerTester<int32_t> m;
931 Int32BinopTester bt(&m);
932
933 // x = 0; while(x < param) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935 Node* zero = m.Int32Constant(0);
936
937 m.Goto(&header);
938
939 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero);
941 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942
943 m.Bind(&body);
944 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
945 m.Goto(&header);
946
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000947 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000948 bt.AddReturn(phi);
949
950 CHECK_EQ(11, bt.call(11, 0));
951 CHECK_EQ(110, bt.call(110, 0));
952 CHECK_EQ(176, bt.call(176, 0));
953 CHECK_EQ(200, bt.call(200, 0));
954}
955
956
957TEST(RunLoopDecrement) {
958 RawMachineAssemblerTester<int32_t> m;
959 Int32BinopTester bt(&m);
960
961 // x = param; while(x) { x--; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000962 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000963
964 m.Goto(&header);
965
966 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000967 Node* phi =
968 m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0));
969 m.Branch(phi, &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970
971 m.Bind(&body);
972 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
973 m.Goto(&header);
974
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000975 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000976 bt.AddReturn(phi);
977
978 CHECK_EQ(0, bt.call(11, 0));
979 CHECK_EQ(0, bt.call(110, 0));
980 CHECK_EQ(0, bt.call(197, 0));
981}
982
983
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984TEST(RunLoopIncrementFloat32) {
985 RawMachineAssemblerTester<int32_t> m;
986
987 // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
988 RawMachineLabel header, body, end;
989 Node* minus_3 = m.Float32Constant(-3.0f);
990 Node* ten = m.Float32Constant(10.0f);
991
992 m.Goto(&header);
993
994 m.Bind(&header);
995 Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten);
996 m.Branch(m.Float32LessThan(phi, ten), &body, &end);
997
998 m.Bind(&body);
999 phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
1000 m.Goto(&header);
1001
1002 m.Bind(&end);
1003 m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
1004
1005 CHECK_EQ(10, m.Call());
1006}
1007
1008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001009TEST(RunLoopIncrementFloat64) {
1010 RawMachineAssemblerTester<int32_t> m;
1011
1012 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001013 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001014 Node* minus_3 = m.Float64Constant(-3.0);
1015 Node* ten = m.Float64Constant(10.0);
1016
1017 m.Goto(&header);
1018
1019 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001020 Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten);
1021 m.Branch(m.Float64LessThan(phi, ten), &body, &end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001022
1023 m.Bind(&body);
1024 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
1025 m.Goto(&header);
1026
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001027 m.Bind(&end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028 m.Return(m.ChangeFloat64ToInt32(phi));
1029
1030 CHECK_EQ(10, m.Call());
1031}
1032
1033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001034TEST(RunSwitch1) {
1035 RawMachineAssemblerTester<int32_t> m;
1036
1037 int constant = 11223344;
1038
1039 RawMachineLabel block0, block1, def, end;
1040 RawMachineLabel* case_labels[] = {&block0, &block1};
1041 int32_t case_values[] = {0, 1};
1042 m.Switch(m.Int32Constant(0), &def, case_values, case_labels,
1043 arraysize(case_labels));
1044 m.Bind(&block0);
1045 m.Goto(&end);
1046 m.Bind(&block1);
1047 m.Goto(&end);
1048 m.Bind(&def);
1049 m.Goto(&end);
1050 m.Bind(&end);
1051 m.Return(m.Int32Constant(constant));
1052
1053 CHECK_EQ(constant, m.Call());
1054}
1055
1056
1057TEST(RunSwitch2) {
1058 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1059
1060 RawMachineLabel blocka, blockb, blockc;
1061 RawMachineLabel* case_labels[] = {&blocka, &blockb};
1062 int32_t case_values[] = {std::numeric_limits<int32_t>::min(),
1063 std::numeric_limits<int32_t>::max()};
1064 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1065 arraysize(case_labels));
1066 m.Bind(&blocka);
1067 m.Return(m.Int32Constant(-1));
1068 m.Bind(&blockb);
1069 m.Return(m.Int32Constant(1));
1070 m.Bind(&blockc);
1071 m.Return(m.Int32Constant(0));
1072
1073 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max()));
1074 CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min()));
1075 for (int i = -100; i < 100; i += 25) {
1076 CHECK_EQ(0, m.Call(i));
1077 }
1078}
1079
1080
1081TEST(RunSwitch3) {
1082 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1083
1084 RawMachineLabel blocka, blockb, blockc;
1085 RawMachineLabel* case_labels[] = {&blocka, &blockb};
1086 int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0,
1087 std::numeric_limits<int32_t>::min() + 1};
1088 m.Switch(m.Parameter(0), &blockc, case_values, case_labels,
1089 arraysize(case_labels));
1090 m.Bind(&blocka);
1091 m.Return(m.Int32Constant(0));
1092 m.Bind(&blockb);
1093 m.Return(m.Int32Constant(1));
1094 m.Bind(&blockc);
1095 m.Return(m.Int32Constant(2));
1096
1097 CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0));
1098 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1));
1099 for (int i = -100; i < 100; i += 25) {
1100 CHECK_EQ(2, m.Call(i));
1101 }
1102}
1103
1104
1105TEST(RunSwitch4) {
1106 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
1107
1108 const size_t kNumCases = 512;
1109 const size_t kNumValues = kNumCases + 1;
1110 int32_t values[kNumValues];
1111 m.main_isolate()->random_number_generator()->NextBytes(values,
1112 sizeof(values));
1113 RawMachineLabel end, def;
1114 int32_t case_values[kNumCases];
1115 RawMachineLabel* case_labels[kNumCases];
1116 Node* results[kNumValues];
1117 for (size_t i = 0; i < kNumCases; ++i) {
1118 case_values[i] = static_cast<int32_t>(i);
1119 case_labels[i] =
1120 new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
1121 }
1122 m.Switch(m.Parameter(0), &def, case_values, case_labels,
1123 arraysize(case_labels));
1124 for (size_t i = 0; i < kNumCases; ++i) {
1125 m.Bind(case_labels[i]);
1126 results[i] = m.Int32Constant(values[i]);
1127 m.Goto(&end);
1128 }
1129 m.Bind(&def);
1130 results[kNumCases] = m.Int32Constant(values[kNumCases]);
1131 m.Goto(&end);
1132 m.Bind(&end);
1133 const int num_results = static_cast<int>(arraysize(results));
1134 Node* phi =
1135 m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results),
1136 num_results, results);
1137 m.Return(phi);
1138
1139 for (size_t i = 0; i < kNumValues; ++i) {
1140 CHECK_EQ(values[i], m.Call(static_cast<int>(i)));
1141 }
1142}
1143
1144
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001145TEST(RunLoadInt32) {
1146 RawMachineAssemblerTester<int32_t> m;
1147
1148 int32_t p1 = 0; // loads directly from this location.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001149 m.Return(m.LoadFromPointer(&p1, MachineType::Int32()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001150
1151 FOR_INT32_INPUTS(i) {
1152 p1 = *i;
1153 CHECK_EQ(p1, m.Call());
1154 }
1155}
1156
1157
1158TEST(RunLoadInt32Offset) {
1159 int32_t p1 = 0; // loads directly from this location.
1160
1161 int32_t offsets[] = {-2000000, -100, -101, 1, 3,
1162 7, 120, 2000, 2000000000, 0xff};
1163
1164 for (size_t i = 0; i < arraysize(offsets); i++) {
1165 RawMachineAssemblerTester<int32_t> m;
1166 int32_t offset = offsets[i];
1167 byte* pointer = reinterpret_cast<byte*>(&p1) - offset;
1168 // generate load [#base + #index]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001169 m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170
1171 FOR_INT32_INPUTS(j) {
1172 p1 = *j;
1173 CHECK_EQ(p1, m.Call());
1174 }
1175 }
1176}
1177
1178
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179TEST(RunLoadStoreFloat32Offset) {
1180 float p1 = 0.0f; // loads directly from this location.
1181 float p2 = 0.0f; // and stores directly into this location.
1182
1183 FOR_INT32_INPUTS(i) {
1184 int32_t magic = 0x2342aabb + *i * 3;
1185 RawMachineAssemblerTester<int32_t> m;
1186 int32_t offset = *i;
1187 byte* from = reinterpret_cast<byte*>(&p1) - offset;
1188 byte* to = reinterpret_cast<byte*>(&p2) - offset;
1189 // generate load [#base + #index]
1190 Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from),
1191 m.IntPtrConstant(offset));
1192 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to),
1193 m.IntPtrConstant(offset), load, kNoWriteBarrier);
1194 m.Return(m.Int32Constant(magic));
1195
1196 FOR_FLOAT32_INPUTS(j) {
1197 p1 = *j;
1198 p2 = *j - 5;
1199 CHECK_EQ(magic, m.Call());
Ben Murdochda12d292016-06-02 14:46:10 +01001200 CHECK_DOUBLE_EQ(p1, p2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001201 }
1202 }
1203}
1204
1205
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001206TEST(RunLoadStoreFloat64Offset) {
1207 double p1 = 0; // loads directly from this location.
1208 double p2 = 0; // and stores directly into this location.
1209
1210 FOR_INT32_INPUTS(i) {
1211 int32_t magic = 0x2342aabb + *i * 3;
1212 RawMachineAssemblerTester<int32_t> m;
1213 int32_t offset = *i;
1214 byte* from = reinterpret_cast<byte*>(&p1) - offset;
1215 byte* to = reinterpret_cast<byte*>(&p2) - offset;
1216 // generate load [#base + #index]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001217 Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from),
1218 m.IntPtrConstant(offset));
1219 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to),
1220 m.IntPtrConstant(offset), load, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001221 m.Return(m.Int32Constant(magic));
1222
1223 FOR_FLOAT64_INPUTS(j) {
1224 p1 = *j;
1225 p2 = *j - 5;
1226 CHECK_EQ(magic, m.Call());
Ben Murdochda12d292016-06-02 14:46:10 +01001227 CHECK_DOUBLE_EQ(p1, p2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001228 }
1229 }
1230}
1231
1232
1233TEST(RunInt32AddP) {
1234 RawMachineAssemblerTester<int32_t> m;
1235 Int32BinopTester bt(&m);
1236
1237 bt.AddReturn(m.Int32Add(bt.param0, bt.param1));
1238
1239 FOR_INT32_INPUTS(i) {
1240 FOR_INT32_INPUTS(j) {
1241 // Use uint32_t because signed overflow is UB in C.
1242 int expected = static_cast<int32_t>(*i + *j);
1243 CHECK_EQ(expected, bt.call(*i, *j));
1244 }
1245 }
1246}
1247
1248
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001249TEST(RunInt32AddAndWord32EqualP) {
1250 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251 RawMachineAssemblerTester<int32_t> m(
1252 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001253 m.Return(m.Int32Add(m.Parameter(0),
1254 m.Word32Equal(m.Parameter(1), m.Parameter(2))));
1255 FOR_INT32_INPUTS(i) {
1256 FOR_INT32_INPUTS(j) {
1257 FOR_INT32_INPUTS(k) {
1258 // Use uint32_t because signed overflow is UB in C.
1259 int32_t const expected =
1260 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1261 CHECK_EQ(expected, m.Call(*i, *j, *k));
1262 }
1263 }
1264 }
1265 }
1266 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001267 RawMachineAssemblerTester<int32_t> m(
1268 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001269 m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
1270 m.Parameter(2)));
1271 FOR_INT32_INPUTS(i) {
1272 FOR_INT32_INPUTS(j) {
1273 FOR_INT32_INPUTS(k) {
1274 // Use uint32_t because signed overflow is UB in C.
1275 int32_t const expected =
1276 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1277 CHECK_EQ(expected, m.Call(*i, *j, *k));
1278 }
1279 }
1280 }
1281 }
1282}
1283
1284
1285TEST(RunInt32AddAndWord32EqualImm) {
1286 {
1287 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001288 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1289 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001290 m.Return(m.Int32Add(m.Int32Constant(*i),
1291 m.Word32Equal(m.Parameter(0), m.Parameter(1))));
1292 FOR_INT32_INPUTS(j) {
1293 FOR_INT32_INPUTS(k) {
1294 // Use uint32_t because signed overflow is UB in C.
1295 int32_t const expected =
1296 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
1297 CHECK_EQ(expected, m.Call(*j, *k));
1298 }
1299 }
1300 }
1301 }
1302 {
1303 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001304 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1305 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001306 m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
1307 m.Parameter(1)));
1308 FOR_INT32_INPUTS(j) {
1309 FOR_INT32_INPUTS(k) {
1310 // Use uint32_t because signed overflow is UB in C.
1311 int32_t const expected =
1312 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
1313 CHECK_EQ(expected, m.Call(*j, *k));
1314 }
1315 }
1316 }
1317 }
1318}
1319
1320
1321TEST(RunInt32AddAndWord32NotEqualP) {
1322 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001323 RawMachineAssemblerTester<int32_t> m(
1324 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001325 m.Return(m.Int32Add(m.Parameter(0),
1326 m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
1327 FOR_INT32_INPUTS(i) {
1328 FOR_INT32_INPUTS(j) {
1329 FOR_INT32_INPUTS(k) {
1330 // Use uint32_t because signed overflow is UB in C.
1331 int32_t const expected =
1332 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1333 CHECK_EQ(expected, m.Call(*i, *j, *k));
1334 }
1335 }
1336 }
1337 }
1338 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001339 RawMachineAssemblerTester<int32_t> m(
1340 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001341 m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
1342 m.Parameter(2)));
1343 FOR_INT32_INPUTS(i) {
1344 FOR_INT32_INPUTS(j) {
1345 FOR_INT32_INPUTS(k) {
1346 // Use uint32_t because signed overflow is UB in C.
1347 int32_t const expected =
1348 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1349 CHECK_EQ(expected, m.Call(*i, *j, *k));
1350 }
1351 }
1352 }
1353 }
1354}
1355
1356
1357TEST(RunInt32AddAndWord32NotEqualImm) {
1358 {
1359 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001360 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1361 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001362 m.Return(m.Int32Add(m.Int32Constant(*i),
1363 m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
1364 FOR_INT32_INPUTS(j) {
1365 FOR_INT32_INPUTS(k) {
1366 // Use uint32_t because signed overflow is UB in C.
1367 int32_t const expected =
1368 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
1369 CHECK_EQ(expected, m.Call(*j, *k));
1370 }
1371 }
1372 }
1373 }
1374 {
1375 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001376 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
1377 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001378 m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
1379 m.Parameter(1)));
1380 FOR_INT32_INPUTS(j) {
1381 FOR_INT32_INPUTS(k) {
1382 // Use uint32_t because signed overflow is UB in C.
1383 int32_t const expected =
1384 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
1385 CHECK_EQ(expected, m.Call(*j, *k));
1386 }
1387 }
1388 }
1389 }
1390}
1391
1392
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001393TEST(RunInt32AddAndWord32SarP) {
1394 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001395 RawMachineAssemblerTester<int32_t> m(
1396 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001397 m.Return(m.Int32Add(m.Parameter(0),
1398 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1399 FOR_UINT32_INPUTS(i) {
1400 FOR_INT32_INPUTS(j) {
1401 FOR_UINT32_SHIFTS(shift) {
1402 // Use uint32_t because signed overflow is UB in C.
1403 int32_t expected = *i + (*j >> shift);
1404 CHECK_EQ(expected, m.Call(*i, *j, shift));
1405 }
1406 }
1407 }
1408 }
1409 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001410 RawMachineAssemblerTester<int32_t> m(
1411 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001412 m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1413 m.Parameter(2)));
1414 FOR_INT32_INPUTS(i) {
1415 FOR_UINT32_SHIFTS(shift) {
1416 FOR_UINT32_INPUTS(k) {
1417 // Use uint32_t because signed overflow is UB in C.
1418 int32_t expected = (*i >> shift) + *k;
1419 CHECK_EQ(expected, m.Call(*i, shift, *k));
1420 }
1421 }
1422 }
1423 }
1424}
1425
1426
1427TEST(RunInt32AddAndWord32ShlP) {
1428 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001429 RawMachineAssemblerTester<int32_t> m(
1430 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001431 m.Return(m.Int32Add(m.Parameter(0),
1432 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1433 FOR_UINT32_INPUTS(i) {
1434 FOR_INT32_INPUTS(j) {
1435 FOR_UINT32_SHIFTS(shift) {
1436 // Use uint32_t because signed overflow is UB in C.
1437 int32_t expected = *i + (*j << shift);
1438 CHECK_EQ(expected, m.Call(*i, *j, shift));
1439 }
1440 }
1441 }
1442 }
1443 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001444 RawMachineAssemblerTester<int32_t> m(
1445 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001446 m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1447 m.Parameter(2)));
1448 FOR_INT32_INPUTS(i) {
1449 FOR_UINT32_SHIFTS(shift) {
1450 FOR_UINT32_INPUTS(k) {
1451 // Use uint32_t because signed overflow is UB in C.
1452 int32_t expected = (*i << shift) + *k;
1453 CHECK_EQ(expected, m.Call(*i, shift, *k));
1454 }
1455 }
1456 }
1457 }
1458}
1459
1460
1461TEST(RunInt32AddAndWord32ShrP) {
1462 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001463 RawMachineAssemblerTester<int32_t> m(
1464 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001465 m.Return(m.Int32Add(m.Parameter(0),
1466 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1467 FOR_UINT32_INPUTS(i) {
1468 FOR_UINT32_INPUTS(j) {
1469 FOR_UINT32_SHIFTS(shift) {
1470 // Use uint32_t because signed overflow is UB in C.
1471 int32_t expected = *i + (*j >> shift);
1472 CHECK_EQ(expected, m.Call(*i, *j, shift));
1473 }
1474 }
1475 }
1476 }
1477 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001478 RawMachineAssemblerTester<int32_t> m(
1479 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001480 m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1481 m.Parameter(2)));
1482 FOR_UINT32_INPUTS(i) {
1483 FOR_UINT32_SHIFTS(shift) {
1484 FOR_UINT32_INPUTS(k) {
1485 // Use uint32_t because signed overflow is UB in C.
1486 int32_t expected = (*i >> shift) + *k;
1487 CHECK_EQ(expected, m.Call(*i, shift, *k));
1488 }
1489 }
1490 }
1491 }
1492}
1493
1494
1495TEST(RunInt32AddInBranch) {
1496 static const int32_t constant = 987654321;
1497 {
1498 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001499 Int32BinopTester bt(&m);
1500 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001501 m.Branch(
1502 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1503 &blocka, &blockb);
1504 m.Bind(&blocka);
1505 bt.AddReturn(m.Int32Constant(constant));
1506 m.Bind(&blockb);
1507 bt.AddReturn(m.Int32Constant(0 - constant));
1508 FOR_UINT32_INPUTS(i) {
1509 FOR_UINT32_INPUTS(j) {
1510 int32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
1511 CHECK_EQ(expected, bt.call(*i, *j));
1512 }
1513 }
1514 }
1515 {
1516 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001517 Int32BinopTester bt(&m);
1518 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001519 m.Branch(
1520 m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)),
1521 &blocka, &blockb);
1522 m.Bind(&blocka);
1523 bt.AddReturn(m.Int32Constant(constant));
1524 m.Bind(&blockb);
1525 bt.AddReturn(m.Int32Constant(0 - constant));
1526 FOR_UINT32_INPUTS(i) {
1527 FOR_UINT32_INPUTS(j) {
1528 int32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
1529 CHECK_EQ(expected, bt.call(*i, *j));
1530 }
1531 }
1532 }
1533 {
1534 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001535 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1536 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001537 m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1538 m.Int32Constant(0)),
1539 &blocka, &blockb);
1540 m.Bind(&blocka);
1541 m.Return(m.Int32Constant(constant));
1542 m.Bind(&blockb);
1543 m.Return(m.Int32Constant(0 - constant));
1544 FOR_UINT32_INPUTS(j) {
1545 uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001546 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001547 }
1548 }
1549 }
1550 {
1551 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001552 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1553 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001554 m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1555 m.Int32Constant(0)),
1556 &blocka, &blockb);
1557 m.Bind(&blocka);
1558 m.Return(m.Int32Constant(constant));
1559 m.Bind(&blockb);
1560 m.Return(m.Int32Constant(0 - constant));
1561 FOR_UINT32_INPUTS(j) {
1562 uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001564 }
1565 }
1566 }
1567 {
1568 RawMachineAssemblerTester<void> m;
1569 const Operator* shops[] = {m.machine()->Word32Sar(),
1570 m.machine()->Word32Shl(),
1571 m.machine()->Word32Shr()};
1572 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001573 RawMachineAssemblerTester<int32_t> m(
1574 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1575 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001576 m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001577 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001578 m.Parameter(2))),
1579 m.Int32Constant(0)),
1580 &blocka, &blockb);
1581 m.Bind(&blocka);
1582 m.Return(m.Int32Constant(constant));
1583 m.Bind(&blockb);
1584 m.Return(m.Int32Constant(0 - constant));
1585 FOR_UINT32_INPUTS(i) {
1586 FOR_INT32_INPUTS(j) {
1587 FOR_UINT32_SHIFTS(shift) {
1588 int32_t right;
1589 switch (shops[n]->opcode()) {
1590 default:
1591 UNREACHABLE();
1592 case IrOpcode::kWord32Sar:
1593 right = *j >> shift;
1594 break;
1595 case IrOpcode::kWord32Shl:
1596 right = *j << shift;
1597 break;
1598 case IrOpcode::kWord32Shr:
1599 right = static_cast<uint32_t>(*j) >> shift;
1600 break;
1601 }
1602 int32_t expected = ((*i + right) == 0) ? constant : 0 - constant;
1603 CHECK_EQ(expected, m.Call(*i, *j, shift));
1604 }
1605 }
1606 }
1607 }
1608 }
1609}
1610
1611
1612TEST(RunInt32AddInComparison) {
1613 {
1614 RawMachineAssemblerTester<int32_t> m;
1615 Uint32BinopTester bt(&m);
1616 bt.AddReturn(
1617 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)));
1618 FOR_UINT32_INPUTS(i) {
1619 FOR_UINT32_INPUTS(j) {
1620 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001621 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 }
1623 }
1624 }
1625 {
1626 RawMachineAssemblerTester<int32_t> m;
1627 Uint32BinopTester bt(&m);
1628 bt.AddReturn(
1629 m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1)));
1630 FOR_UINT32_INPUTS(i) {
1631 FOR_UINT32_INPUTS(j) {
1632 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001633 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001634 }
1635 }
1636 }
1637 {
1638 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001639 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001640 m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)),
1641 m.Int32Constant(0)));
1642 FOR_UINT32_INPUTS(j) {
1643 uint32_t expected = (*i + *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001644 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001645 }
1646 }
1647 }
1648 {
1649 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001650 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001651 m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)),
1652 m.Int32Constant(0)));
1653 FOR_UINT32_INPUTS(j) {
1654 uint32_t expected = (*j + *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001655 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001656 }
1657 }
1658 }
1659 {
1660 RawMachineAssemblerTester<void> m;
1661 const Operator* shops[] = {m.machine()->Word32Sar(),
1662 m.machine()->Word32Shl(),
1663 m.machine()->Word32Shr()};
1664 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001665 RawMachineAssemblerTester<int32_t> m(
1666 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001667 m.Return(m.Word32Equal(
1668 m.Int32Add(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001669 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001670 m.Int32Constant(0)));
1671 FOR_UINT32_INPUTS(i) {
1672 FOR_INT32_INPUTS(j) {
1673 FOR_UINT32_SHIFTS(shift) {
1674 int32_t right;
1675 switch (shops[n]->opcode()) {
1676 default:
1677 UNREACHABLE();
1678 case IrOpcode::kWord32Sar:
1679 right = *j >> shift;
1680 break;
1681 case IrOpcode::kWord32Shl:
1682 right = *j << shift;
1683 break;
1684 case IrOpcode::kWord32Shr:
1685 right = static_cast<uint32_t>(*j) >> shift;
1686 break;
1687 }
1688 int32_t expected = (*i + right) == 0;
1689 CHECK_EQ(expected, m.Call(*i, *j, shift));
1690 }
1691 }
1692 }
1693 }
1694 }
1695}
1696
1697
1698TEST(RunInt32SubP) {
1699 RawMachineAssemblerTester<int32_t> m;
1700 Uint32BinopTester bt(&m);
1701
1702 m.Return(m.Int32Sub(bt.param0, bt.param1));
1703
1704 FOR_UINT32_INPUTS(i) {
1705 FOR_UINT32_INPUTS(j) {
1706 uint32_t expected = static_cast<int32_t>(*i - *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001707 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001708 }
1709 }
1710}
1711
1712
1713TEST(RunInt32SubImm) {
1714 {
1715 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001716 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001717 m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)));
1718 FOR_UINT32_INPUTS(j) {
1719 uint32_t expected = *i - *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001720 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001721 }
1722 }
1723 }
1724 {
1725 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001727 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)));
1728 FOR_UINT32_INPUTS(j) {
1729 uint32_t expected = *j - *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001730 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001731 }
1732 }
1733 }
1734}
1735
1736
1737TEST(RunInt32SubAndWord32SarP) {
1738 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001739 RawMachineAssemblerTester<int32_t> m(
1740 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001741 m.Return(m.Int32Sub(m.Parameter(0),
1742 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
1743 FOR_UINT32_INPUTS(i) {
1744 FOR_INT32_INPUTS(j) {
1745 FOR_UINT32_SHIFTS(shift) {
1746 int32_t expected = *i - (*j >> shift);
1747 CHECK_EQ(expected, m.Call(*i, *j, shift));
1748 }
1749 }
1750 }
1751 }
1752 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001753 RawMachineAssemblerTester<int32_t> m(
1754 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001755 m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
1756 m.Parameter(2)));
1757 FOR_INT32_INPUTS(i) {
1758 FOR_UINT32_SHIFTS(shift) {
1759 FOR_UINT32_INPUTS(k) {
1760 int32_t expected = (*i >> shift) - *k;
1761 CHECK_EQ(expected, m.Call(*i, shift, *k));
1762 }
1763 }
1764 }
1765 }
1766}
1767
1768
1769TEST(RunInt32SubAndWord32ShlP) {
1770 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001771 RawMachineAssemblerTester<int32_t> m(
1772 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001773 m.Return(m.Int32Sub(m.Parameter(0),
1774 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
1775 FOR_UINT32_INPUTS(i) {
1776 FOR_INT32_INPUTS(j) {
1777 FOR_UINT32_SHIFTS(shift) {
1778 int32_t expected = *i - (*j << shift);
1779 CHECK_EQ(expected, m.Call(*i, *j, shift));
1780 }
1781 }
1782 }
1783 }
1784 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785 RawMachineAssemblerTester<int32_t> m(
1786 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001787 m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)),
1788 m.Parameter(2)));
1789 FOR_INT32_INPUTS(i) {
1790 FOR_UINT32_SHIFTS(shift) {
1791 FOR_UINT32_INPUTS(k) {
1792 // Use uint32_t because signed overflow is UB in C.
1793 int32_t expected = (*i << shift) - *k;
1794 CHECK_EQ(expected, m.Call(*i, shift, *k));
1795 }
1796 }
1797 }
1798 }
1799}
1800
1801
1802TEST(RunInt32SubAndWord32ShrP) {
1803 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001804 RawMachineAssemblerTester<uint32_t> m(
1805 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001806 m.Return(m.Int32Sub(m.Parameter(0),
1807 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
1808 FOR_UINT32_INPUTS(i) {
1809 FOR_UINT32_INPUTS(j) {
1810 FOR_UINT32_SHIFTS(shift) {
1811 // Use uint32_t because signed overflow is UB in C.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001812 uint32_t expected = *i - (*j >> shift);
1813 CHECK_EQ(expected, m.Call(*i, *j, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001814 }
1815 }
1816 }
1817 }
1818 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001819 RawMachineAssemblerTester<uint32_t> m(
1820 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001821 m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
1822 m.Parameter(2)));
1823 FOR_UINT32_INPUTS(i) {
1824 FOR_UINT32_SHIFTS(shift) {
1825 FOR_UINT32_INPUTS(k) {
1826 // Use uint32_t because signed overflow is UB in C.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001827 uint32_t expected = (*i >> shift) - *k;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001828 CHECK_EQ(expected, m.Call(*i, shift, *k));
1829 }
1830 }
1831 }
1832 }
1833}
1834
1835
1836TEST(RunInt32SubInBranch) {
1837 static const int constant = 987654321;
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.Word32Equal(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 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001858 Int32BinopTester bt(&m);
1859 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001860 m.Branch(
1861 m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)),
1862 &blocka, &blockb);
1863 m.Bind(&blocka);
1864 bt.AddReturn(m.Int32Constant(constant));
1865 m.Bind(&blockb);
1866 bt.AddReturn(m.Int32Constant(0 - constant));
1867 FOR_UINT32_INPUTS(i) {
1868 FOR_UINT32_INPUTS(j) {
1869 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1870 CHECK_EQ(expected, bt.call(*i, *j));
1871 }
1872 }
1873 }
1874 {
1875 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001876 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
1877 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001878 m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1879 m.Int32Constant(0)),
1880 &blocka, &blockb);
1881 m.Bind(&blocka);
1882 m.Return(m.Int32Constant(constant));
1883 m.Bind(&blockb);
1884 m.Return(m.Int32Constant(0 - constant));
1885 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001886 uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001887 CHECK_EQ(expected, m.Call(*j));
1888 }
1889 }
1890 }
1891 {
1892 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001893 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
1894 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001895 m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1896 m.Int32Constant(0)),
1897 &blocka, &blockb);
1898 m.Bind(&blocka);
1899 m.Return(m.Int32Constant(constant));
1900 m.Bind(&blockb);
1901 m.Return(m.Int32Constant(0 - constant));
1902 FOR_UINT32_INPUTS(j) {
1903 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant;
1904 CHECK_EQ(expected, m.Call(*j));
1905 }
1906 }
1907 }
1908 {
1909 RawMachineAssemblerTester<void> m;
1910 const Operator* shops[] = {m.machine()->Word32Sar(),
1911 m.machine()->Word32Shl(),
1912 m.machine()->Word32Shr()};
1913 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001914 RawMachineAssemblerTester<int32_t> m(
1915 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
1916 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001917 m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001918 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001919 m.Parameter(2))),
1920 m.Int32Constant(0)),
1921 &blocka, &blockb);
1922 m.Bind(&blocka);
1923 m.Return(m.Int32Constant(constant));
1924 m.Bind(&blockb);
1925 m.Return(m.Int32Constant(0 - constant));
1926 FOR_UINT32_INPUTS(i) {
1927 FOR_INT32_INPUTS(j) {
1928 FOR_UINT32_SHIFTS(shift) {
1929 int32_t right;
1930 switch (shops[n]->opcode()) {
1931 default:
1932 UNREACHABLE();
1933 case IrOpcode::kWord32Sar:
1934 right = *j >> shift;
1935 break;
1936 case IrOpcode::kWord32Shl:
1937 right = *j << shift;
1938 break;
1939 case IrOpcode::kWord32Shr:
1940 right = static_cast<uint32_t>(*j) >> shift;
1941 break;
1942 }
1943 int32_t expected = ((*i - right) == 0) ? constant : 0 - constant;
1944 CHECK_EQ(expected, m.Call(*i, *j, shift));
1945 }
1946 }
1947 }
1948 }
1949 }
1950}
1951
1952
1953TEST(RunInt32SubInComparison) {
1954 {
1955 RawMachineAssemblerTester<int32_t> m;
1956 Uint32BinopTester bt(&m);
1957 bt.AddReturn(
1958 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)));
1959 FOR_UINT32_INPUTS(i) {
1960 FOR_UINT32_INPUTS(j) {
1961 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001962 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001963 }
1964 }
1965 }
1966 {
1967 RawMachineAssemblerTester<int32_t> m;
1968 Uint32BinopTester bt(&m);
1969 bt.AddReturn(
1970 m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1)));
1971 FOR_UINT32_INPUTS(i) {
1972 FOR_UINT32_INPUTS(j) {
1973 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001974 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001975 }
1976 }
1977 }
1978 {
1979 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001980 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001981 m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)),
1982 m.Int32Constant(0)));
1983 FOR_UINT32_INPUTS(j) {
1984 uint32_t expected = (*i - *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001985 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001986 }
1987 }
1988 }
1989 {
1990 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001991 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001992 m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)),
1993 m.Int32Constant(0)));
1994 FOR_UINT32_INPUTS(j) {
1995 uint32_t expected = (*j - *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001996 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001997 }
1998 }
1999 }
2000 {
2001 RawMachineAssemblerTester<void> m;
2002 const Operator* shops[] = {m.machine()->Word32Sar(),
2003 m.machine()->Word32Shl(),
2004 m.machine()->Word32Shr()};
2005 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002006 RawMachineAssemblerTester<int32_t> m(
2007 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002008 m.Return(m.Word32Equal(
2009 m.Int32Sub(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002010 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002011 m.Int32Constant(0)));
2012 FOR_UINT32_INPUTS(i) {
2013 FOR_INT32_INPUTS(j) {
2014 FOR_UINT32_SHIFTS(shift) {
2015 int32_t right;
2016 switch (shops[n]->opcode()) {
2017 default:
2018 UNREACHABLE();
2019 case IrOpcode::kWord32Sar:
2020 right = *j >> shift;
2021 break;
2022 case IrOpcode::kWord32Shl:
2023 right = *j << shift;
2024 break;
2025 case IrOpcode::kWord32Shr:
2026 right = static_cast<uint32_t>(*j) >> shift;
2027 break;
2028 }
2029 int32_t expected = (*i - right) == 0;
2030 CHECK_EQ(expected, m.Call(*i, *j, shift));
2031 }
2032 }
2033 }
2034 }
2035 }
2036}
2037
2038
2039TEST(RunInt32MulP) {
2040 {
2041 RawMachineAssemblerTester<int32_t> m;
2042 Int32BinopTester bt(&m);
2043 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2044 FOR_INT32_INPUTS(i) {
2045 FOR_INT32_INPUTS(j) {
2046 int expected = static_cast<int32_t>(*i * *j);
2047 CHECK_EQ(expected, bt.call(*i, *j));
2048 }
2049 }
2050 }
2051 {
2052 RawMachineAssemblerTester<int32_t> m;
2053 Uint32BinopTester bt(&m);
2054 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1));
2055 FOR_UINT32_INPUTS(i) {
2056 FOR_UINT32_INPUTS(j) {
2057 uint32_t expected = *i * *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002058 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002059 }
2060 }
2061 }
2062}
2063
2064
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002065TEST(RunInt32MulHighP) {
2066 RawMachineAssemblerTester<int32_t> m;
2067 Int32BinopTester bt(&m);
2068 bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
2069 FOR_INT32_INPUTS(i) {
2070 FOR_INT32_INPUTS(j) {
2071 int32_t expected = static_cast<int32_t>(
2072 (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
2073 CHECK_EQ(expected, bt.call(*i, *j));
2074 }
2075 }
2076}
2077
2078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002079TEST(RunInt32MulImm) {
2080 {
2081 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002082 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002083 m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0)));
2084 FOR_UINT32_INPUTS(j) {
2085 uint32_t expected = *i * *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002086 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002087 }
2088 }
2089 }
2090 {
2091 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002092 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002093 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i)));
2094 FOR_UINT32_INPUTS(j) {
2095 uint32_t expected = *j * *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002096 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002097 }
2098 }
2099 }
2100}
2101
2102
2103TEST(RunInt32MulAndInt32AddP) {
2104 {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002105 FOR_INT32_INPUTS(i) {
2106 FOR_INT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002107 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002108 int32_t p0 = *i;
2109 int32_t p1 = *j;
2110 m.Return(m.Int32Add(m.Int32Constant(p0),
2111 m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
2112 FOR_INT32_INPUTS(k) {
2113 int32_t p2 = *k;
2114 int expected = p0 + static_cast<int32_t>(p1 * p2);
2115 CHECK_EQ(expected, m.Call(p2));
2116 }
2117 }
2118 }
2119 }
2120 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002121 RawMachineAssemblerTester<int32_t> m(
2122 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002123 m.Return(
2124 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2125 FOR_INT32_INPUTS(i) {
2126 FOR_INT32_INPUTS(j) {
2127 FOR_INT32_INPUTS(k) {
2128 int32_t p0 = *i;
2129 int32_t p1 = *j;
2130 int32_t p2 = *k;
2131 int expected = p0 + static_cast<int32_t>(p1 * p2);
2132 CHECK_EQ(expected, m.Call(p0, p1, p2));
2133 }
2134 }
2135 }
2136 }
2137 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002138 RawMachineAssemblerTester<int32_t> m(
2139 MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002140 m.Return(
2141 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
2142 FOR_INT32_INPUTS(i) {
2143 FOR_INT32_INPUTS(j) {
2144 FOR_INT32_INPUTS(k) {
2145 int32_t p0 = *i;
2146 int32_t p1 = *j;
2147 int32_t p2 = *k;
2148 int expected = static_cast<int32_t>(p0 * p1) + p2;
2149 CHECK_EQ(expected, m.Call(p0, p1, p2));
2150 }
2151 }
2152 }
2153 }
2154 {
2155 FOR_INT32_INPUTS(i) {
2156 RawMachineAssemblerTester<int32_t> m;
2157 Int32BinopTester bt(&m);
2158 bt.AddReturn(
2159 m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2160 FOR_INT32_INPUTS(j) {
2161 FOR_INT32_INPUTS(k) {
2162 int32_t p0 = *j;
2163 int32_t p1 = *k;
2164 int expected = *i + static_cast<int32_t>(p0 * p1);
2165 CHECK_EQ(expected, bt.call(p0, p1));
2166 }
2167 }
2168 }
2169 }
2170}
2171
2172
2173TEST(RunInt32MulAndInt32SubP) {
2174 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002175 RawMachineAssemblerTester<int32_t> m(
2176 MachineType::Uint32(), MachineType::Int32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002177 m.Return(
2178 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
2179 FOR_UINT32_INPUTS(i) {
2180 FOR_INT32_INPUTS(j) {
2181 FOR_INT32_INPUTS(k) {
2182 uint32_t p0 = *i;
2183 int32_t p1 = *j;
2184 int32_t p2 = *k;
2185 // Use uint32_t because signed overflow is UB in C.
2186 int expected = p0 - static_cast<uint32_t>(p1 * p2);
2187 CHECK_EQ(expected, m.Call(p0, p1, p2));
2188 }
2189 }
2190 }
2191 }
2192 {
2193 FOR_UINT32_INPUTS(i) {
2194 RawMachineAssemblerTester<int32_t> m;
2195 Int32BinopTester bt(&m);
2196 bt.AddReturn(
2197 m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1)));
2198 FOR_INT32_INPUTS(j) {
2199 FOR_INT32_INPUTS(k) {
2200 int32_t p0 = *j;
2201 int32_t p1 = *k;
2202 // Use uint32_t because signed overflow is UB in C.
2203 int expected = *i - static_cast<uint32_t>(p0 * p1);
2204 CHECK_EQ(expected, bt.call(p0, p1));
2205 }
2206 }
2207 }
2208 }
2209}
2210
2211
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002212TEST(RunUint32MulHighP) {
2213 RawMachineAssemblerTester<int32_t> m;
2214 Int32BinopTester bt(&m);
2215 bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
2216 FOR_UINT32_INPUTS(i) {
2217 FOR_UINT32_INPUTS(j) {
2218 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
2219 (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
2220 CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
2221 }
2222 }
2223}
2224
2225
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002226TEST(RunInt32DivP) {
2227 {
2228 RawMachineAssemblerTester<int32_t> m;
2229 Int32BinopTester bt(&m);
2230 bt.AddReturn(m.Int32Div(bt.param0, bt.param1));
2231 FOR_INT32_INPUTS(i) {
2232 FOR_INT32_INPUTS(j) {
2233 int p0 = *i;
2234 int p1 = *j;
2235 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2236 int expected = static_cast<int32_t>(p0 / p1);
2237 CHECK_EQ(expected, bt.call(p0, p1));
2238 }
2239 }
2240 }
2241 }
2242 {
2243 RawMachineAssemblerTester<int32_t> m;
2244 Int32BinopTester bt(&m);
2245 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1)));
2246 FOR_INT32_INPUTS(i) {
2247 FOR_INT32_INPUTS(j) {
2248 int p0 = *i;
2249 int p1 = *j;
2250 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2251 int expected = static_cast<int32_t>(p0 + (p0 / p1));
2252 CHECK_EQ(expected, bt.call(p0, p1));
2253 }
2254 }
2255 }
2256 }
2257}
2258
2259
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002260TEST(RunUint32DivP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002261 {
2262 RawMachineAssemblerTester<int32_t> m;
2263 Int32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002264 bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002265 FOR_UINT32_INPUTS(i) {
2266 FOR_UINT32_INPUTS(j) {
2267 uint32_t p0 = *i;
2268 uint32_t p1 = *j;
2269 if (p1 != 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002270 int32_t expected = bit_cast<int32_t>(p0 / p1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002271 CHECK_EQ(expected, bt.call(p0, p1));
2272 }
2273 }
2274 }
2275 }
2276 {
2277 RawMachineAssemblerTester<int32_t> m;
2278 Int32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002279 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002280 FOR_UINT32_INPUTS(i) {
2281 FOR_UINT32_INPUTS(j) {
2282 uint32_t p0 = *i;
2283 uint32_t p1 = *j;
2284 if (p1 != 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002285 int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002286 CHECK_EQ(expected, bt.call(p0, p1));
2287 }
2288 }
2289 }
2290 }
2291}
2292
2293
2294TEST(RunInt32ModP) {
2295 {
2296 RawMachineAssemblerTester<int32_t> m;
2297 Int32BinopTester bt(&m);
2298 bt.AddReturn(m.Int32Mod(bt.param0, bt.param1));
2299 FOR_INT32_INPUTS(i) {
2300 FOR_INT32_INPUTS(j) {
2301 int p0 = *i;
2302 int p1 = *j;
2303 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2304 int expected = static_cast<int32_t>(p0 % p1);
2305 CHECK_EQ(expected, bt.call(p0, p1));
2306 }
2307 }
2308 }
2309 }
2310 {
2311 RawMachineAssemblerTester<int32_t> m;
2312 Int32BinopTester bt(&m);
2313 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1)));
2314 FOR_INT32_INPUTS(i) {
2315 FOR_INT32_INPUTS(j) {
2316 int p0 = *i;
2317 int p1 = *j;
2318 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) {
2319 int expected = static_cast<int32_t>(p0 + (p0 % p1));
2320 CHECK_EQ(expected, bt.call(p0, p1));
2321 }
2322 }
2323 }
2324 }
2325}
2326
2327
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002328TEST(RunUint32ModP) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002329 {
2330 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002331 Uint32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002332 bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002333 FOR_UINT32_INPUTS(i) {
2334 FOR_UINT32_INPUTS(j) {
2335 uint32_t p0 = *i;
2336 uint32_t p1 = *j;
2337 if (p1 != 0) {
2338 uint32_t expected = static_cast<uint32_t>(p0 % p1);
2339 CHECK_EQ(expected, bt.call(p0, p1));
2340 }
2341 }
2342 }
2343 }
2344 {
2345 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002346 Uint32BinopTester bt(&m);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002347 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002348 FOR_UINT32_INPUTS(i) {
2349 FOR_UINT32_INPUTS(j) {
2350 uint32_t p0 = *i;
2351 uint32_t p1 = *j;
2352 if (p1 != 0) {
2353 uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1));
2354 CHECK_EQ(expected, bt.call(p0, p1));
2355 }
2356 }
2357 }
2358 }
2359}
2360
2361
2362TEST(RunWord32AndP) {
2363 {
2364 RawMachineAssemblerTester<int32_t> m;
2365 Int32BinopTester bt(&m);
2366 bt.AddReturn(m.Word32And(bt.param0, bt.param1));
2367 FOR_UINT32_INPUTS(i) {
2368 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002369 int32_t expected = *i & *j;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002370 CHECK_EQ(expected, bt.call(*i, *j));
2371 }
2372 }
2373 }
2374 {
2375 RawMachineAssemblerTester<int32_t> m;
2376 Int32BinopTester bt(&m);
2377 bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1)));
2378 FOR_UINT32_INPUTS(i) {
2379 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002380 int32_t expected = *i & ~(*j);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002381 CHECK_EQ(expected, bt.call(*i, *j));
2382 }
2383 }
2384 }
2385 {
2386 RawMachineAssemblerTester<int32_t> m;
2387 Int32BinopTester bt(&m);
2388 bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1));
2389 FOR_UINT32_INPUTS(i) {
2390 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002391 int32_t expected = ~(*i) & *j;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002392 CHECK_EQ(expected, bt.call(*i, *j));
2393 }
2394 }
2395 }
2396}
2397
2398
2399TEST(RunWord32AndAndWord32ShlP) {
2400 {
2401 RawMachineAssemblerTester<int32_t> m;
2402 Uint32BinopTester bt(&m);
2403 bt.AddReturn(
2404 m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2405 FOR_UINT32_INPUTS(i) {
2406 FOR_UINT32_INPUTS(j) {
2407 uint32_t expected = *i << (*j & 0x1f);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002408 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002409 }
2410 }
2411 }
2412 {
2413 RawMachineAssemblerTester<int32_t> m;
2414 Uint32BinopTester bt(&m);
2415 bt.AddReturn(
2416 m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2417 FOR_UINT32_INPUTS(i) {
2418 FOR_UINT32_INPUTS(j) {
2419 uint32_t expected = *i << (0x1f & *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002420 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002421 }
2422 }
2423 }
2424}
2425
2426
2427TEST(RunWord32AndAndWord32ShrP) {
2428 {
2429 RawMachineAssemblerTester<int32_t> m;
2430 Uint32BinopTester bt(&m);
2431 bt.AddReturn(
2432 m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2433 FOR_UINT32_INPUTS(i) {
2434 FOR_UINT32_INPUTS(j) {
2435 uint32_t expected = *i >> (*j & 0x1f);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002436 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002437 }
2438 }
2439 }
2440 {
2441 RawMachineAssemblerTester<int32_t> m;
2442 Uint32BinopTester bt(&m);
2443 bt.AddReturn(
2444 m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2445 FOR_UINT32_INPUTS(i) {
2446 FOR_UINT32_INPUTS(j) {
2447 uint32_t expected = *i >> (0x1f & *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002448 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002449 }
2450 }
2451 }
2452}
2453
2454
2455TEST(RunWord32AndAndWord32SarP) {
2456 {
2457 RawMachineAssemblerTester<int32_t> m;
2458 Int32BinopTester bt(&m);
2459 bt.AddReturn(
2460 m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f))));
2461 FOR_INT32_INPUTS(i) {
2462 FOR_INT32_INPUTS(j) {
2463 int32_t expected = *i >> (*j & 0x1f);
2464 CHECK_EQ(expected, bt.call(*i, *j));
2465 }
2466 }
2467 }
2468 {
2469 RawMachineAssemblerTester<int32_t> m;
2470 Int32BinopTester bt(&m);
2471 bt.AddReturn(
2472 m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1)));
2473 FOR_INT32_INPUTS(i) {
2474 FOR_INT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002475 int32_t expected = *i >> (0x1f & *j);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002476 CHECK_EQ(expected, bt.call(*i, *j));
2477 }
2478 }
2479 }
2480}
2481
2482
2483TEST(RunWord32AndImm) {
2484 {
2485 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002486 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002487 m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0)));
2488 FOR_UINT32_INPUTS(j) {
2489 uint32_t expected = *i & *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002490 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002491 }
2492 }
2493 }
2494 {
2495 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002496 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002497 m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2498 FOR_UINT32_INPUTS(j) {
2499 uint32_t expected = *i & ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002500 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002501 }
2502 }
2503 }
2504}
2505
2506
2507TEST(RunWord32AndInBranch) {
2508 static const int constant = 987654321;
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.Word32Equal(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 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002529 Int32BinopTester bt(&m);
2530 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002531 m.Branch(
2532 m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)),
2533 &blocka, &blockb);
2534 m.Bind(&blocka);
2535 bt.AddReturn(m.Int32Constant(constant));
2536 m.Bind(&blockb);
2537 bt.AddReturn(m.Int32Constant(0 - constant));
2538 FOR_UINT32_INPUTS(i) {
2539 FOR_UINT32_INPUTS(j) {
2540 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2541 CHECK_EQ(expected, bt.call(*i, *j));
2542 }
2543 }
2544 }
2545 {
2546 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002547 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2548 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002549 m.Branch(m.Word32Equal(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 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002564 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
2565 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002566 m.Branch(
2567 m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2568 m.Int32Constant(0)),
2569 &blocka, &blockb);
2570 m.Bind(&blocka);
2571 m.Return(m.Int32Constant(constant));
2572 m.Bind(&blockb);
2573 m.Return(m.Int32Constant(0 - constant));
2574 FOR_UINT32_INPUTS(j) {
2575 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant;
2576 CHECK_EQ(expected, m.Call(*j));
2577 }
2578 }
2579 }
2580 {
2581 RawMachineAssemblerTester<void> m;
2582 const Operator* shops[] = {m.machine()->Word32Sar(),
2583 m.machine()->Word32Shl(),
2584 m.machine()->Word32Shr()};
2585 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002586 RawMachineAssemblerTester<int32_t> m(
2587 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2588 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002589 m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002590 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002591 m.Parameter(2))),
2592 m.Int32Constant(0)),
2593 &blocka, &blockb);
2594 m.Bind(&blocka);
2595 m.Return(m.Int32Constant(constant));
2596 m.Bind(&blockb);
2597 m.Return(m.Int32Constant(0 - constant));
2598 FOR_UINT32_INPUTS(i) {
2599 FOR_INT32_INPUTS(j) {
2600 FOR_UINT32_SHIFTS(shift) {
2601 int32_t right;
2602 switch (shops[n]->opcode()) {
2603 default:
2604 UNREACHABLE();
2605 case IrOpcode::kWord32Sar:
2606 right = *j >> shift;
2607 break;
2608 case IrOpcode::kWord32Shl:
2609 right = *j << shift;
2610 break;
2611 case IrOpcode::kWord32Shr:
2612 right = static_cast<uint32_t>(*j) >> shift;
2613 break;
2614 }
2615 int32_t expected = ((*i & right) == 0) ? constant : 0 - constant;
2616 CHECK_EQ(expected, m.Call(*i, *j, shift));
2617 }
2618 }
2619 }
2620 }
2621 }
2622}
2623
2624
2625TEST(RunWord32AndInComparison) {
2626 {
2627 RawMachineAssemblerTester<int32_t> m;
2628 Uint32BinopTester bt(&m);
2629 bt.AddReturn(
2630 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)));
2631 FOR_UINT32_INPUTS(i) {
2632 FOR_UINT32_INPUTS(j) {
2633 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002634 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002635 }
2636 }
2637 }
2638 {
2639 RawMachineAssemblerTester<int32_t> m;
2640 Uint32BinopTester bt(&m);
2641 bt.AddReturn(
2642 m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1)));
2643 FOR_UINT32_INPUTS(i) {
2644 FOR_UINT32_INPUTS(j) {
2645 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002646 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002647 }
2648 }
2649 }
2650 {
2651 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002652 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002653 m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)),
2654 m.Int32Constant(0)));
2655 FOR_UINT32_INPUTS(j) {
2656 uint32_t expected = (*i & *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002657 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002658 }
2659 }
2660 }
2661 {
2662 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002663 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002664 m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)),
2665 m.Int32Constant(0)));
2666 FOR_UINT32_INPUTS(j) {
2667 uint32_t expected = (*j & *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002668 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002669 }
2670 }
2671 }
2672}
2673
2674
2675TEST(RunWord32OrP) {
2676 {
2677 RawMachineAssemblerTester<int32_t> m;
2678 Uint32BinopTester bt(&m);
2679 bt.AddReturn(m.Word32Or(bt.param0, bt.param1));
2680 FOR_UINT32_INPUTS(i) {
2681 FOR_UINT32_INPUTS(j) {
2682 uint32_t expected = *i | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002683 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002684 }
2685 }
2686 }
2687 {
2688 RawMachineAssemblerTester<int32_t> m;
2689 Uint32BinopTester bt(&m);
2690 bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1)));
2691 FOR_UINT32_INPUTS(i) {
2692 FOR_UINT32_INPUTS(j) {
2693 uint32_t expected = *i | ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002694 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002695 }
2696 }
2697 }
2698 {
2699 RawMachineAssemblerTester<int32_t> m;
2700 Uint32BinopTester bt(&m);
2701 bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1));
2702 FOR_UINT32_INPUTS(i) {
2703 FOR_UINT32_INPUTS(j) {
2704 uint32_t expected = ~(*i) | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002705 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002706 }
2707 }
2708 }
2709}
2710
2711
2712TEST(RunWord32OrImm) {
2713 {
2714 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002715 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002716 m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)));
2717 FOR_UINT32_INPUTS(j) {
2718 uint32_t expected = *i | *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002719 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002720 }
2721 }
2722 }
2723 {
2724 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002725 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002726 m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2727 FOR_UINT32_INPUTS(j) {
2728 uint32_t expected = *i | ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002729 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002730 }
2731 }
2732 }
2733}
2734
2735
2736TEST(RunWord32OrInBranch) {
2737 static const int constant = 987654321;
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.Word32Equal(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 RawMachineAssemblerTester<int32_t> m;
2758 Int32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002759 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002760 m.Branch(
2761 m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)),
2762 &blocka, &blockb);
2763 m.Bind(&blocka);
2764 bt.AddReturn(m.Int32Constant(constant));
2765 m.Bind(&blockb);
2766 bt.AddReturn(m.Int32Constant(0 - constant));
2767 FOR_INT32_INPUTS(i) {
2768 FOR_INT32_INPUTS(j) {
2769 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2770 CHECK_EQ(expected, bt.call(*i, *j));
2771 }
2772 }
2773 }
2774 {
2775 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002776 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2777 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002778 m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2779 m.Int32Constant(0)),
2780 &blocka, &blockb);
2781 m.Bind(&blocka);
2782 m.Return(m.Int32Constant(constant));
2783 m.Bind(&blockb);
2784 m.Return(m.Int32Constant(0 - constant));
2785 FOR_INT32_INPUTS(j) {
2786 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant;
2787 CHECK_EQ(expected, m.Call(*j));
2788 }
2789 }
2790 }
2791 {
2792 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002793 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
2794 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002795 m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2796 m.Int32Constant(0)),
2797 &blocka, &blockb);
2798 m.Bind(&blocka);
2799 m.Return(m.Int32Constant(constant));
2800 m.Bind(&blockb);
2801 m.Return(m.Int32Constant(0 - constant));
2802 FOR_INT32_INPUTS(j) {
2803 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant;
2804 CHECK_EQ(expected, m.Call(*j));
2805 }
2806 }
2807 }
2808 {
2809 RawMachineAssemblerTester<void> m;
2810 const Operator* shops[] = {m.machine()->Word32Sar(),
2811 m.machine()->Word32Shl(),
2812 m.machine()->Word32Shr()};
2813 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002814 RawMachineAssemblerTester<int32_t> m(
2815 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
2816 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002817 m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002818 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002819 m.Parameter(2))),
2820 m.Int32Constant(0)),
2821 &blocka, &blockb);
2822 m.Bind(&blocka);
2823 m.Return(m.Int32Constant(constant));
2824 m.Bind(&blockb);
2825 m.Return(m.Int32Constant(0 - constant));
2826 FOR_UINT32_INPUTS(i) {
2827 FOR_INT32_INPUTS(j) {
2828 FOR_UINT32_SHIFTS(shift) {
2829 int32_t right;
2830 switch (shops[n]->opcode()) {
2831 default:
2832 UNREACHABLE();
2833 case IrOpcode::kWord32Sar:
2834 right = *j >> shift;
2835 break;
2836 case IrOpcode::kWord32Shl:
2837 right = *j << shift;
2838 break;
2839 case IrOpcode::kWord32Shr:
2840 right = static_cast<uint32_t>(*j) >> shift;
2841 break;
2842 }
2843 int32_t expected = ((*i | right) == 0) ? constant : 0 - constant;
2844 CHECK_EQ(expected, m.Call(*i, *j, shift));
2845 }
2846 }
2847 }
2848 }
2849 }
2850}
2851
2852
2853TEST(RunWord32OrInComparison) {
2854 {
2855 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002856 Int32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002857 bt.AddReturn(
2858 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)));
2859 FOR_UINT32_INPUTS(i) {
2860 FOR_UINT32_INPUTS(j) {
2861 int32_t expected = (*i | *j) == 0;
2862 CHECK_EQ(expected, bt.call(*i, *j));
2863 }
2864 }
2865 }
2866 {
2867 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002868 Int32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002869 bt.AddReturn(
2870 m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1)));
2871 FOR_UINT32_INPUTS(i) {
2872 FOR_UINT32_INPUTS(j) {
2873 int32_t expected = (*i | *j) == 0;
2874 CHECK_EQ(expected, bt.call(*i, *j));
2875 }
2876 }
2877 }
2878 {
2879 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002880 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002881 m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)),
2882 m.Int32Constant(0)));
2883 FOR_UINT32_INPUTS(j) {
2884 uint32_t expected = (*i | *j) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002885 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002886 }
2887 }
2888 }
2889 {
2890 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002891 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002892 m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)),
2893 m.Int32Constant(0)));
2894 FOR_UINT32_INPUTS(j) {
2895 uint32_t expected = (*j | *i) == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002896 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002897 }
2898 }
2899 }
2900}
2901
2902
2903TEST(RunWord32XorP) {
2904 {
2905 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002906 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002907 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)));
2908 FOR_UINT32_INPUTS(j) {
2909 uint32_t expected = *i ^ *j;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002910 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002911 }
2912 }
2913 }
2914 {
2915 RawMachineAssemblerTester<int32_t> m;
2916 Uint32BinopTester bt(&m);
2917 bt.AddReturn(m.Word32Xor(bt.param0, bt.param1));
2918 FOR_UINT32_INPUTS(i) {
2919 FOR_UINT32_INPUTS(j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002920 uint32_t expected = *i ^ *j;
2921 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002922 }
2923 }
2924 }
2925 {
2926 RawMachineAssemblerTester<int32_t> m;
2927 Int32BinopTester bt(&m);
2928 bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1)));
2929 FOR_INT32_INPUTS(i) {
2930 FOR_INT32_INPUTS(j) {
2931 int32_t expected = *i ^ ~(*j);
2932 CHECK_EQ(expected, bt.call(*i, *j));
2933 }
2934 }
2935 }
2936 {
2937 RawMachineAssemblerTester<int32_t> m;
2938 Int32BinopTester bt(&m);
2939 bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1));
2940 FOR_INT32_INPUTS(i) {
2941 FOR_INT32_INPUTS(j) {
2942 int32_t expected = ~(*i) ^ *j;
2943 CHECK_EQ(expected, bt.call(*i, *j));
2944 }
2945 }
2946 }
2947 {
2948 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002949 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002950 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0))));
2951 FOR_UINT32_INPUTS(j) {
2952 uint32_t expected = *i ^ ~(*j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002953 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002954 }
2955 }
2956 }
2957}
2958
2959
2960TEST(RunWord32XorInBranch) {
2961 static const uint32_t constant = 987654321;
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.Word32Equal(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 RawMachineAssemblerTester<int32_t> m;
2982 Uint32BinopTester bt(&m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002983 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002984 m.Branch(
2985 m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)),
2986 &blocka, &blockb);
2987 m.Bind(&blocka);
2988 bt.AddReturn(m.Int32Constant(constant));
2989 m.Bind(&blockb);
2990 bt.AddReturn(m.Int32Constant(0 - constant));
2991 FOR_UINT32_INPUTS(i) {
2992 FOR_UINT32_INPUTS(j) {
2993 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002994 CHECK_EQ(expected, bt.call(*i, *j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002995 }
2996 }
2997 }
2998 {
2999 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003000 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3001 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003002 m.Branch(m.Word32Equal(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 FOR_UINT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003017 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
3018 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003019 m.Branch(
3020 m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)),
3021 m.Int32Constant(0)),
3022 &blocka, &blockb);
3023 m.Bind(&blocka);
3024 m.Return(m.Int32Constant(constant));
3025 m.Bind(&blockb);
3026 m.Return(m.Int32Constant(0 - constant));
3027 FOR_UINT32_INPUTS(j) {
3028 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003029 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003030 }
3031 }
3032 }
3033 {
3034 RawMachineAssemblerTester<void> m;
3035 const Operator* shops[] = {m.machine()->Word32Sar(),
3036 m.machine()->Word32Shl(),
3037 m.machine()->Word32Shr()};
3038 for (size_t n = 0; n < arraysize(shops); n++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003039 RawMachineAssemblerTester<int32_t> m(
3040 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32());
3041 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003042 m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003043 m.AddNode(shops[n], m.Parameter(1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003044 m.Parameter(2))),
3045 m.Int32Constant(0)),
3046 &blocka, &blockb);
3047 m.Bind(&blocka);
3048 m.Return(m.Int32Constant(constant));
3049 m.Bind(&blockb);
3050 m.Return(m.Int32Constant(0 - constant));
3051 FOR_UINT32_INPUTS(i) {
3052 FOR_INT32_INPUTS(j) {
3053 FOR_UINT32_SHIFTS(shift) {
3054 int32_t right;
3055 switch (shops[n]->opcode()) {
3056 default:
3057 UNREACHABLE();
3058 case IrOpcode::kWord32Sar:
3059 right = *j >> shift;
3060 break;
3061 case IrOpcode::kWord32Shl:
3062 right = *j << shift;
3063 break;
3064 case IrOpcode::kWord32Shr:
3065 right = static_cast<uint32_t>(*j) >> shift;
3066 break;
3067 }
3068 int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant;
3069 CHECK_EQ(expected, m.Call(*i, *j, shift));
3070 }
3071 }
3072 }
3073 }
3074 }
3075}
3076
3077
3078TEST(RunWord32ShlP) {
3079 {
3080 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003081 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003082 m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)));
3083 FOR_UINT32_INPUTS(j) {
3084 uint32_t expected = *j << shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003085 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003086 }
3087 }
3088 }
3089 {
3090 RawMachineAssemblerTester<int32_t> m;
3091 Uint32BinopTester bt(&m);
3092 bt.AddReturn(m.Word32Shl(bt.param0, bt.param1));
3093 FOR_UINT32_INPUTS(i) {
3094 FOR_UINT32_SHIFTS(shift) {
3095 uint32_t expected = *i << shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003096 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003097 }
3098 }
3099 }
3100}
3101
3102
3103TEST(RunWord32ShlInComparison) {
3104 {
3105 RawMachineAssemblerTester<int32_t> m;
3106 Uint32BinopTester bt(&m);
3107 bt.AddReturn(
3108 m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0)));
3109 FOR_UINT32_INPUTS(i) {
3110 FOR_UINT32_SHIFTS(shift) {
3111 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003112 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003113 }
3114 }
3115 }
3116 {
3117 RawMachineAssemblerTester<int32_t> m;
3118 Uint32BinopTester bt(&m);
3119 bt.AddReturn(
3120 m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1)));
3121 FOR_UINT32_INPUTS(i) {
3122 FOR_UINT32_SHIFTS(shift) {
3123 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003124 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003125 }
3126 }
3127 }
3128 {
3129 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003130 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003131 m.Return(
3132 m.Word32Equal(m.Int32Constant(0),
3133 m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))));
3134 FOR_UINT32_INPUTS(i) {
3135 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003136 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003137 }
3138 }
3139 }
3140 {
3141 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003142 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003143 m.Return(
3144 m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)),
3145 m.Int32Constant(0)));
3146 FOR_UINT32_INPUTS(i) {
3147 uint32_t expected = 0 == (*i << shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003148 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003149 }
3150 }
3151 }
3152}
3153
3154
3155TEST(RunWord32ShrP) {
3156 {
3157 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003158 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003159 m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)));
3160 FOR_UINT32_INPUTS(j) {
3161 uint32_t expected = *j >> shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003162 CHECK_EQ(expected, m.Call(*j));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003163 }
3164 }
3165 }
3166 {
3167 RawMachineAssemblerTester<int32_t> m;
3168 Uint32BinopTester bt(&m);
3169 bt.AddReturn(m.Word32Shr(bt.param0, bt.param1));
3170 FOR_UINT32_INPUTS(i) {
3171 FOR_UINT32_SHIFTS(shift) {
3172 uint32_t expected = *i >> shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003173 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003174 }
3175 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003176 CHECK_EQ(0x00010000u, bt.call(0x80000000, 15));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003177 }
3178}
3179
3180
3181TEST(RunWord32ShrInComparison) {
3182 {
3183 RawMachineAssemblerTester<int32_t> m;
3184 Uint32BinopTester bt(&m);
3185 bt.AddReturn(
3186 m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0)));
3187 FOR_UINT32_INPUTS(i) {
3188 FOR_UINT32_SHIFTS(shift) {
3189 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003190 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003191 }
3192 }
3193 }
3194 {
3195 RawMachineAssemblerTester<int32_t> m;
3196 Uint32BinopTester bt(&m);
3197 bt.AddReturn(
3198 m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1)));
3199 FOR_UINT32_INPUTS(i) {
3200 FOR_UINT32_SHIFTS(shift) {
3201 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003202 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003203 }
3204 }
3205 }
3206 {
3207 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003208 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003209 m.Return(
3210 m.Word32Equal(m.Int32Constant(0),
3211 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
3212 FOR_UINT32_INPUTS(i) {
3213 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003214 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003215 }
3216 }
3217 }
3218 {
3219 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003220 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003221 m.Return(
3222 m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
3223 m.Int32Constant(0)));
3224 FOR_UINT32_INPUTS(i) {
3225 uint32_t expected = 0 == (*i >> shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003226 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003227 }
3228 }
3229 }
3230}
3231
3232
3233TEST(RunWord32SarP) {
3234 {
3235 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003236 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003237 m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)));
3238 FOR_INT32_INPUTS(j) {
3239 int32_t expected = *j >> shift;
3240 CHECK_EQ(expected, m.Call(*j));
3241 }
3242 }
3243 }
3244 {
3245 RawMachineAssemblerTester<int32_t> m;
3246 Int32BinopTester bt(&m);
3247 bt.AddReturn(m.Word32Sar(bt.param0, bt.param1));
3248 FOR_INT32_INPUTS(i) {
3249 FOR_INT32_SHIFTS(shift) {
3250 int32_t expected = *i >> shift;
3251 CHECK_EQ(expected, bt.call(*i, shift));
3252 }
3253 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003254 CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003255 }
3256}
3257
3258
3259TEST(RunWord32SarInComparison) {
3260 {
3261 RawMachineAssemblerTester<int32_t> m;
3262 Int32BinopTester bt(&m);
3263 bt.AddReturn(
3264 m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0)));
3265 FOR_INT32_INPUTS(i) {
3266 FOR_INT32_SHIFTS(shift) {
3267 int32_t expected = 0 == (*i >> shift);
3268 CHECK_EQ(expected, bt.call(*i, shift));
3269 }
3270 }
3271 }
3272 {
3273 RawMachineAssemblerTester<int32_t> m;
3274 Int32BinopTester bt(&m);
3275 bt.AddReturn(
3276 m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1)));
3277 FOR_INT32_INPUTS(i) {
3278 FOR_INT32_SHIFTS(shift) {
3279 int32_t expected = 0 == (*i >> shift);
3280 CHECK_EQ(expected, bt.call(*i, shift));
3281 }
3282 }
3283 }
3284 {
3285 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003286 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003287 m.Return(
3288 m.Word32Equal(m.Int32Constant(0),
3289 m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))));
3290 FOR_INT32_INPUTS(i) {
3291 int32_t expected = 0 == (*i >> shift);
3292 CHECK_EQ(expected, m.Call(*i));
3293 }
3294 }
3295 }
3296 {
3297 FOR_INT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003298 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003299 m.Return(
3300 m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)),
3301 m.Int32Constant(0)));
3302 FOR_INT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003303 int32_t expected = 0 == (*i >> shift);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003304 CHECK_EQ(expected, m.Call(*i));
3305 }
3306 }
3307 }
3308}
3309
3310
3311TEST(RunWord32RorP) {
3312 {
3313 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003314 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003315 m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)));
3316 FOR_UINT32_INPUTS(j) {
3317 int32_t expected = bits::RotateRight32(*j, shift);
3318 CHECK_EQ(expected, m.Call(*j));
3319 }
3320 }
3321 }
3322 {
3323 RawMachineAssemblerTester<int32_t> m;
3324 Uint32BinopTester bt(&m);
3325 bt.AddReturn(m.Word32Ror(bt.param0, bt.param1));
3326 FOR_UINT32_INPUTS(i) {
3327 FOR_UINT32_SHIFTS(shift) {
3328 uint32_t expected = bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003329 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003330 }
3331 }
3332 }
3333}
3334
3335
3336TEST(RunWord32RorInComparison) {
3337 {
3338 RawMachineAssemblerTester<int32_t> m;
3339 Uint32BinopTester bt(&m);
3340 bt.AddReturn(
3341 m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0)));
3342 FOR_UINT32_INPUTS(i) {
3343 FOR_UINT32_SHIFTS(shift) {
3344 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003345 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003346 }
3347 }
3348 }
3349 {
3350 RawMachineAssemblerTester<int32_t> m;
3351 Uint32BinopTester bt(&m);
3352 bt.AddReturn(
3353 m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1)));
3354 FOR_UINT32_INPUTS(i) {
3355 FOR_UINT32_SHIFTS(shift) {
3356 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003357 CHECK_EQ(expected, bt.call(*i, shift));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003358 }
3359 }
3360 }
3361 {
3362 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003363 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003364 m.Return(
3365 m.Word32Equal(m.Int32Constant(0),
3366 m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))));
3367 FOR_UINT32_INPUTS(i) {
3368 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003369 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003370 }
3371 }
3372 }
3373 {
3374 FOR_UINT32_SHIFTS(shift) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003375 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003376 m.Return(
3377 m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)),
3378 m.Int32Constant(0)));
3379 FOR_UINT32_INPUTS(i) {
3380 uint32_t expected = 0 == bits::RotateRight32(*i, shift);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003381 CHECK_EQ(expected, m.Call(*i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003382 }
3383 }
3384 }
3385}
3386
3387
3388TEST(RunWord32NotP) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003389 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003390 m.Return(m.Word32Not(m.Parameter(0)));
3391 FOR_INT32_INPUTS(i) {
3392 int expected = ~(*i);
3393 CHECK_EQ(expected, m.Call(*i));
3394 }
3395}
3396
3397
3398TEST(RunInt32NegP) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003399 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003400 m.Return(m.Int32Neg(m.Parameter(0)));
3401 FOR_INT32_INPUTS(i) {
3402 int expected = -*i;
3403 CHECK_EQ(expected, m.Call(*i));
3404 }
3405}
3406
3407
3408TEST(RunWord32EqualAndWord32SarP) {
3409 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003410 RawMachineAssemblerTester<int32_t> m(
3411 MachineType::Int32(), MachineType::Int32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003412 m.Return(m.Word32Equal(m.Parameter(0),
3413 m.Word32Sar(m.Parameter(1), m.Parameter(2))));
3414 FOR_INT32_INPUTS(i) {
3415 FOR_INT32_INPUTS(j) {
3416 FOR_UINT32_SHIFTS(shift) {
3417 int32_t expected = (*i == (*j >> shift));
3418 CHECK_EQ(expected, m.Call(*i, *j, shift));
3419 }
3420 }
3421 }
3422 }
3423 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003424 RawMachineAssemblerTester<int32_t> m(
3425 MachineType::Int32(), MachineType::Uint32(), MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003426 m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)),
3427 m.Parameter(2)));
3428 FOR_INT32_INPUTS(i) {
3429 FOR_UINT32_SHIFTS(shift) {
3430 FOR_INT32_INPUTS(k) {
3431 int32_t expected = ((*i >> shift) == *k);
3432 CHECK_EQ(expected, m.Call(*i, shift, *k));
3433 }
3434 }
3435 }
3436 }
3437}
3438
3439
3440TEST(RunWord32EqualAndWord32ShlP) {
3441 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003442 RawMachineAssemblerTester<int32_t> m(
3443 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003444 m.Return(m.Word32Equal(m.Parameter(0),
3445 m.Word32Shl(m.Parameter(1), m.Parameter(2))));
3446 FOR_UINT32_INPUTS(i) {
3447 FOR_UINT32_INPUTS(j) {
3448 FOR_UINT32_SHIFTS(shift) {
3449 int32_t expected = (*i == (*j << shift));
3450 CHECK_EQ(expected, m.Call(*i, *j, shift));
3451 }
3452 }
3453 }
3454 }
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.Word32Shl(m.Parameter(0), m.Parameter(1)),
3459 m.Parameter(2)));
3460 FOR_UINT32_INPUTS(i) {
3461 FOR_UINT32_SHIFTS(shift) {
3462 FOR_UINT32_INPUTS(k) {
3463 int32_t expected = ((*i << shift) == *k);
3464 CHECK_EQ(expected, m.Call(*i, shift, *k));
3465 }
3466 }
3467 }
3468 }
3469}
3470
3471
3472TEST(RunWord32EqualAndWord32ShrP) {
3473 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003474 RawMachineAssemblerTester<int32_t> m(
3475 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003476 m.Return(m.Word32Equal(m.Parameter(0),
3477 m.Word32Shr(m.Parameter(1), m.Parameter(2))));
3478 FOR_UINT32_INPUTS(i) {
3479 FOR_UINT32_INPUTS(j) {
3480 FOR_UINT32_SHIFTS(shift) {
3481 int32_t expected = (*i == (*j >> shift));
3482 CHECK_EQ(expected, m.Call(*i, *j, shift));
3483 }
3484 }
3485 }
3486 }
3487 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003488 RawMachineAssemblerTester<int32_t> m(
3489 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003490 m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)),
3491 m.Parameter(2)));
3492 FOR_UINT32_INPUTS(i) {
3493 FOR_UINT32_SHIFTS(shift) {
3494 FOR_UINT32_INPUTS(k) {
3495 int32_t expected = ((*i >> shift) == *k);
3496 CHECK_EQ(expected, m.Call(*i, shift, *k));
3497 }
3498 }
3499 }
3500 }
3501}
3502
3503
3504TEST(RunDeadNodes) {
3505 for (int i = 0; true; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003506 RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32()
3507 : MachineType::None());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003508 int constant = 0x55 + i;
3509 switch (i) {
3510 case 0:
3511 m.Int32Constant(44);
3512 break;
3513 case 1:
3514 m.StringConstant("unused");
3515 break;
3516 case 2:
3517 m.NumberConstant(11.1);
3518 break;
3519 case 3:
3520 m.PointerConstant(&constant);
3521 break;
3522 case 4:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003523 m.LoadFromPointer(&constant, MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003524 break;
3525 case 5:
3526 m.Parameter(0);
3527 break;
3528 default:
3529 return;
3530 }
3531 m.Return(m.Int32Constant(constant));
3532 if (i != 5) {
3533 CHECK_EQ(constant, m.Call());
3534 } else {
3535 CHECK_EQ(constant, m.Call(0));
3536 }
3537 }
3538}
3539
3540
3541TEST(RunDeadInt32Binops) {
3542 RawMachineAssemblerTester<int32_t> m;
3543
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003544 const Operator* kOps[] = {
3545 m.machine()->Word32And(), m.machine()->Word32Or(),
3546 m.machine()->Word32Xor(), m.machine()->Word32Shl(),
3547 m.machine()->Word32Shr(), m.machine()->Word32Sar(),
3548 m.machine()->Word32Ror(), m.machine()->Word32Equal(),
3549 m.machine()->Int32Add(), m.machine()->Int32Sub(),
3550 m.machine()->Int32Mul(), m.machine()->Int32MulHigh(),
3551 m.machine()->Int32Div(), m.machine()->Uint32Div(),
3552 m.machine()->Int32Mod(), m.machine()->Uint32Mod(),
3553 m.machine()->Uint32MulHigh(), m.machine()->Int32LessThan(),
3554 m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
3555 m.machine()->Uint32LessThanOrEqual()};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003556
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003557 for (size_t i = 0; i < arraysize(kOps); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003558 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
3559 MachineType::Int32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003560 int32_t constant = static_cast<int32_t>(0x55555 + i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003561 m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003562 m.Return(m.Int32Constant(constant));
3563
3564 CHECK_EQ(constant, m.Call(1, 1));
3565 }
3566}
3567
3568
3569template <typename Type>
3570static void RunLoadImmIndex(MachineType rep) {
3571 const int kNumElems = 3;
3572 Type buffer[kNumElems];
3573
Ben Murdoch097c5b22016-05-18 11:27:45 +01003574 // initialize the buffer with some raw data.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003575 byte* raw = reinterpret_cast<byte*>(buffer);
3576 for (size_t i = 0; i < sizeof(buffer); i++) {
3577 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
3578 }
3579
3580 // Test with various large and small offsets.
3581 for (int offset = -1; offset <= 200000; offset *= -5) {
3582 for (int i = 0; i < kNumElems; i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003583 BufferedRawMachineAssemblerTester<Type> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003584 Node* base = m.PointerConstant(buffer - offset);
3585 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
3586 m.Return(m.Load(rep, base, index));
3587
Ben Murdoch097c5b22016-05-18 11:27:45 +01003588 volatile Type expected = buffer[i];
3589 volatile Type actual = m.Call();
3590 CHECK_EQ(expected, actual);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003591 }
3592 }
3593}
3594
3595
3596TEST(RunLoadImmIndex) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003597 RunLoadImmIndex<int8_t>(MachineType::Int8());
3598 RunLoadImmIndex<uint8_t>(MachineType::Uint8());
3599 RunLoadImmIndex<int16_t>(MachineType::Int16());
3600 RunLoadImmIndex<uint16_t>(MachineType::Uint16());
3601 RunLoadImmIndex<int32_t>(MachineType::Int32());
3602 RunLoadImmIndex<uint32_t>(MachineType::Uint32());
3603 RunLoadImmIndex<int32_t*>(MachineType::AnyTagged());
Ben Murdoch097c5b22016-05-18 11:27:45 +01003604 RunLoadImmIndex<float>(MachineType::Float32());
3605 RunLoadImmIndex<double>(MachineType::Float64());
3606 if (kPointerSize == 8) {
3607 RunLoadImmIndex<int64_t>(MachineType::Int64());
3608 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003609 // TODO(titzer): test various indexing modes.
3610}
3611
3612
3613template <typename CType>
3614static void RunLoadStore(MachineType rep) {
3615 const int kNumElems = 4;
3616 CType buffer[kNumElems];
3617
3618 for (int32_t x = 0; x < kNumElems; x++) {
3619 int32_t y = kNumElems - x - 1;
3620 // initialize the buffer with raw data.
3621 byte* raw = reinterpret_cast<byte*>(buffer);
3622 for (size_t i = 0; i < sizeof(buffer); i++) {
3623 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
3624 }
3625
3626 RawMachineAssemblerTester<int32_t> m;
3627 int32_t OK = 0x29000 + x;
3628 Node* base = m.PointerConstant(buffer);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003629 Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0]));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003630 Node* load = m.Load(rep, base, index0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003631 Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0]));
3632 m.Store(rep.representation(), base, index1, load, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003633 m.Return(m.Int32Constant(OK));
3634
3635 CHECK(buffer[x] != buffer[y]);
3636 CHECK_EQ(OK, m.Call());
3637 CHECK(buffer[x] == buffer[y]);
3638 }
3639}
3640
3641
3642TEST(RunLoadStore) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003643 RunLoadStore<int8_t>(MachineType::Int8());
3644 RunLoadStore<uint8_t>(MachineType::Uint8());
3645 RunLoadStore<int16_t>(MachineType::Int16());
3646 RunLoadStore<uint16_t>(MachineType::Uint16());
3647 RunLoadStore<int32_t>(MachineType::Int32());
3648 RunLoadStore<uint32_t>(MachineType::Uint32());
3649 RunLoadStore<void*>(MachineType::AnyTagged());
3650 RunLoadStore<float>(MachineType::Float32());
3651 RunLoadStore<double>(MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003652}
3653
3654
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003655TEST(RunFloat32Add) {
3656 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3657 MachineType::Float32());
3658 m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1)));
3659
3660 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003661 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i + *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003662 }
3663}
3664
3665
3666TEST(RunFloat32Sub) {
3667 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3668 MachineType::Float32());
3669 m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1)));
3670
3671 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003672 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003673 }
3674}
3675
3676
3677TEST(RunFloat32Mul) {
3678 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3679 MachineType::Float32());
3680 m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1)));
3681
3682 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003683 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i * *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003684 }
3685}
3686
3687
3688TEST(RunFloat32Div) {
3689 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3690 MachineType::Float32());
3691 m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1)));
3692
3693 FOR_FLOAT32_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003694 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i / *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003695 }
3696}
3697
3698
3699TEST(RunFloat64Add) {
3700 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3701 MachineType::Float64());
3702 m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1)));
3703
3704 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003705 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i + *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003706 }
3707}
3708
3709
3710TEST(RunFloat64Sub) {
3711 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3712 MachineType::Float64());
3713 m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1)));
3714
3715 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003716 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i - *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003717 }
3718}
3719
3720
3721TEST(RunFloat64Mul) {
3722 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3723 MachineType::Float64());
3724 m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1)));
3725
3726 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003727 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i * *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003728 }
3729}
3730
3731
3732TEST(RunFloat64Div) {
3733 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3734 MachineType::Float64());
3735 m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1)));
3736
3737 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003738 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i / *j, m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003739 }
3740}
3741
3742
3743TEST(RunFloat64Mod) {
3744 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3745 MachineType::Float64());
3746 m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
3747
3748 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01003749 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), m.Call(*i, *j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003750 }
3751}
3752
3753
3754TEST(RunDeadFloat32Binops) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003755 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003756
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003757 const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(),
3758 m.machine()->Float32Mul(), m.machine()->Float32Div(),
3759 NULL};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003760
3761 for (int i = 0; ops[i] != NULL; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003762 RawMachineAssemblerTester<int32_t> m;
3763 int constant = 0x53355 + i;
3764 m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f));
3765 m.Return(m.Int32Constant(constant));
3766 CHECK_EQ(constant, m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003767 }
3768}
3769
3770
3771TEST(RunDeadFloat64Binops) {
3772 RawMachineAssemblerTester<int32_t> m;
3773
3774 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3775 m.machine()->Float64Mul(), m.machine()->Float64Div(),
3776 m.machine()->Float64Mod(), NULL};
3777
3778 for (int i = 0; ops[i] != NULL; i++) {
3779 RawMachineAssemblerTester<int32_t> m;
3780 int constant = 0x53355 + i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003781 m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003782 m.Return(m.Int32Constant(constant));
3783 CHECK_EQ(constant, m.Call());
3784 }
3785}
3786
3787
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003788TEST(RunFloat32AddP) {
3789 RawMachineAssemblerTester<int32_t> m;
3790 Float32BinopTester bt(&m);
3791
3792 bt.AddReturn(m.Float32Add(bt.param0, bt.param1));
3793
3794 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003795 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl + *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003796 }
3797}
3798
3799
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003800TEST(RunFloat64AddP) {
3801 RawMachineAssemblerTester<int32_t> m;
3802 Float64BinopTester bt(&m);
3803
3804 bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
3805
3806 FOR_FLOAT64_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003807 FOR_FLOAT64_INPUTS(pr) { CHECK_DOUBLE_EQ(*pl + *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003808 }
3809}
3810
3811
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003812TEST(RunFloa32MaxP) {
3813 RawMachineAssemblerTester<int32_t> m;
3814 Float32BinopTester bt(&m);
3815 if (!m.machine()->Float32Max().IsSupported()) return;
3816
3817 bt.AddReturn(m.Float32Max(bt.param0, bt.param1));
3818
3819 FOR_FLOAT32_INPUTS(pl) {
3820 FOR_FLOAT32_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003821 CHECK_DOUBLE_EQ(*pl > *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003822 }
3823 }
3824}
3825
3826
3827TEST(RunFloat64MaxP) {
3828 RawMachineAssemblerTester<int32_t> m;
3829 Float64BinopTester bt(&m);
3830 if (!m.machine()->Float64Max().IsSupported()) return;
3831
3832 bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
3833
3834 FOR_FLOAT64_INPUTS(pl) {
3835 FOR_FLOAT64_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003836 CHECK_DOUBLE_EQ(*pl > *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003837 }
3838 }
3839}
3840
3841
3842TEST(RunFloat32MinP) {
3843 RawMachineAssemblerTester<int32_t> m;
3844 Float32BinopTester bt(&m);
3845 if (!m.machine()->Float32Min().IsSupported()) return;
3846
3847 bt.AddReturn(m.Float32Min(bt.param0, bt.param1));
3848
3849 FOR_FLOAT32_INPUTS(pl) {
3850 FOR_FLOAT32_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003851 CHECK_DOUBLE_EQ(*pl < *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003852 }
3853 }
3854}
3855
3856
3857TEST(RunFloat64MinP) {
3858 RawMachineAssemblerTester<int32_t> m;
3859 Float64BinopTester bt(&m);
3860 if (!m.machine()->Float64Min().IsSupported()) return;
3861
3862 bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
3863
3864 FOR_FLOAT64_INPUTS(pl) {
3865 FOR_FLOAT64_INPUTS(pr) {
Ben Murdochda12d292016-06-02 14:46:10 +01003866 CHECK_DOUBLE_EQ(*pl < *pr ? *pl : *pr, bt.call(*pl, *pr));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003867 }
3868 }
3869}
3870
3871
3872TEST(RunFloat32SubP) {
3873 RawMachineAssemblerTester<int32_t> m;
3874 Float32BinopTester bt(&m);
3875
3876 bt.AddReturn(m.Float32Sub(bt.param0, bt.param1));
3877
3878 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003879 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl - *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003880 }
3881}
3882
3883
3884TEST(RunFloat32SubImm1) {
3885 FOR_FLOAT32_INPUTS(i) {
3886 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3887 m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0)));
3888
Ben Murdochda12d292016-06-02 14:46:10 +01003889 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003890 }
3891}
3892
3893
3894TEST(RunFloat32SubImm2) {
3895 FOR_FLOAT32_INPUTS(i) {
3896 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3897 m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i)));
3898
Ben Murdochda12d292016-06-02 14:46:10 +01003899 FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*j - *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003900 }
3901}
3902
3903
3904TEST(RunFloat64SubImm1) {
3905 FOR_FLOAT64_INPUTS(i) {
3906 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3907 m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
3908
Ben Murdochda12d292016-06-02 14:46:10 +01003909 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003910 }
3911}
3912
3913
3914TEST(RunFloat64SubImm2) {
3915 FOR_FLOAT64_INPUTS(i) {
3916 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3917 m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
3918
Ben Murdochda12d292016-06-02 14:46:10 +01003919 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j - *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003920 }
3921}
3922
3923
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003924TEST(RunFloat64SubP) {
3925 RawMachineAssemblerTester<int32_t> m;
3926 Float64BinopTester bt(&m);
3927
3928 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
3929
3930 FOR_FLOAT64_INPUTS(pl) {
3931 FOR_FLOAT64_INPUTS(pr) {
3932 double expected = *pl - *pr;
Ben Murdochda12d292016-06-02 14:46:10 +01003933 CHECK_DOUBLE_EQ(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003934 }
3935 }
3936}
3937
3938
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003939TEST(RunFloat32MulP) {
3940 RawMachineAssemblerTester<int32_t> m;
3941 Float32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003942
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003943 bt.AddReturn(m.Float32Mul(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003945 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01003946 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl * *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003947 }
3948}
3949
3950
3951TEST(RunFloat64MulP) {
3952 RawMachineAssemblerTester<int32_t> m;
3953 Float64BinopTester bt(&m);
3954
3955 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
3956
3957 FOR_FLOAT64_INPUTS(pl) {
3958 FOR_FLOAT64_INPUTS(pr) {
3959 double expected = *pl * *pr;
Ben Murdochda12d292016-06-02 14:46:10 +01003960 CHECK_DOUBLE_EQ(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003961 }
3962 }
3963}
3964
3965
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003966TEST(RunFloat64MulAndFloat64Add1) {
3967 BufferedRawMachineAssemblerTester<double> m(
3968 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3969 m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
3970 m.Parameter(2)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003971
3972 FOR_FLOAT64_INPUTS(i) {
3973 FOR_FLOAT64_INPUTS(j) {
3974 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003975 CHECK_DOUBLE_EQ((*i * *j) + *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003976 }
3977 }
3978 }
3979}
3980
3981
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003982TEST(RunFloat64MulAndFloat64Add2) {
3983 BufferedRawMachineAssemblerTester<double> m(
3984 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
3985 m.Return(m.Float64Add(m.Parameter(0),
3986 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003987
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003988 FOR_FLOAT64_INPUTS(i) {
3989 FOR_FLOAT64_INPUTS(j) {
3990 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01003991 CHECK_DOUBLE_EQ(*i + (*j * *k), m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003992 }
3993 }
3994 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003995}
3996
3997
3998TEST(RunFloat64MulAndFloat64Sub1) {
3999 BufferedRawMachineAssemblerTester<double> m(
4000 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4001 m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
4002 m.Parameter(2)));
4003
4004 FOR_FLOAT64_INPUTS(i) {
4005 FOR_FLOAT64_INPUTS(j) {
4006 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01004007 CHECK_DOUBLE_EQ((*i * *j) - *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004008 }
4009 }
4010 }
4011}
4012
4013
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004014TEST(RunFloat64MulAndFloat64Sub2) {
4015 BufferedRawMachineAssemblerTester<double> m(
4016 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4017 m.Return(m.Float64Sub(m.Parameter(0),
4018 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
4019
4020 FOR_FLOAT64_INPUTS(i) {
4021 FOR_FLOAT64_INPUTS(j) {
4022 FOR_FLOAT64_INPUTS(k) {
Ben Murdochda12d292016-06-02 14:46:10 +01004023 CHECK_DOUBLE_EQ(*i - (*j * *k), m.Call(*i, *j, *k));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004024 }
4025 }
4026 }
4027}
4028
4029
4030TEST(RunFloat64MulImm1) {
4031 FOR_FLOAT64_INPUTS(i) {
4032 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4033 m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
4034
Ben Murdochda12d292016-06-02 14:46:10 +01004035 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i * *j, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004036 }
4037}
4038
4039
4040TEST(RunFloat64MulImm2) {
4041 FOR_FLOAT64_INPUTS(i) {
4042 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4043 m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
4044
Ben Murdochda12d292016-06-02 14:46:10 +01004045 FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j * *i, m.Call(*j)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004046 }
4047}
4048
4049
4050TEST(RunFloat32DivP) {
4051 RawMachineAssemblerTester<int32_t> m;
4052 Float32BinopTester bt(&m);
4053
4054 bt.AddReturn(m.Float32Div(bt.param0, bt.param1));
4055
4056 FOR_FLOAT32_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01004057 FOR_FLOAT32_INPUTS(pr) { CHECK_FLOAT_EQ(*pl / *pr, bt.call(*pl, *pr)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004058 }
4059}
4060
4061
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004062TEST(RunFloat64DivP) {
4063 RawMachineAssemblerTester<int32_t> m;
4064 Float64BinopTester bt(&m);
4065
4066 bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
4067
4068 FOR_FLOAT64_INPUTS(pl) {
Ben Murdochda12d292016-06-02 14:46:10 +01004069 FOR_FLOAT64_INPUTS(pr) { CHECK_DOUBLE_EQ(*pl / *pr, bt.call(*pl, *pr)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004070 }
4071}
4072
4073
4074TEST(RunFloat64ModP) {
4075 RawMachineAssemblerTester<int32_t> m;
4076 Float64BinopTester bt(&m);
4077
4078 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
4079
4080 FOR_FLOAT64_INPUTS(i) {
Ben Murdochda12d292016-06-02 14:46:10 +01004081 FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), bt.call(*i, *j)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004082 }
4083}
4084
4085
4086TEST(RunChangeInt32ToFloat64_A) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004087 int32_t magic = 0x986234;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004088 BufferedRawMachineAssemblerTester<double> m;
4089 m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic)));
Ben Murdochda12d292016-06-02 14:46:10 +01004090 CHECK_DOUBLE_EQ(static_cast<double>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004091}
4092
4093
4094TEST(RunChangeInt32ToFloat64_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004095 BufferedRawMachineAssemblerTester<double> m(MachineType::Int32());
4096 m.Return(m.ChangeInt32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004097
Ben Murdochda12d292016-06-02 14:46:10 +01004098 FOR_INT32_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004099}
4100
4101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004102TEST(RunChangeUint32ToFloat64) {
4103 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32());
4104 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004105
Ben Murdochda12d292016-06-02 14:46:10 +01004106 FOR_UINT32_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004107}
4108
4109
Ben Murdoch097c5b22016-05-18 11:27:45 +01004110TEST(RunTruncateFloat32ToInt32) {
4111 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float32());
4112 m.Return(m.TruncateFloat32ToInt32(m.Parameter(0)));
4113 FOR_FLOAT32_INPUTS(i) {
4114 if (*i <= static_cast<float>(std::numeric_limits<int32_t>::max()) &&
4115 *i >= static_cast<float>(std::numeric_limits<int32_t>::min())) {
Ben Murdochda12d292016-06-02 14:46:10 +01004116 CHECK_FLOAT_EQ(static_cast<int32_t>(*i), m.Call(*i));
Ben Murdoch097c5b22016-05-18 11:27:45 +01004117 }
4118 }
4119}
4120
4121
4122TEST(RunTruncateFloat32ToUint32) {
4123 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float32());
4124 m.Return(m.TruncateFloat32ToUint32(m.Parameter(0)));
4125 {
4126 FOR_UINT32_INPUTS(i) {
4127 float input = static_cast<float>(*i);
4128 // This condition on 'input' is required because
4129 // static_cast<float>(std::numeric_limits<uint32_t>::max()) results in a
4130 // value outside uint32 range.
4131 if (input < static_cast<float>(std::numeric_limits<uint32_t>::max())) {
4132 CHECK_EQ(static_cast<uint32_t>(input), m.Call(input));
4133 }
4134 }
4135 }
4136 {
4137 FOR_FLOAT32_INPUTS(i) {
4138 if (*i <= static_cast<float>(std::numeric_limits<uint32_t>::max()) &&
4139 *i >= static_cast<float>(std::numeric_limits<uint32_t>::min())) {
Ben Murdochda12d292016-06-02 14:46:10 +01004140 CHECK_FLOAT_EQ(static_cast<uint32_t>(*i), m.Call(*i));
Ben Murdoch097c5b22016-05-18 11:27:45 +01004141 }
4142 }
4143 }
4144}
4145
4146
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004147TEST(RunChangeFloat64ToInt32_A) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004148 BufferedRawMachineAssemblerTester<int32_t> m;
4149 double magic = 11.1;
4150 m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic)));
4151 CHECK_EQ(static_cast<int32_t>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004152}
4153
4154
4155TEST(RunChangeFloat64ToInt32_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004156 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64());
4157 m.Return(m.ChangeFloat64ToInt32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004158
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004159 // Note we don't check fractional inputs, or inputs outside the range of
4160 // int32, because these Convert operators really should be Change operators.
4161 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
4162
4163 for (int32_t n = 1; n < 31; ++n) {
4164 CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n)));
4165 }
4166
4167 for (int32_t n = 1; n < 31; ++n) {
4168 CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n)));
4169 }
4170}
4171
4172
4173TEST(RunChangeFloat64ToUint32) {
4174 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
4175 m.Return(m.ChangeFloat64ToUint32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004176
4177 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004178 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004179 }
4180
4181 // Check various powers of 2.
4182 for (int32_t n = 1; n < 31; ++n) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004183 { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004184
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004185 { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004186 }
4187 // Note we don't check fractional inputs, because these Convert operators
4188 // really should be Change operators.
4189}
4190
4191
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004192TEST(RunTruncateFloat64ToFloat32) {
4193 BufferedRawMachineAssemblerTester<float> m(MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004194
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004195 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004196
Ben Murdochda12d292016-06-02 14:46:10 +01004197 FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(DoubleToFloat32(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004198}
4199
Ben Murdochda12d292016-06-02 14:46:10 +01004200uint64_t ToInt64(uint32_t low, uint32_t high) {
4201 return (static_cast<uint64_t>(high) << 32) | static_cast<uint64_t>(low);
4202}
4203
4204#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_X87
4205TEST(RunInt32PairAdd) {
4206 BufferedRawMachineAssemblerTester<int32_t> m(
4207 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4208 MachineType::Uint32());
4209
4210 uint32_t high;
4211 uint32_t low;
4212
4213 Node* PairAdd = m.Int32PairAdd(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4214 m.Parameter(3));
4215
4216 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4217 m.Projection(0, PairAdd));
4218 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4219 m.Projection(1, PairAdd));
4220 m.Return(m.Int32Constant(74));
4221
4222 FOR_UINT64_INPUTS(i) {
4223 FOR_UINT64_INPUTS(j) {
4224 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4225 static_cast<uint32_t>(*i >> 32),
4226 static_cast<uint32_t>(*j & 0xffffffff),
4227 static_cast<uint32_t>(*j >> 32));
4228 CHECK_EQ(*i + *j, ToInt64(low, high));
4229 }
4230 }
4231}
4232
4233void TestInt32PairAddWithSharedInput(int a, int b, int c, int d) {
4234 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4235 MachineType::Uint32());
4236
4237 uint32_t high;
4238 uint32_t low;
4239
4240 Node* PairAdd = m.Int32PairAdd(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4241 m.Parameter(d));
4242
4243 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4244 m.Projection(0, PairAdd));
4245 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4246 m.Projection(1, PairAdd));
4247 m.Return(m.Int32Constant(74));
4248
4249 FOR_UINT32_INPUTS(i) {
4250 FOR_UINT32_INPUTS(j) {
4251 m.Call(*i, *j);
4252 uint32_t inputs[] = {*i, *j};
4253 CHECK_EQ(ToInt64(inputs[a], inputs[b]) + ToInt64(inputs[c], inputs[d]),
4254 ToInt64(low, high));
4255 }
4256 }
4257}
4258
4259TEST(RunInt32PairAddWithSharedInput) {
4260 TestInt32PairAddWithSharedInput(0, 0, 0, 0);
4261 TestInt32PairAddWithSharedInput(1, 0, 0, 0);
4262 TestInt32PairAddWithSharedInput(0, 1, 0, 0);
4263 TestInt32PairAddWithSharedInput(0, 0, 1, 0);
4264 TestInt32PairAddWithSharedInput(0, 0, 0, 1);
4265 TestInt32PairAddWithSharedInput(1, 1, 0, 0);
4266}
4267
4268TEST(RunInt32PairSub) {
4269 BufferedRawMachineAssemblerTester<int32_t> m(
4270 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4271 MachineType::Uint32());
4272
4273 uint32_t high;
4274 uint32_t low;
4275
4276 Node* PairSub = m.Int32PairSub(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4277 m.Parameter(3));
4278
4279 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4280 m.Projection(0, PairSub));
4281 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4282 m.Projection(1, PairSub));
4283 m.Return(m.Int32Constant(74));
4284
4285 FOR_UINT64_INPUTS(i) {
4286 FOR_UINT64_INPUTS(j) {
4287 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4288 static_cast<uint32_t>(*i >> 32),
4289 static_cast<uint32_t>(*j & 0xffffffff),
4290 static_cast<uint32_t>(*j >> 32));
4291 CHECK_EQ(*i - *j, ToInt64(low, high));
4292 }
4293 }
4294}
4295
4296void TestInt32PairSubWithSharedInput(int a, int b, int c, int d) {
4297 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4298 MachineType::Uint32());
4299
4300 uint32_t high;
4301 uint32_t low;
4302
4303 Node* PairSub = m.Int32PairSub(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4304 m.Parameter(d));
4305
4306 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4307 m.Projection(0, PairSub));
4308 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4309 m.Projection(1, PairSub));
4310 m.Return(m.Int32Constant(74));
4311
4312 FOR_UINT32_INPUTS(i) {
4313 FOR_UINT32_INPUTS(j) {
4314 m.Call(*i, *j);
4315 uint32_t inputs[] = {*i, *j};
4316 CHECK_EQ(ToInt64(inputs[a], inputs[b]) - ToInt64(inputs[c], inputs[d]),
4317 ToInt64(low, high));
4318 }
4319 }
4320}
4321
4322TEST(RunInt32PairSubWithSharedInput) {
4323 TestInt32PairSubWithSharedInput(0, 0, 0, 0);
4324 TestInt32PairSubWithSharedInput(1, 0, 0, 0);
4325 TestInt32PairSubWithSharedInput(0, 1, 0, 0);
4326 TestInt32PairSubWithSharedInput(0, 0, 1, 0);
4327 TestInt32PairSubWithSharedInput(0, 0, 0, 1);
4328 TestInt32PairSubWithSharedInput(1, 1, 0, 0);
4329}
4330
4331TEST(RunInt32PairMul) {
4332 BufferedRawMachineAssemblerTester<int32_t> m(
4333 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32(),
4334 MachineType::Uint32());
4335
4336 uint32_t high;
4337 uint32_t low;
4338
4339 Node* PairMul = m.Int32PairMul(m.Parameter(0), m.Parameter(1), m.Parameter(2),
4340 m.Parameter(3));
4341
4342 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4343 m.Projection(0, PairMul));
4344 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4345 m.Projection(1, PairMul));
4346 m.Return(m.Int32Constant(74));
4347
4348 FOR_UINT64_INPUTS(i) {
4349 FOR_UINT64_INPUTS(j) {
4350 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4351 static_cast<uint32_t>(*i >> 32),
4352 static_cast<uint32_t>(*j & 0xffffffff),
4353 static_cast<uint32_t>(*j >> 32));
4354 CHECK_EQ(*i * *j, ToInt64(low, high));
4355 }
4356 }
4357}
4358
4359void TestInt32PairMulWithSharedInput(int a, int b, int c, int d) {
4360 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4361 MachineType::Uint32());
4362
4363 uint32_t high;
4364 uint32_t low;
4365
4366 Node* PairMul = m.Int32PairMul(m.Parameter(a), m.Parameter(b), m.Parameter(c),
4367 m.Parameter(d));
4368
4369 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4370 m.Projection(0, PairMul));
4371 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4372 m.Projection(1, PairMul));
4373 m.Return(m.Int32Constant(74));
4374
4375 FOR_UINT32_INPUTS(i) {
4376 FOR_UINT32_INPUTS(j) {
4377 m.Call(*i, *j);
4378 uint32_t inputs[] = {*i, *j};
4379 CHECK_EQ(ToInt64(inputs[a], inputs[b]) * ToInt64(inputs[c], inputs[d]),
4380 ToInt64(low, high));
4381 }
4382 }
4383}
4384
4385TEST(RunInt32PairMulWithSharedInput) {
4386 TestInt32PairMulWithSharedInput(0, 0, 0, 0);
4387 TestInt32PairMulWithSharedInput(1, 0, 0, 0);
4388 TestInt32PairMulWithSharedInput(0, 1, 0, 0);
4389 TestInt32PairMulWithSharedInput(0, 0, 1, 0);
4390 TestInt32PairMulWithSharedInput(0, 0, 0, 1);
4391 TestInt32PairMulWithSharedInput(1, 1, 0, 0);
4392 TestInt32PairMulWithSharedInput(0, 1, 1, 0);
4393}
4394
4395TEST(RunWord32PairShl) {
4396 BufferedRawMachineAssemblerTester<int32_t> m(
4397 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32());
4398
4399 uint32_t high;
4400 uint32_t low;
4401
4402 Node* PairAdd =
4403 m.Word32PairShl(m.Parameter(0), m.Parameter(1), m.Parameter(2));
4404
4405 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4406 m.Projection(0, PairAdd));
4407 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4408 m.Projection(1, PairAdd));
4409 m.Return(m.Int32Constant(74));
4410
4411 FOR_UINT64_INPUTS(i) {
4412 for (uint32_t j = 0; j < 64; j++) {
4413 m.Call(static_cast<uint32_t>(*i & 0xffffffff),
4414 static_cast<uint32_t>(*i >> 32), j);
4415 CHECK_EQ(*i << j, ToInt64(low, high));
4416 }
4417 }
4418}
4419
4420void TestWord32PairShlWithSharedInput(int a, int b) {
4421 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32(),
4422 MachineType::Uint32());
4423
4424 uint32_t high;
4425 uint32_t low;
4426
4427 Node* PairAdd =
4428 m.Word32PairShl(m.Parameter(a), m.Parameter(b), m.Parameter(1));
4429
4430 m.StoreToPointer(&low, MachineRepresentation::kWord32,
4431 m.Projection(0, PairAdd));
4432 m.StoreToPointer(&high, MachineRepresentation::kWord32,
4433 m.Projection(1, PairAdd));
4434 m.Return(m.Int32Constant(74));
4435
4436 FOR_UINT32_INPUTS(i) {
4437 for (uint32_t j = 0; j < 64; j++) {
4438 m.Call(*i, j);
4439 uint32_t inputs[] = {*i, j};
4440 CHECK_EQ(ToInt64(inputs[a], inputs[b]) << j, ToInt64(low, high));
4441 }
4442 }
4443}
4444
4445TEST(RunWord32PairShlWithSharedInput) {
4446 TestWord32PairShlWithSharedInput(0, 0);
4447 TestWord32PairShlWithSharedInput(0, 1);
4448 TestWord32PairShlWithSharedInput(1, 0);
4449 TestWord32PairShlWithSharedInput(1, 1);
4450}
4451
4452#endif
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004453
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004454TEST(RunDeadChangeFloat64ToInt32) {
4455 RawMachineAssemblerTester<int32_t> m;
4456 const int magic = 0x88abcda4;
4457 m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
4458 m.Return(m.Int32Constant(magic));
4459 CHECK_EQ(magic, m.Call());
4460}
4461
4462
4463TEST(RunDeadChangeInt32ToFloat64) {
4464 RawMachineAssemblerTester<int32_t> m;
4465 const int magic = 0x8834abcd;
4466 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
4467 m.Return(m.Int32Constant(magic));
4468 CHECK_EQ(magic, m.Call());
4469}
4470
4471
4472TEST(RunLoopPhiInduction2) {
4473 RawMachineAssemblerTester<int32_t> m;
4474
4475 int false_val = 0x10777;
4476
4477 // x = false_val; while(false) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004478 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004479 Node* false_node = m.Int32Constant(false_val);
4480 m.Goto(&header);
4481 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004482 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004483 m.Branch(m.Int32Constant(0), &body, &end);
4484 m.Bind(&body);
4485 Node* add = m.Int32Add(phi, m.Int32Constant(1));
4486 phi->ReplaceInput(1, add);
4487 m.Goto(&header);
4488 m.Bind(&end);
4489 m.Return(phi);
4490
4491 CHECK_EQ(false_val, m.Call());
4492}
4493
4494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004495TEST(RunFloatDiamond) {
4496 RawMachineAssemblerTester<int32_t> m;
4497
4498 const int magic = 99645;
4499 float buffer = 0.1f;
4500 float constant = 99.99f;
4501
4502 RawMachineLabel blocka, blockb, end;
4503 Node* k1 = m.Float32Constant(constant);
4504 Node* k2 = m.Float32Constant(0 - constant);
4505 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4506 m.Bind(&blocka);
4507 m.Goto(&end);
4508 m.Bind(&blockb);
4509 m.Goto(&end);
4510 m.Bind(&end);
4511 Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1);
4512 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer),
4513 m.IntPtrConstant(0), phi, kNoWriteBarrier);
4514 m.Return(m.Int32Constant(magic));
4515
4516 CHECK_EQ(magic, m.Call());
4517 CHECK(constant == buffer);
4518}
4519
4520
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004521TEST(RunDoubleDiamond) {
4522 RawMachineAssemblerTester<int32_t> m;
4523
4524 const int magic = 99645;
4525 double buffer = 0.1;
4526 double constant = 99.99;
4527
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004528 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004529 Node* k1 = m.Float64Constant(constant);
4530 Node* k2 = m.Float64Constant(0 - constant);
4531 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4532 m.Bind(&blocka);
4533 m.Goto(&end);
4534 m.Bind(&blockb);
4535 m.Goto(&end);
4536 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004537 Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1);
4538 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4539 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004540 m.Return(m.Int32Constant(magic));
4541
4542 CHECK_EQ(magic, m.Call());
4543 CHECK_EQ(constant, buffer);
4544}
4545
4546
4547TEST(RunRefDiamond) {
4548 RawMachineAssemblerTester<int32_t> m;
4549
4550 const int magic = 99644;
4551 Handle<String> rexpected =
4552 CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
4553 String* buffer;
4554
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004555 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004556 Node* k1 = m.StringConstant("A");
4557 Node* k2 = m.StringConstant("B");
4558 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4559 m.Bind(&blocka);
4560 m.Goto(&end);
4561 m.Bind(&blockb);
4562 m.Goto(&end);
4563 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004564 Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1);
4565 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer),
4566 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004567 m.Return(m.Int32Constant(magic));
4568
4569 CHECK_EQ(magic, m.Call());
4570 CHECK(rexpected->SameValue(buffer));
4571}
4572
4573
4574TEST(RunDoubleRefDiamond) {
4575 RawMachineAssemblerTester<int32_t> m;
4576
4577 const int magic = 99648;
4578 double dbuffer = 0.1;
4579 double dconstant = 99.99;
4580 Handle<String> rexpected =
4581 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
4582 String* rbuffer;
4583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004584 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004585 Node* d1 = m.Float64Constant(dconstant);
4586 Node* d2 = m.Float64Constant(0 - dconstant);
4587 Node* r1 = m.StringConstant("AX");
4588 Node* r2 = m.StringConstant("BX");
4589 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4590 m.Bind(&blocka);
4591 m.Goto(&end);
4592 m.Bind(&blockb);
4593 m.Goto(&end);
4594 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004595 Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4596 Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1);
4597 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4598 m.Int32Constant(0), dphi, kNoWriteBarrier);
4599 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4600 m.Int32Constant(0), rphi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004601 m.Return(m.Int32Constant(magic));
4602
4603 CHECK_EQ(magic, m.Call());
4604 CHECK_EQ(dconstant, dbuffer);
4605 CHECK(rexpected->SameValue(rbuffer));
4606}
4607
4608
4609TEST(RunDoubleRefDoubleDiamond) {
4610 RawMachineAssemblerTester<int32_t> m;
4611
4612 const int magic = 99649;
4613 double dbuffer = 0.1;
4614 double dconstant = 99.997;
4615 Handle<String> rexpected =
4616 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
4617 String* rbuffer;
4618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004619 RawMachineLabel blocka, blockb, mid, blockd, blocke, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004620 Node* d1 = m.Float64Constant(dconstant);
4621 Node* d2 = m.Float64Constant(0 - dconstant);
4622 Node* r1 = m.StringConstant("AD");
4623 Node* r2 = m.StringConstant("BD");
4624 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4625 m.Bind(&blocka);
4626 m.Goto(&mid);
4627 m.Bind(&blockb);
4628 m.Goto(&mid);
4629 m.Bind(&mid);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004630 Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4631 Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004632 m.Branch(m.Int32Constant(0), &blockd, &blocke);
4633
4634 m.Bind(&blockd);
4635 m.Goto(&end);
4636 m.Bind(&blocke);
4637 m.Goto(&end);
4638 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004639 Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1);
4640 Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004641
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004642 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4643 m.Int32Constant(0), dphi2, kNoWriteBarrier);
4644 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4645 m.Int32Constant(0), rphi2, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004646 m.Return(m.Int32Constant(magic));
4647
4648 CHECK_EQ(magic, m.Call());
4649 CHECK_EQ(dconstant, dbuffer);
4650 CHECK(rexpected->SameValue(rbuffer));
4651}
4652
4653
4654TEST(RunDoubleLoopPhi) {
4655 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004656 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004657
4658 int magic = 99773;
4659 double buffer = 0.99;
4660 double dconstant = 777.1;
4661
4662 Node* zero = m.Int32Constant(0);
4663 Node* dk = m.Float64Constant(dconstant);
4664
4665 m.Goto(&header);
4666 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004667 Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004668 phi->ReplaceInput(1, phi);
4669 m.Branch(zero, &body, &end);
4670 m.Bind(&body);
4671 m.Goto(&header);
4672 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004673 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4674 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004675 m.Return(m.Int32Constant(magic));
4676
4677 CHECK_EQ(magic, m.Call());
4678}
4679
4680
4681TEST(RunCountToTenAccRaw) {
4682 RawMachineAssemblerTester<int32_t> m;
4683
4684 Node* zero = m.Int32Constant(0);
4685 Node* ten = m.Int32Constant(10);
4686 Node* one = m.Int32Constant(1);
4687
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004688 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004689
4690 m.Goto(&header);
4691
4692 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004693 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4694 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004695 m.Goto(&body);
4696
4697 m.Bind(&body);
4698 Node* next_i = m.Int32Add(i, one);
4699 Node* next_j = m.Int32Add(j, one);
4700 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4701
4702 m.Bind(&body_cont);
4703 i->ReplaceInput(1, next_i);
4704 j->ReplaceInput(1, next_j);
4705 m.Goto(&header);
4706
4707 m.Bind(&end);
4708 m.Return(ten);
4709
4710 CHECK_EQ(10, m.Call());
4711}
4712
4713
4714TEST(RunCountToTenAccRaw2) {
4715 RawMachineAssemblerTester<int32_t> m;
4716
4717 Node* zero = m.Int32Constant(0);
4718 Node* ten = m.Int32Constant(10);
4719 Node* one = m.Int32Constant(1);
4720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004721 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004722
4723 m.Goto(&header);
4724
4725 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004726 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4727 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
4728 Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004729 m.Goto(&body);
4730
4731 m.Bind(&body);
4732 Node* next_i = m.Int32Add(i, one);
4733 Node* next_j = m.Int32Add(j, one);
4734 Node* next_k = m.Int32Add(j, one);
4735 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4736
4737 m.Bind(&body_cont);
4738 i->ReplaceInput(1, next_i);
4739 j->ReplaceInput(1, next_j);
4740 k->ReplaceInput(1, next_k);
4741 m.Goto(&header);
4742
4743 m.Bind(&end);
4744 m.Return(ten);
4745
4746 CHECK_EQ(10, m.Call());
4747}
4748
4749
4750TEST(RunAddTree) {
4751 RawMachineAssemblerTester<int32_t> m;
4752 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
4753
4754 Node* base = m.PointerConstant(inputs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004755 Node* n0 =
4756 m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t)));
4757 Node* n1 =
4758 m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t)));
4759 Node* n2 =
4760 m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t)));
4761 Node* n3 =
4762 m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t)));
4763 Node* n4 =
4764 m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t)));
4765 Node* n5 =
4766 m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t)));
4767 Node* n6 =
4768 m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t)));
4769 Node* n7 =
4770 m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004771
4772 Node* i1 = m.Int32Add(n0, n1);
4773 Node* i2 = m.Int32Add(n2, n3);
4774 Node* i3 = m.Int32Add(n4, n5);
4775 Node* i4 = m.Int32Add(n6, n7);
4776
4777 Node* i5 = m.Int32Add(i1, i2);
4778 Node* i6 = m.Int32Add(i3, i4);
4779
4780 Node* i7 = m.Int32Add(i5, i6);
4781
4782 m.Return(i7);
4783
4784 CHECK_EQ(116, m.Call());
4785}
4786
4787
4788static const int kFloat64CompareHelperTestCases = 15;
4789static const int kFloat64CompareHelperNodeType = 4;
4790
4791static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
4792 int test_case, int node_type, double x,
4793 double y) {
4794 static double buffer[2];
4795 buffer[0] = x;
4796 buffer[1] = y;
4797 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
4798 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
4799 CHECK(x < y);
4800 bool load_a = node_type / 2 == 1;
4801 bool load_b = node_type % 2 == 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004802 Node* a =
4803 load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0]))
4804 : m->Float64Constant(x);
4805 Node* b =
4806 load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1]))
4807 : m->Float64Constant(y);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004808 Node* cmp = NULL;
4809 bool expected = false;
4810 switch (test_case) {
4811 // Equal tests.
4812 case 0:
4813 cmp = m->Float64Equal(a, b);
4814 expected = false;
4815 break;
4816 case 1:
4817 cmp = m->Float64Equal(a, a);
4818 expected = true;
4819 break;
4820 // LessThan tests.
4821 case 2:
4822 cmp = m->Float64LessThan(a, b);
4823 expected = true;
4824 break;
4825 case 3:
4826 cmp = m->Float64LessThan(b, a);
4827 expected = false;
4828 break;
4829 case 4:
4830 cmp = m->Float64LessThan(a, a);
4831 expected = false;
4832 break;
4833 // LessThanOrEqual tests.
4834 case 5:
4835 cmp = m->Float64LessThanOrEqual(a, b);
4836 expected = true;
4837 break;
4838 case 6:
4839 cmp = m->Float64LessThanOrEqual(b, a);
4840 expected = false;
4841 break;
4842 case 7:
4843 cmp = m->Float64LessThanOrEqual(a, a);
4844 expected = true;
4845 break;
4846 // NotEqual tests.
4847 case 8:
4848 cmp = m->Float64NotEqual(a, b);
4849 expected = true;
4850 break;
4851 case 9:
4852 cmp = m->Float64NotEqual(b, a);
4853 expected = true;
4854 break;
4855 case 10:
4856 cmp = m->Float64NotEqual(a, a);
4857 expected = false;
4858 break;
4859 // GreaterThan tests.
4860 case 11:
4861 cmp = m->Float64GreaterThan(a, a);
4862 expected = false;
4863 break;
4864 case 12:
4865 cmp = m->Float64GreaterThan(a, b);
4866 expected = false;
4867 break;
4868 // GreaterThanOrEqual tests.
4869 case 13:
4870 cmp = m->Float64GreaterThanOrEqual(a, a);
4871 expected = true;
4872 break;
4873 case 14:
4874 cmp = m->Float64GreaterThanOrEqual(b, a);
4875 expected = true;
4876 break;
4877 default:
4878 UNREACHABLE();
4879 }
4880 m->Return(cmp);
4881 return expected;
4882}
4883
4884
4885TEST(RunFloat64Compare) {
4886 double inf = V8_INFINITY;
4887 // All pairs (a1, a2) are of the form a1 < a2.
4888 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22,
4889 -inf, 0.22, 0.22, inf, -inf, inf};
4890
4891 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
4892 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
4893 node_type++) {
4894 for (size_t input = 0; input < arraysize(inputs); input += 2) {
4895 RawMachineAssemblerTester<int32_t> m;
4896 int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
4897 inputs[input + 1]);
4898 CHECK_EQ(expected, m.Call());
4899 }
4900 }
4901 }
4902}
4903
4904
4905TEST(RunFloat64UnorderedCompare) {
4906 RawMachineAssemblerTester<int32_t> m;
4907
4908 const Operator* operators[] = {m.machine()->Float64Equal(),
4909 m.machine()->Float64LessThan(),
4910 m.machine()->Float64LessThanOrEqual()};
4911
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004912 double nan = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004913
4914 FOR_FLOAT64_INPUTS(i) {
4915 for (size_t o = 0; o < arraysize(operators); ++o) {
4916 for (int j = 0; j < 2; j++) {
4917 RawMachineAssemblerTester<int32_t> m;
4918 Node* a = m.Float64Constant(*i);
4919 Node* b = m.Float64Constant(nan);
4920 if (j == 1) std::swap(a, b);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004921 m.Return(m.AddNode(operators[o], a, b));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004922 CHECK_EQ(0, m.Call());
4923 }
4924 }
4925 }
4926}
4927
4928
4929TEST(RunFloat64Equal) {
4930 double input_a = 0.0;
4931 double input_b = 0.0;
4932
4933 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004934 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4935 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004936 m.Return(m.Float64Equal(a, b));
4937
4938 CompareWrapper cmp(IrOpcode::kFloat64Equal);
4939 FOR_FLOAT64_INPUTS(pl) {
4940 FOR_FLOAT64_INPUTS(pr) {
4941 input_a = *pl;
4942 input_b = *pr;
4943 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4944 CHECK_EQ(expected, m.Call());
4945 }
4946 }
4947}
4948
4949
4950TEST(RunFloat64LessThan) {
4951 double input_a = 0.0;
4952 double input_b = 0.0;
4953
4954 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004955 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4956 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004957 m.Return(m.Float64LessThan(a, b));
4958
4959 CompareWrapper cmp(IrOpcode::kFloat64LessThan);
4960 FOR_FLOAT64_INPUTS(pl) {
4961 FOR_FLOAT64_INPUTS(pr) {
4962 input_a = *pl;
4963 input_b = *pr;
4964 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4965 CHECK_EQ(expected, m.Call());
4966 }
4967 }
4968}
4969
4970
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004971template <typename IntType>
4972static void LoadStoreTruncation(MachineType kRepresentation) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004973 IntType input;
4974
4975 RawMachineAssemblerTester<int32_t> m;
4976 Node* a = m.LoadFromPointer(&input, kRepresentation);
4977 Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004978 m.StoreToPointer(&input, kRepresentation.representation(), ap1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004979 m.Return(ap1);
4980
4981 const IntType max = std::numeric_limits<IntType>::max();
4982 const IntType min = std::numeric_limits<IntType>::min();
4983
4984 // Test upper bound.
4985 input = max;
4986 CHECK_EQ(max + 1, m.Call());
4987 CHECK_EQ(min, input);
4988
4989 // Test lower bound.
4990 input = min;
4991 CHECK_EQ(static_cast<IntType>(max + 2), m.Call());
4992 CHECK_EQ(min + 1, input);
4993
4994 // Test all one byte values that are not one byte bounds.
4995 for (int i = -127; i < 127; i++) {
4996 input = i;
4997 int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
4998 CHECK_EQ(static_cast<IntType>(expected), m.Call());
4999 CHECK_EQ(static_cast<IntType>(i + 1), input);
5000 }
5001}
5002
5003
5004TEST(RunLoadStoreTruncation) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005005 LoadStoreTruncation<int8_t>(MachineType::Int8());
5006 LoadStoreTruncation<int16_t>(MachineType::Int16());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005007}
5008
5009
5010static void IntPtrCompare(intptr_t left, intptr_t right) {
5011 for (int test = 0; test < 7; test++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005012 RawMachineAssemblerTester<bool> m(MachineType::Pointer(),
5013 MachineType::Pointer());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005014 Node* p0 = m.Parameter(0);
5015 Node* p1 = m.Parameter(1);
5016 Node* res = NULL;
5017 bool expected = false;
5018 switch (test) {
5019 case 0:
5020 res = m.IntPtrLessThan(p0, p1);
5021 expected = true;
5022 break;
5023 case 1:
5024 res = m.IntPtrLessThanOrEqual(p0, p1);
5025 expected = true;
5026 break;
5027 case 2:
5028 res = m.IntPtrEqual(p0, p1);
5029 expected = false;
5030 break;
5031 case 3:
5032 res = m.IntPtrGreaterThanOrEqual(p0, p1);
5033 expected = false;
5034 break;
5035 case 4:
5036 res = m.IntPtrGreaterThan(p0, p1);
5037 expected = false;
5038 break;
5039 case 5:
5040 res = m.IntPtrEqual(p0, p0);
5041 expected = true;
5042 break;
5043 case 6:
5044 res = m.IntPtrNotEqual(p0, p1);
5045 expected = true;
5046 break;
5047 default:
5048 UNREACHABLE();
5049 break;
5050 }
5051 m.Return(res);
5052 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
5053 reinterpret_cast<int32_t*>(right)));
5054 }
5055}
5056
5057
5058TEST(RunIntPtrCompare) {
5059 intptr_t min = std::numeric_limits<intptr_t>::min();
5060 intptr_t max = std::numeric_limits<intptr_t>::max();
5061 // An ascending chain of intptr_t
5062 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
5063 for (size_t i = 0; i < arraysize(inputs) - 1; i++) {
5064 IntPtrCompare(inputs[i], inputs[i + 1]);
5065 }
5066}
5067
5068
5069TEST(RunTestIntPtrArithmetic) {
5070 static const int kInputSize = 10;
5071 int32_t inputs[kInputSize];
5072 int32_t outputs[kInputSize];
5073 for (int i = 0; i < kInputSize; i++) {
5074 inputs[i] = i;
5075 outputs[i] = -1;
5076 }
5077 RawMachineAssemblerTester<int32_t*> m;
5078 Node* input = m.PointerConstant(&inputs[0]);
5079 Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005080 Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005081 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005082 m.Store(MachineRepresentation::kWord32, output,
5083 m.Load(MachineType::Int32(), input), kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005084 input = m.IntPtrAdd(input, elem_size);
5085 output = m.IntPtrSub(output, elem_size);
5086 }
5087 m.Return(input);
5088 CHECK_EQ(&inputs[kInputSize], m.Call());
5089 for (int i = 0; i < kInputSize; i++) {
5090 CHECK_EQ(i, inputs[i]);
5091 CHECK_EQ(kInputSize - i - 1, outputs[i]);
5092 }
5093}
5094
5095
5096TEST(RunSpillLotsOfThings) {
5097 static const int kInputSize = 1000;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005098 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005099 Node* accs[kInputSize];
5100 int32_t outputs[kInputSize];
5101 Node* one = m.Int32Constant(1);
5102 Node* acc = one;
5103 for (int i = 0; i < kInputSize; i++) {
5104 acc = m.Int32Add(acc, one);
5105 accs[i] = acc;
5106 }
5107 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005108 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005109 }
5110 m.Return(one);
5111 m.Call();
5112 for (int i = 0; i < kInputSize; i++) {
5113 CHECK_EQ(outputs[i], i + 2);
5114 }
5115}
5116
5117
5118TEST(RunSpillConstantsAndParameters) {
5119 static const int kInputSize = 1000;
5120 static const int32_t kBase = 987;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005121 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5122 MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005123 int32_t outputs[kInputSize];
5124 Node* csts[kInputSize];
5125 Node* accs[kInputSize];
5126 Node* acc = m.Int32Constant(0);
5127 for (int i = 0; i < kInputSize; i++) {
5128 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
5129 }
5130 for (int i = 0; i < kInputSize; i++) {
5131 acc = m.Int32Add(acc, csts[i]);
5132 accs[i] = acc;
5133 }
5134 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005135 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005136 }
5137 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
5138 FOR_INT32_INPUTS(i) {
5139 FOR_INT32_INPUTS(j) {
5140 int32_t expected = *i + *j;
5141 for (int k = 0; k < kInputSize; k++) {
5142 expected += kBase + k;
5143 }
5144 CHECK_EQ(expected, m.Call(*i, *j));
5145 expected = 0;
5146 for (int k = 0; k < kInputSize; k++) {
5147 expected += kBase + k;
5148 CHECK_EQ(expected, outputs[k]);
5149 }
5150 }
5151 }
5152}
5153
5154
5155TEST(RunNewSpaceConstantsInPhi) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005156 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005157
5158 Isolate* isolate = CcTest::i_isolate();
5159 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
5160 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
5161 Node* true_node = m.HeapConstant(true_val);
5162 Node* false_node = m.HeapConstant(false_val);
5163
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005164 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005165 m.Branch(m.Parameter(0), &blocka, &blockb);
5166 m.Bind(&blocka);
5167 m.Goto(&end);
5168 m.Bind(&blockb);
5169 m.Goto(&end);
5170
5171 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005172 Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005173 m.Return(phi);
5174
5175 CHECK_EQ(*false_val, m.Call(0));
5176 CHECK_EQ(*true_val, m.Call(1));
5177}
5178
5179
5180TEST(RunInt32AddWithOverflowP) {
5181 int32_t actual_val = -1;
5182 RawMachineAssemblerTester<int32_t> m;
5183 Int32BinopTester bt(&m);
5184 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
5185 Node* val = m.Projection(0, add);
5186 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005187 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005188 bt.AddReturn(ovf);
5189 FOR_INT32_INPUTS(i) {
5190 FOR_INT32_INPUTS(j) {
5191 int32_t expected_val;
5192 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5193 CHECK_EQ(expected_ovf, bt.call(*i, *j));
5194 CHECK_EQ(expected_val, actual_val);
5195 }
5196 }
5197}
5198
5199
5200TEST(RunInt32AddWithOverflowImm) {
5201 int32_t actual_val = -1, expected_val = 0;
5202 FOR_INT32_INPUTS(i) {
5203 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005204 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005205 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5206 Node* val = m.Projection(0, add);
5207 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005208 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005209 m.Return(ovf);
5210 FOR_INT32_INPUTS(j) {
5211 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5212 CHECK_EQ(expected_ovf, m.Call(*j));
5213 CHECK_EQ(expected_val, actual_val);
5214 }
5215 }
5216 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005217 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005218 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5219 Node* val = m.Projection(0, add);
5220 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005221 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005222 m.Return(ovf);
5223 FOR_INT32_INPUTS(j) {
5224 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5225 CHECK_EQ(expected_ovf, m.Call(*j));
5226 CHECK_EQ(expected_val, actual_val);
5227 }
5228 }
5229 FOR_INT32_INPUTS(j) {
5230 RawMachineAssemblerTester<int32_t> m;
5231 Node* add =
5232 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5233 Node* val = m.Projection(0, add);
5234 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005235 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005236 m.Return(ovf);
5237 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5238 CHECK_EQ(expected_ovf, m.Call());
5239 CHECK_EQ(expected_val, actual_val);
5240 }
5241 }
5242}
5243
5244
5245TEST(RunInt32AddWithOverflowInBranchP) {
5246 int constant = 911777;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005247 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005248 RawMachineAssemblerTester<int32_t> m;
5249 Int32BinopTester bt(&m);
5250 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
5251 Node* ovf = m.Projection(1, add);
5252 m.Branch(ovf, &blocka, &blockb);
5253 m.Bind(&blocka);
5254 bt.AddReturn(m.Int32Constant(constant));
5255 m.Bind(&blockb);
5256 Node* val = m.Projection(0, add);
5257 bt.AddReturn(val);
5258 FOR_INT32_INPUTS(i) {
5259 FOR_INT32_INPUTS(j) {
5260 int32_t expected;
5261 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant;
5262 CHECK_EQ(expected, bt.call(*i, *j));
5263 }
5264 }
5265}
5266
5267
5268TEST(RunInt32SubWithOverflowP) {
5269 int32_t actual_val = -1;
5270 RawMachineAssemblerTester<int32_t> m;
5271 Int32BinopTester bt(&m);
5272 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
5273 Node* val = m.Projection(0, add);
5274 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005275 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005276 bt.AddReturn(ovf);
5277 FOR_INT32_INPUTS(i) {
5278 FOR_INT32_INPUTS(j) {
5279 int32_t expected_val;
5280 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5281 CHECK_EQ(expected_ovf, bt.call(*i, *j));
5282 CHECK_EQ(expected_val, actual_val);
5283 }
5284 }
5285}
5286
5287
5288TEST(RunInt32SubWithOverflowImm) {
5289 int32_t actual_val = -1, expected_val = 0;
5290 FOR_INT32_INPUTS(i) {
5291 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005292 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005293 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5294 Node* val = m.Projection(0, add);
5295 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005296 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005297 m.Return(ovf);
5298 FOR_INT32_INPUTS(j) {
5299 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5300 CHECK_EQ(expected_ovf, m.Call(*j));
5301 CHECK_EQ(expected_val, actual_val);
5302 }
5303 }
5304 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005305 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005306 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5307 Node* val = m.Projection(0, add);
5308 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005309 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005310 m.Return(ovf);
5311 FOR_INT32_INPUTS(j) {
5312 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
5313 CHECK_EQ(expected_ovf, m.Call(*j));
5314 CHECK_EQ(expected_val, actual_val);
5315 }
5316 }
5317 FOR_INT32_INPUTS(j) {
5318 RawMachineAssemblerTester<int32_t> m;
5319 Node* add =
5320 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5321 Node* val = m.Projection(0, add);
5322 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005323 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005324 m.Return(ovf);
5325 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5326 CHECK_EQ(expected_ovf, m.Call());
5327 CHECK_EQ(expected_val, actual_val);
5328 }
5329 }
5330}
5331
5332
5333TEST(RunInt32SubWithOverflowInBranchP) {
5334 int constant = 911999;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005335 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005336 RawMachineAssemblerTester<int32_t> m;
5337 Int32BinopTester bt(&m);
5338 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
5339 Node* ovf = m.Projection(1, sub);
5340 m.Branch(ovf, &blocka, &blockb);
5341 m.Bind(&blocka);
5342 bt.AddReturn(m.Int32Constant(constant));
5343 m.Bind(&blockb);
5344 Node* val = m.Projection(0, sub);
5345 bt.AddReturn(val);
5346 FOR_INT32_INPUTS(i) {
5347 FOR_INT32_INPUTS(j) {
5348 int32_t expected;
5349 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant;
5350 CHECK_EQ(expected, bt.call(*i, *j));
5351 }
5352 }
5353}
5354
5355
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005356TEST(RunWord64EqualInBranchP) {
5357 int64_t input;
5358 RawMachineLabel blocka, blockb;
5359 RawMachineAssemblerTester<int64_t> m;
5360 if (!m.machine()->Is64()) return;
5361 Node* value = m.LoadFromPointer(&input, MachineType::Int64());
5362 m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
5363 m.Bind(&blocka);
5364 m.Return(m.Int32Constant(1));
5365 m.Bind(&blockb);
5366 m.Return(m.Int32Constant(2));
5367 input = V8_INT64_C(0);
5368 CHECK_EQ(1, m.Call());
5369 input = V8_INT64_C(1);
5370 CHECK_EQ(2, m.Call());
5371 input = V8_INT64_C(0x100000000);
5372 CHECK_EQ(2, m.Call());
5373}
5374
5375
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005376TEST(RunChangeInt32ToInt64P) {
5377 if (kPointerSize < 8) return;
5378 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005379 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5380 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
5381 m.ChangeInt32ToInt64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005382 m.Return(m.Int32Constant(0));
5383 FOR_INT32_INPUTS(i) {
5384 int64_t expected = *i;
5385 CHECK_EQ(0, m.Call(*i));
5386 CHECK_EQ(expected, actual);
5387 }
5388}
5389
5390
5391TEST(RunChangeUint32ToUint64P) {
5392 if (kPointerSize < 8) return;
5393 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005394 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
5395 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005396 m.ChangeUint32ToUint64(m.Parameter(0)));
5397 m.Return(m.Int32Constant(0));
5398 FOR_UINT32_INPUTS(i) {
5399 int64_t expected = static_cast<uint64_t>(*i);
5400 CHECK_EQ(0, m.Call(*i));
5401 CHECK_EQ(expected, actual);
5402 }
5403}
5404
5405
5406TEST(RunTruncateInt64ToInt32P) {
5407 if (kPointerSize < 8) return;
5408 int64_t expected = -1;
5409 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005410 m.Return(m.TruncateInt64ToInt32(
5411 m.LoadFromPointer(&expected, MachineType::Int64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005412 FOR_UINT32_INPUTS(i) {
5413 FOR_UINT32_INPUTS(j) {
5414 expected = (static_cast<uint64_t>(*j) << 32) | *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005415 CHECK_EQ(static_cast<int32_t>(expected), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005416 }
5417 }
5418}
5419
5420
5421TEST(RunTruncateFloat64ToInt32P) {
5422 struct {
5423 double from;
5424 double raw;
5425 } kValues[] = {{0, 0},
5426 {0.5, 0},
5427 {-0.5, 0},
5428 {1.5, 1},
5429 {-1.5, -1},
5430 {5.5, 5},
5431 {-5.0, -5},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005432 {std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005433 {std::numeric_limits<double>::infinity(), 0},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005434 {-std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005435 {-std::numeric_limits<double>::infinity(), 0},
5436 {4.94065645841e-324, 0},
5437 {-4.94065645841e-324, 0},
5438 {0.9999999999999999, 0},
5439 {-0.9999999999999999, 0},
5440 {4294967296.0, 0},
5441 {-4294967296.0, 0},
5442 {9223372036854775000.0, 4294966272.0},
5443 {-9223372036854775000.0, -4294966272.0},
5444 {4.5036e+15, 372629504},
5445 {-4.5036e+15, -372629504},
5446 {287524199.5377777, 0x11234567},
5447 {-287524199.5377777, -0x11234567},
5448 {2300193596.302222, 2300193596.0},
5449 {-2300193596.302222, -2300193596.0},
5450 {4600387192.604444, 305419896},
5451 {-4600387192.604444, -305419896},
5452 {4823855600872397.0, 1737075661},
5453 {-4823855600872397.0, -1737075661},
5454 {4503603922337791.0, -1},
5455 {-4503603922337791.0, 1},
5456 {4503601774854143.0, 2147483647},
5457 {-4503601774854143.0, -2147483647},
5458 {9007207844675582.0, -2},
5459 {-9007207844675582.0, 2},
5460 {2.4178527921507624e+24, -536870912},
5461 {-2.4178527921507624e+24, 536870912},
5462 {2.417853945072267e+24, -536870912},
5463 {-2.417853945072267e+24, 536870912},
5464 {4.8357055843015248e+24, -1073741824},
5465 {-4.8357055843015248e+24, 1073741824},
5466 {4.8357078901445341e+24, -1073741824},
5467 {-4.8357078901445341e+24, 1073741824},
5468 {2147483647.0, 2147483647.0},
5469 {-2147483648.0, -2147483648.0},
5470 {9.6714111686030497e+24, -2147483648.0},
5471 {-9.6714111686030497e+24, -2147483648.0},
5472 {9.6714157802890681e+24, -2147483648.0},
5473 {-9.6714157802890681e+24, -2147483648.0},
5474 {1.9342813113834065e+25, 2147483648.0},
5475 {-1.9342813113834065e+25, 2147483648.0},
5476 {3.868562622766813e+25, 0},
5477 {-3.868562622766813e+25, 0},
5478 {1.7976931348623157e+308, 0},
5479 {-1.7976931348623157e+308, 0}};
5480 double input = -1.0;
5481 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005482 m.Return(m.TruncateFloat64ToInt32(
5483 TruncationMode::kJavaScript,
5484 m.LoadFromPointer(&input, MachineType::Float64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005485 for (size_t i = 0; i < arraysize(kValues); ++i) {
5486 input = kValues[i].from;
5487 uint64_t expected = static_cast<int64_t>(kValues[i].raw);
5488 CHECK_EQ(static_cast<int>(expected), m.Call());
5489 }
5490}
5491
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005492
5493TEST(RunChangeFloat32ToFloat64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005494 BufferedRawMachineAssemblerTester<double> m(MachineType::Float32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005495
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005496 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005497
Ben Murdochda12d292016-06-02 14:46:10 +01005498 FOR_FLOAT32_INPUTS(i) {
5499 CHECK_DOUBLE_EQ(static_cast<double>(*i), m.Call(*i));
5500 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005501}
5502
5503
5504TEST(RunFloat32Constant) {
5505 FOR_FLOAT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005506 BufferedRawMachineAssemblerTester<float> m;
5507 m.Return(m.Float32Constant(*i));
Ben Murdochda12d292016-06-02 14:46:10 +01005508 CHECK_FLOAT_EQ(*i, m.Call());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005509 }
5510}
5511
5512
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005513TEST(RunFloat64ExtractLowWord32) {
5514 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5515 m.Return(m.Float64ExtractLowWord32(m.Parameter(0)));
5516 FOR_FLOAT64_INPUTS(i) {
5517 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i));
5518 CHECK_EQ(expected, m.Call(*i));
5519 }
5520}
5521
5522
5523TEST(RunFloat64ExtractHighWord32) {
5524 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5525 m.Return(m.Float64ExtractHighWord32(m.Parameter(0)));
5526 FOR_FLOAT64_INPUTS(i) {
5527 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32);
5528 CHECK_EQ(expected, m.Call(*i));
5529 }
5530}
5531
5532
5533TEST(RunFloat64InsertLowWord32) {
5534 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5535 MachineType::Int32());
5536 m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1)));
5537 FOR_FLOAT64_INPUTS(i) {
5538 FOR_INT32_INPUTS(j) {
5539 double expected = bit_cast<double>(
5540 (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) |
5541 (static_cast<uint64_t>(bit_cast<uint32_t>(*j))));
Ben Murdochda12d292016-06-02 14:46:10 +01005542 CHECK_DOUBLE_EQ(expected, m.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005543 }
5544 }
5545}
5546
5547
5548TEST(RunFloat64InsertHighWord32) {
5549 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5550 MachineType::Uint32());
5551 m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1)));
5552 FOR_FLOAT64_INPUTS(i) {
5553 FOR_UINT32_INPUTS(j) {
5554 uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) |
5555 (static_cast<uint64_t>(*j) << 32);
5556
Ben Murdochda12d292016-06-02 14:46:10 +01005557 CHECK_DOUBLE_EQ(bit_cast<double>(expected), m.Call(*i, *j));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005558 }
5559 }
5560}
5561
5562
5563TEST(RunFloat32Abs) {
5564 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5565 m.Return(m.Float32Abs(m.Parameter(0)));
Ben Murdochda12d292016-06-02 14:46:10 +01005566 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(std::abs(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005567}
5568
5569
5570TEST(RunFloat64Abs) {
5571 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5572 m.Return(m.Float64Abs(m.Parameter(0)));
Ben Murdochda12d292016-06-02 14:46:10 +01005573 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(std::abs(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005574}
5575
5576
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005577static double two_30 = 1 << 30; // 2^30 is a smi boundary.
5578static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary.
5579static double kValues[] = {0.1,
5580 0.2,
5581 0.49999999999999994,
5582 0.5,
5583 0.7,
5584 1.0 - std::numeric_limits<double>::epsilon(),
5585 -0.1,
5586 -0.49999999999999994,
5587 -0.5,
5588 -0.7,
5589 1.1,
5590 1.0 + std::numeric_limits<double>::epsilon(),
5591 1.5,
5592 1.7,
5593 -1,
5594 -1 + std::numeric_limits<double>::epsilon(),
5595 -1 - std::numeric_limits<double>::epsilon(),
5596 -1.1,
5597 -1.5,
5598 -1.7,
5599 std::numeric_limits<double>::min(),
5600 -std::numeric_limits<double>::min(),
5601 std::numeric_limits<double>::max(),
5602 -std::numeric_limits<double>::max(),
5603 std::numeric_limits<double>::infinity(),
5604 -std::numeric_limits<double>::infinity(),
5605 two_30,
5606 two_30 + 0.1,
5607 two_30 + 0.5,
5608 two_30 + 0.7,
5609 two_30 - 1,
5610 two_30 - 1 + 0.1,
5611 two_30 - 1 + 0.5,
5612 two_30 - 1 + 0.7,
5613 -two_30,
5614 -two_30 + 0.1,
5615 -two_30 + 0.5,
5616 -two_30 + 0.7,
5617 -two_30 + 1,
5618 -two_30 + 1 + 0.1,
5619 -two_30 + 1 + 0.5,
5620 -two_30 + 1 + 0.7,
5621 two_52,
5622 two_52 + 0.1,
5623 two_52 + 0.5,
5624 two_52 + 0.5,
5625 two_52 + 0.7,
5626 two_52 + 0.7,
5627 two_52 - 1,
5628 two_52 - 1 + 0.1,
5629 two_52 - 1 + 0.5,
5630 two_52 - 1 + 0.7,
5631 -two_52,
5632 -two_52 + 0.1,
5633 -two_52 + 0.5,
5634 -two_52 + 0.7,
5635 -two_52 + 1,
5636 -two_52 + 1 + 0.1,
5637 -two_52 + 1 + 0.5,
5638 -two_52 + 1 + 0.7,
5639 two_30,
5640 two_30 - 0.1,
5641 two_30 - 0.5,
5642 two_30 - 0.7,
5643 two_30 - 1,
5644 two_30 - 1 - 0.1,
5645 two_30 - 1 - 0.5,
5646 two_30 - 1 - 0.7,
5647 -two_30,
5648 -two_30 - 0.1,
5649 -two_30 - 0.5,
5650 -two_30 - 0.7,
5651 -two_30 + 1,
5652 -two_30 + 1 - 0.1,
5653 -two_30 + 1 - 0.5,
5654 -two_30 + 1 - 0.7,
5655 two_52,
5656 two_52 - 0.1,
5657 two_52 - 0.5,
5658 two_52 - 0.5,
5659 two_52 - 0.7,
5660 two_52 - 0.7,
5661 two_52 - 1,
5662 two_52 - 1 - 0.1,
5663 two_52 - 1 - 0.5,
5664 two_52 - 1 - 0.7,
5665 -two_52,
5666 -two_52 - 0.1,
5667 -two_52 - 0.5,
5668 -two_52 - 0.7,
5669 -two_52 + 1,
5670 -two_52 + 1 - 0.1,
5671 -two_52 + 1 - 0.5,
5672 -two_52 + 1 - 0.7};
5673
5674
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005675TEST(RunFloat32RoundDown) {
5676 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5677 if (!m.machine()->Float32RoundDown().IsSupported()) return;
5678
5679 m.Return(m.Float32RoundDown(m.Parameter(0)));
5680
Ben Murdochda12d292016-06-02 14:46:10 +01005681 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(floorf(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005682}
5683
5684
5685TEST(RunFloat64RoundDown1) {
5686 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5687 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5688
5689 m.Return(m.Float64RoundDown(m.Parameter(0)));
5690
Ben Murdochda12d292016-06-02 14:46:10 +01005691 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(floor(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005692}
5693
5694
5695TEST(RunFloat64RoundDown2) {
5696 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5697 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5698 m.Return(m.Float64Sub(m.Float64Constant(-0.0),
5699 m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
5700 m.Parameter(0)))));
5701
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005702 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005703 CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005704 }
5705}
5706
5707
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005708TEST(RunFloat32RoundUp) {
5709 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5710 if (!m.machine()->Float32RoundUp().IsSupported()) return;
5711 m.Return(m.Float32RoundUp(m.Parameter(0)));
5712
Ben Murdochda12d292016-06-02 14:46:10 +01005713 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(ceilf(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005714}
5715
5716
5717TEST(RunFloat64RoundUp) {
5718 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5719 if (!m.machine()->Float64RoundUp().IsSupported()) return;
5720 m.Return(m.Float64RoundUp(m.Parameter(0)));
5721
Ben Murdochda12d292016-06-02 14:46:10 +01005722 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(ceil(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005723}
5724
5725
5726TEST(RunFloat32RoundTiesEven) {
5727 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5728 if (!m.machine()->Float32RoundTiesEven().IsSupported()) return;
5729 m.Return(m.Float32RoundTiesEven(m.Parameter(0)));
5730
Ben Murdochda12d292016-06-02 14:46:10 +01005731 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyint(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005732}
5733
5734
5735TEST(RunFloat64RoundTiesEven) {
5736 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5737 if (!m.machine()->Float64RoundTiesEven().IsSupported()) return;
5738 m.Return(m.Float64RoundTiesEven(m.Parameter(0)));
5739
Ben Murdochda12d292016-06-02 14:46:10 +01005740 FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), m.Call(*i)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005741}
5742
5743
5744TEST(RunFloat32RoundTruncate) {
5745 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5746 if (!m.machine()->Float32RoundTruncate().IsSupported()) return;
5747
5748 m.Return(m.Float32RoundTruncate(m.Parameter(0)));
5749
Ben Murdochda12d292016-06-02 14:46:10 +01005750 FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(truncf(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005751}
5752
5753
5754TEST(RunFloat64RoundTruncate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005755 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5756 if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
5757 m.Return(m.Float64RoundTruncate(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005758 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005759 CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005760 }
5761}
5762
5763
5764TEST(RunFloat64RoundTiesAway) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005765 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5766 if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
5767 m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005768 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005769 CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005770 }
5771}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005772
5773
5774#if !USE_SIMULATOR
5775
5776namespace {
5777
5778int32_t const kMagicFoo0 = 0xdeadbeef;
5779
5780
5781int32_t foo0() { return kMagicFoo0; }
5782
5783
5784int32_t foo1(int32_t x) { return x; }
5785
5786
5787int32_t foo2(int32_t x, int32_t y) { return x - y; }
5788
5789
5790int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
5791 int32_t g, int32_t h) {
5792 return a + b + c + d + e + f + g + h;
5793}
5794
5795} // namespace
5796
5797
5798TEST(RunCallCFunction0) {
5799 auto* foo0_ptr = &foo0;
5800 RawMachineAssemblerTester<int32_t> m;
5801 Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer());
5802 m.Return(m.CallCFunction0(MachineType::Int32(), function));
5803 CHECK_EQ(kMagicFoo0, m.Call());
5804}
5805
5806
5807TEST(RunCallCFunction1) {
5808 auto* foo1_ptr = &foo1;
5809 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5810 Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer());
5811 m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(),
5812 function, m.Parameter(0)));
5813 FOR_INT32_INPUTS(i) {
5814 int32_t const expected = *i;
5815 CHECK_EQ(expected, m.Call(expected));
5816 }
5817}
5818
5819
5820TEST(RunCallCFunction2) {
5821 auto* foo2_ptr = &foo2;
5822 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5823 MachineType::Int32());
5824 Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer());
5825 m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(),
5826 MachineType::Int32(), function, m.Parameter(0),
5827 m.Parameter(1)));
5828 FOR_INT32_INPUTS(i) {
5829 int32_t const x = *i;
5830 FOR_INT32_INPUTS(j) {
5831 int32_t const y = *j;
5832 CHECK_EQ(x - y, m.Call(x, y));
5833 }
5834 }
5835}
5836
5837
5838TEST(RunCallCFunction8) {
5839 auto* foo8_ptr = &foo8;
5840 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5841 Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer());
5842 Node* param = m.Parameter(0);
5843 m.Return(m.CallCFunction8(
5844 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5845 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5846 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5847 function, param, param, param, param, param, param, param, param));
5848 FOR_INT32_INPUTS(i) {
5849 int32_t const x = *i;
5850 CHECK_EQ(x * 8, m.Call(x));
5851 }
5852}
5853#endif // USE_SIMULATOR
5854
5855#if V8_TARGET_ARCH_64_BIT
5856// TODO(titzer): run int64 tests on all platforms when supported.
5857TEST(RunCheckedLoadInt64) {
5858 int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL};
5859 RawMachineAssemblerTester<int64_t> m(MachineType::Int32());
5860 Node* base = m.PointerConstant(buffer);
5861 Node* index = m.Parameter(0);
5862 Node* length = m.Int32Constant(16);
5863 Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base,
5864 index, length);
5865 m.Return(load);
5866
5867 CHECK_EQ(buffer[0], m.Call(0));
5868 CHECK_EQ(buffer[1], m.Call(8));
5869 CHECK_EQ(0, m.Call(16));
5870}
5871
5872
5873TEST(RunCheckedStoreInt64) {
5874 const int64_t write = 0x5566778899aabbLL;
5875 const int64_t before = 0x33bbccddeeff0011LL;
5876 int64_t buffer[] = {before, before};
5877 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5878 Node* base = m.PointerConstant(buffer);
5879 Node* index = m.Parameter(0);
5880 Node* length = m.Int32Constant(16);
5881 Node* value = m.Int64Constant(write);
5882 Node* store =
5883 m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base,
5884 index, length, value);
5885 USE(store);
5886 m.Return(m.Int32Constant(11));
5887
5888 CHECK_EQ(11, m.Call(16));
5889 CHECK_EQ(before, buffer[0]);
5890 CHECK_EQ(before, buffer[1]);
5891
5892 CHECK_EQ(11, m.Call(0));
5893 CHECK_EQ(write, buffer[0]);
5894 CHECK_EQ(before, buffer[1]);
5895
5896 CHECK_EQ(11, m.Call(8));
5897 CHECK_EQ(write, buffer[0]);
5898 CHECK_EQ(write, buffer[1]);
5899}
5900
5901
5902TEST(RunBitcastInt64ToFloat64) {
5903 int64_t input = 1;
5904 double output = 0.0;
5905 RawMachineAssemblerTester<int32_t> m;
5906 m.StoreToPointer(
5907 &output, MachineRepresentation::kFloat64,
5908 m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64())));
5909 m.Return(m.Int32Constant(11));
5910 FOR_INT64_INPUTS(i) {
5911 input = *i;
5912 CHECK_EQ(11, m.Call());
5913 double expected = bit_cast<double>(input);
5914 CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output));
5915 }
5916}
5917
5918
5919TEST(RunBitcastFloat64ToInt64) {
5920 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5921
5922 m.Return(m.BitcastFloat64ToInt64(m.Parameter(0)));
5923 FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); }
5924}
5925
5926
5927TEST(RunTryTruncateFloat32ToInt64WithoutCheck) {
5928 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5929 m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0)));
5930
5931 FOR_INT64_INPUTS(i) {
5932 float input = static_cast<float>(*i);
5933 if (input < static_cast<float>(INT64_MAX) &&
5934 input >= static_cast<float>(INT64_MIN)) {
5935 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5936 }
5937 }
5938}
5939
5940
5941TEST(RunTryTruncateFloat32ToInt64WithCheck) {
5942 int64_t success = 0;
5943 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5944 Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0));
5945 Node* val = m.Projection(0, trunc);
5946 Node* check = m.Projection(1, trunc);
5947 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5948 m.Return(val);
5949
5950 FOR_FLOAT32_INPUTS(i) {
5951 if (*i < static_cast<float>(INT64_MAX) &&
5952 *i >= static_cast<float>(INT64_MIN)) {
5953 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5954 CHECK_NE(0, success);
5955 } else {
5956 m.Call(*i);
5957 CHECK_EQ(0, success);
5958 }
5959 }
5960}
5961
5962
5963TEST(RunTryTruncateFloat64ToInt64WithoutCheck) {
5964 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5965 m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0)));
5966
5967 FOR_INT64_INPUTS(i) {
5968 double input = static_cast<double>(*i);
5969 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5970 }
5971}
5972
5973
5974TEST(RunTryTruncateFloat64ToInt64WithCheck) {
5975 int64_t success = 0;
5976 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5977 Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0));
5978 Node* val = m.Projection(0, trunc);
5979 Node* check = m.Projection(1, trunc);
5980 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5981 m.Return(val);
5982
5983 FOR_FLOAT64_INPUTS(i) {
5984 if (*i < static_cast<double>(INT64_MAX) &&
5985 *i >= static_cast<double>(INT64_MIN)) {
5986 // Conversions within this range should succeed.
5987 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5988 CHECK_NE(0, success);
5989 } else {
5990 m.Call(*i);
5991 CHECK_EQ(0, success);
5992 }
5993 }
5994}
5995
5996
5997TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
5998 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5999 m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
6000
6001 FOR_UINT64_INPUTS(i) {
6002 float input = static_cast<float>(*i);
6003 // This condition on 'input' is required because
6004 // static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
6005 if (input < static_cast<float>(UINT64_MAX)) {
6006 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
6007 }
6008 }
6009}
6010
6011
6012TEST(RunTryTruncateFloat32ToUint64WithCheck) {
6013 int64_t success = 0;
6014 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
6015 Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0));
6016 Node* val = m.Projection(0, trunc);
6017 Node* check = m.Projection(1, trunc);
6018 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
6019 m.Return(val);
6020
6021 FOR_FLOAT32_INPUTS(i) {
6022 if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
6023 // Conversions within this range should succeed.
6024 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
6025 CHECK_NE(0, success);
6026 } else {
6027 m.Call(*i);
6028 CHECK_EQ(0, success);
6029 }
6030 }
6031}
6032
6033
6034TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
6035 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64());
Ben Murdochda12d292016-06-02 14:46:10 +01006036 m.Return(m.TryTruncateFloat64ToUint64(m.Parameter(0)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006037
6038 FOR_UINT64_INPUTS(j) {
6039 double input = static_cast<double>(*j);
6040
6041 if (input < static_cast<float>(UINT64_MAX)) {
6042 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
6043 }
6044 }
6045}
6046
6047
6048TEST(RunTryTruncateFloat64ToUint64WithCheck) {
6049 int64_t success = 0;
6050 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
6051 Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0));
6052 Node* val = m.Projection(0, trunc);
6053 Node* check = m.Projection(1, trunc);
6054 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
6055 m.Return(val);
6056
6057 FOR_FLOAT64_INPUTS(i) {
6058 if (*i < 18446744073709551616.0 && *i > -1) {
6059 // Conversions within this range should succeed.
6060 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
6061 CHECK_NE(0, success);
6062 } else {
6063 m.Call(*i);
6064 CHECK_EQ(0, success);
6065 }
6066 }
6067}
6068
6069
6070TEST(RunRoundInt64ToFloat32) {
6071 BufferedRawMachineAssemblerTester<float> m(MachineType::Int64());
6072 m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
6073 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
6074}
6075
6076
6077TEST(RunRoundInt64ToFloat64) {
6078 BufferedRawMachineAssemblerTester<double> m(MachineType::Int64());
6079 m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
6080 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); }
6081}
6082
6083
6084TEST(RunRoundUint64ToFloat64) {
6085 struct {
6086 uint64_t input;
6087 uint64_t expected;
6088 } values[] = {{0x0, 0x0},
6089 {0x1, 0x3ff0000000000000},
6090 {0xffffffff, 0x41efffffffe00000},
6091 {0x1b09788b, 0x41bb09788b000000},
6092 {0x4c5fce8, 0x419317f3a0000000},
6093 {0xcc0de5bf, 0x41e981bcb7e00000},
6094 {0x2, 0x4000000000000000},
6095 {0x3, 0x4008000000000000},
6096 {0x4, 0x4010000000000000},
6097 {0x5, 0x4014000000000000},
6098 {0x8, 0x4020000000000000},
6099 {0x9, 0x4022000000000000},
6100 {0xffffffffffffffff, 0x43f0000000000000},
6101 {0xfffffffffffffffe, 0x43f0000000000000},
6102 {0xfffffffffffffffd, 0x43f0000000000000},
6103 {0x100000000, 0x41f0000000000000},
6104 {0xffffffff00000000, 0x43efffffffe00000},
6105 {0x1b09788b00000000, 0x43bb09788b000000},
6106 {0x4c5fce800000000, 0x439317f3a0000000},
6107 {0xcc0de5bf00000000, 0x43e981bcb7e00000},
6108 {0x200000000, 0x4200000000000000},
6109 {0x300000000, 0x4208000000000000},
6110 {0x400000000, 0x4210000000000000},
6111 {0x500000000, 0x4214000000000000},
6112 {0x800000000, 0x4220000000000000},
6113 {0x900000000, 0x4222000000000000},
6114 {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
6115 {0xece3af835495a16b, 0x43ed9c75f06a92b4},
6116 {0xb668ecc11223344, 0x43a6cd1d98224467},
6117 {0x9e, 0x4063c00000000000},
6118 {0x43, 0x4050c00000000000},
6119 {0xaf73, 0x40e5ee6000000000},
6120 {0x116b, 0x40b16b0000000000},
6121 {0x658ecc, 0x415963b300000000},
6122 {0x2b3b4c, 0x41459da600000000},
6123 {0x88776655, 0x41e10eeccaa00000},
6124 {0x70000000, 0x41dc000000000000},
6125 {0x7200000, 0x419c800000000000},
6126 {0x7fffffff, 0x41dfffffffc00000},
6127 {0x56123761, 0x41d5848dd8400000},
6128 {0x7fffff00, 0x41dfffffc0000000},
6129 {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
6130 {0x80000000eeeeeeee, 0x43e00000001dddde},
6131 {0x88888888dddddddd, 0x43e11111111bbbbc},
6132 {0xa0000000dddddddd, 0x43e40000001bbbbc},
6133 {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
6134 {0xe0000000aaaaaaaa, 0x43ec000000155555},
6135 {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
6136 {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
6137 {0xf0000000dddddddd, 0x43ee0000001bbbbc},
6138 {0x7fffffdddddddd, 0x435ffffff7777777},
6139 {0x3fffffaaaaaaaa, 0x434fffffd5555555},
6140 {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
6141 {0xfffff, 0x412ffffe00000000},
6142 {0x7ffff, 0x411ffffc00000000},
6143 {0x3ffff, 0x410ffff800000000},
6144 {0x1ffff, 0x40fffff000000000},
6145 {0xffff, 0x40efffe000000000},
6146 {0x7fff, 0x40dfffc000000000},
6147 {0x3fff, 0x40cfff8000000000},
6148 {0x1fff, 0x40bfff0000000000},
6149 {0xfff, 0x40affe0000000000},
6150 {0x7ff, 0x409ffc0000000000},
6151 {0x3ff, 0x408ff80000000000},
6152 {0x1ff, 0x407ff00000000000},
6153 {0x3fffffffffff, 0x42cfffffffffff80},
6154 {0x1fffffffffff, 0x42bfffffffffff00},
6155 {0xfffffffffff, 0x42affffffffffe00},
6156 {0x7ffffffffff, 0x429ffffffffffc00},
6157 {0x3ffffffffff, 0x428ffffffffff800},
6158 {0x1ffffffffff, 0x427ffffffffff000},
6159 {0x8000008000000000, 0x43e0000010000000},
6160 {0x8000008000000001, 0x43e0000010000000},
6161 {0x8000000000000400, 0x43e0000000000000},
6162 {0x8000000000000401, 0x43e0000000000001}};
6163
6164 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64());
6165 m.Return(m.RoundUint64ToFloat64(m.Parameter(0)));
6166
6167 for (size_t i = 0; i < arraysize(values); i++) {
6168 CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input));
6169 }
6170}
6171
6172
6173TEST(RunRoundUint64ToFloat32) {
6174 struct {
6175 uint64_t input;
6176 uint32_t expected;
6177 } values[] = {{0x0, 0x0},
6178 {0x1, 0x3f800000},
6179 {0xffffffff, 0x4f800000},
6180 {0x1b09788b, 0x4dd84bc4},
6181 {0x4c5fce8, 0x4c98bf9d},
6182 {0xcc0de5bf, 0x4f4c0de6},
6183 {0x2, 0x40000000},
6184 {0x3, 0x40400000},
6185 {0x4, 0x40800000},
6186 {0x5, 0x40a00000},
6187 {0x8, 0x41000000},
6188 {0x9, 0x41100000},
6189 {0xffffffffffffffff, 0x5f800000},
6190 {0xfffffffffffffffe, 0x5f800000},
6191 {0xfffffffffffffffd, 0x5f800000},
6192 {0x0, 0x0},
6193 {0x100000000, 0x4f800000},
6194 {0xffffffff00000000, 0x5f800000},
6195 {0x1b09788b00000000, 0x5dd84bc4},
6196 {0x4c5fce800000000, 0x5c98bf9d},
6197 {0xcc0de5bf00000000, 0x5f4c0de6},
6198 {0x200000000, 0x50000000},
6199 {0x300000000, 0x50400000},
6200 {0x400000000, 0x50800000},
6201 {0x500000000, 0x50a00000},
6202 {0x800000000, 0x51000000},
6203 {0x900000000, 0x51100000},
6204 {0x273a798e187937a3, 0x5e1ce9e6},
6205 {0xece3af835495a16b, 0x5f6ce3b0},
6206 {0xb668ecc11223344, 0x5d3668ed},
6207 {0x9e, 0x431e0000},
6208 {0x43, 0x42860000},
6209 {0xaf73, 0x472f7300},
6210 {0x116b, 0x458b5800},
6211 {0x658ecc, 0x4acb1d98},
6212 {0x2b3b4c, 0x4a2ced30},
6213 {0x88776655, 0x4f087766},
6214 {0x70000000, 0x4ee00000},
6215 {0x7200000, 0x4ce40000},
6216 {0x7fffffff, 0x4f000000},
6217 {0x56123761, 0x4eac246f},
6218 {0x7fffff00, 0x4efffffe},
6219 {0x761c4761eeeeeeee, 0x5eec388f},
6220 {0x80000000eeeeeeee, 0x5f000000},
6221 {0x88888888dddddddd, 0x5f088889},
6222 {0xa0000000dddddddd, 0x5f200000},
6223 {0xddddddddaaaaaaaa, 0x5f5dddde},
6224 {0xe0000000aaaaaaaa, 0x5f600000},
6225 {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
6226 {0xfffffffdeeeeeeee, 0x5f800000},
6227 {0xf0000000dddddddd, 0x5f700000},
6228 {0x7fffffdddddddd, 0x5b000000},
6229 {0x3fffffaaaaaaaa, 0x5a7fffff},
6230 {0x1fffffaaaaaaaa, 0x59fffffd},
6231 {0xfffff, 0x497ffff0},
6232 {0x7ffff, 0x48ffffe0},
6233 {0x3ffff, 0x487fffc0},
6234 {0x1ffff, 0x47ffff80},
6235 {0xffff, 0x477fff00},
6236 {0x7fff, 0x46fffe00},
6237 {0x3fff, 0x467ffc00},
6238 {0x1fff, 0x45fff800},
6239 {0xfff, 0x457ff000},
6240 {0x7ff, 0x44ffe000},
6241 {0x3ff, 0x447fc000},
6242 {0x1ff, 0x43ff8000},
6243 {0x3fffffffffff, 0x56800000},
6244 {0x1fffffffffff, 0x56000000},
6245 {0xfffffffffff, 0x55800000},
6246 {0x7ffffffffff, 0x55000000},
6247 {0x3ffffffffff, 0x54800000},
6248 {0x1ffffffffff, 0x54000000},
6249 {0x8000008000000000, 0x5f000000},
6250 {0x8000008000000001, 0x5f000001},
6251 {0x8000000000000400, 0x5f000000},
6252 {0x8000000000000401, 0x5f000000}};
6253
6254 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64());
6255 m.Return(m.RoundUint64ToFloat32(m.Parameter(0)));
6256
6257 for (size_t i = 0; i < arraysize(values); i++) {
6258 CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input));
6259 }
6260}
6261
6262
6263#endif
6264
6265
6266TEST(RunBitcastFloat32ToInt32) {
6267 float input = 32.25;
6268 RawMachineAssemblerTester<int32_t> m;
6269 m.Return(m.BitcastFloat32ToInt32(
6270 m.LoadFromPointer(&input, MachineType::Float32())));
6271 FOR_FLOAT32_INPUTS(i) {
6272 input = *i;
6273 int32_t expected = bit_cast<int32_t>(input);
6274 CHECK_EQ(expected, m.Call());
6275 }
6276}
6277
6278
Ben Murdoch097c5b22016-05-18 11:27:45 +01006279TEST(RunRoundInt32ToFloat32) {
6280 BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
6281 m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
6282 FOR_INT32_INPUTS(i) {
6283 volatile float expected = static_cast<float>(*i);
6284 CHECK_EQ(expected, m.Call(*i));
6285 }
6286}
6287
6288
6289TEST(RunRoundUint32ToFloat32) {
6290 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint32());
6291 m.Return(m.RoundUint32ToFloat32(m.Parameter(0)));
6292 FOR_UINT32_INPUTS(i) {
6293 volatile float expected = static_cast<float>(*i);
6294 CHECK_EQ(expected, m.Call(*i));
6295 }
6296}
6297
6298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006299TEST(RunBitcastInt32ToFloat32) {
6300 int32_t input = 1;
6301 float output = 0.0;
6302 RawMachineAssemblerTester<int32_t> m;
6303 m.StoreToPointer(
6304 &output, MachineRepresentation::kFloat32,
6305 m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32())));
6306 m.Return(m.Int32Constant(11));
6307 FOR_INT32_INPUTS(i) {
6308 input = *i;
6309 CHECK_EQ(11, m.Call());
6310 float expected = bit_cast<float>(input);
6311 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output));
6312 }
6313}
6314
6315
6316TEST(RunComputedCodeObject) {
6317 GraphBuilderTester<int32_t> a;
6318 a.Return(a.Int32Constant(33));
6319 a.End();
6320 Handle<Code> code_a = a.GetCode();
6321
6322 GraphBuilderTester<int32_t> b;
6323 b.Return(b.Int32Constant(44));
6324 b.End();
6325 Handle<Code> code_b = b.GetCode();
6326
6327 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6328 RawMachineLabel tlabel;
6329 RawMachineLabel flabel;
6330 RawMachineLabel merge;
6331 r.Branch(r.Parameter(0), &tlabel, &flabel);
6332 r.Bind(&tlabel);
6333 Node* fa = r.HeapConstant(code_a);
6334 r.Goto(&merge);
6335 r.Bind(&flabel);
6336 Node* fb = r.HeapConstant(code_b);
6337 r.Goto(&merge);
6338 r.Bind(&merge);
6339 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6340
6341 // TODO(titzer): all this descriptor hackery is just to call the above
6342 // functions as code objects instead of direct addresses.
6343 CSignature0<int32_t> sig;
6344 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig);
6345 LinkageLocation ret[] = {c->GetReturnLocation(0)};
6346 Signature<LinkageLocation> loc(1, 0, ret);
6347 CallDescriptor* desc = new (r.zone()) CallDescriptor( // --
6348 CallDescriptor::kCallCodeObject, // kind
6349 MachineType::AnyTagged(), // target_type
6350 c->GetInputLocation(0), // target_loc
6351 &sig, // machine_sig
6352 &loc, // location_sig
6353 0, // stack count
6354 Operator::kNoProperties, // properties
6355 c->CalleeSavedRegisters(), // callee saved
6356 c->CalleeSavedFPRegisters(), // callee saved FP
6357 CallDescriptor::kNoFlags, // flags
6358 "c-call-as-code");
6359 Node* call = r.AddNode(r.common()->Call(desc), phi);
6360 r.Return(call);
6361
6362 CHECK_EQ(33, r.Call(1));
6363 CHECK_EQ(44, r.Call(0));
6364}
6365
Ben Murdoch097c5b22016-05-18 11:27:45 +01006366TEST(ParentFramePointer) {
6367 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6368 RawMachineLabel tlabel;
6369 RawMachineLabel flabel;
6370 RawMachineLabel merge;
6371 Node* frame = r.LoadFramePointer();
6372 Node* parent_frame = r.LoadParentFramePointer();
6373 frame = r.Load(MachineType::IntPtr(), frame);
6374 r.Branch(r.WordEqual(frame, parent_frame), &tlabel, &flabel);
6375 r.Bind(&tlabel);
6376 Node* fa = r.Int32Constant(1);
6377 r.Goto(&merge);
6378 r.Bind(&flabel);
6379 Node* fb = r.Int32Constant(0);
6380 r.Goto(&merge);
6381 r.Bind(&merge);
6382 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6383 r.Return(phi);
6384 CHECK_EQ(1, r.Call(1));
6385}
6386
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006387} // namespace compiler
6388} // namespace internal
6389} // namespace v8