blob: fba9e0e1a505e8ca89dd2866a51f50bb1af9c7fa [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());
1200 CheckDoubleEq(p1, p2);
1201 }
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 Murdoch4a90d5f2016-03-22 12:00:34 +00001227 CheckDoubleEq(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) {
3661 FOR_FLOAT32_INPUTS(j) {
3662 volatile float expected = *i + *j;
3663 CheckFloatEq(expected, m.Call(*i, *j));
3664 }
3665 }
3666}
3667
3668
3669TEST(RunFloat32Sub) {
3670 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3671 MachineType::Float32());
3672 m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1)));
3673
3674 FOR_FLOAT32_INPUTS(i) {
3675 FOR_FLOAT32_INPUTS(j) {
3676 volatile float expected = *i - *j;
3677 CheckFloatEq(expected, m.Call(*i, *j));
3678 }
3679 }
3680}
3681
3682
3683TEST(RunFloat32Mul) {
3684 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3685 MachineType::Float32());
3686 m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1)));
3687
3688 FOR_FLOAT32_INPUTS(i) {
3689 FOR_FLOAT32_INPUTS(j) {
3690 volatile float expected = *i * *j;
3691 CheckFloatEq(expected, m.Call(*i, *j));
3692 }
3693 }
3694}
3695
3696
3697TEST(RunFloat32Div) {
3698 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(),
3699 MachineType::Float32());
3700 m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1)));
3701
3702 FOR_FLOAT32_INPUTS(i) {
3703 FOR_FLOAT32_INPUTS(j) {
3704 volatile float expected = *i / *j;
3705 CheckFloatEq(expected, m.Call(*i, *j));
3706 }
3707 }
3708}
3709
3710
3711TEST(RunFloat64Add) {
3712 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3713 MachineType::Float64());
3714 m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1)));
3715
3716 FOR_FLOAT64_INPUTS(i) {
3717 FOR_FLOAT64_INPUTS(j) {
3718 volatile double expected = *i + *j;
3719 CheckDoubleEq(expected, m.Call(*i, *j));
3720 }
3721 }
3722}
3723
3724
3725TEST(RunFloat64Sub) {
3726 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3727 MachineType::Float64());
3728 m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1)));
3729
3730 FOR_FLOAT64_INPUTS(i) {
3731 FOR_FLOAT64_INPUTS(j) {
3732 volatile double expected = *i - *j;
3733 CheckDoubleEq(expected, m.Call(*i, *j));
3734 }
3735 }
3736}
3737
3738
3739TEST(RunFloat64Mul) {
3740 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3741 MachineType::Float64());
3742 m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1)));
3743
3744 FOR_FLOAT64_INPUTS(i) {
3745 FOR_FLOAT64_INPUTS(j) {
3746 volatile double expected = *i * *j;
3747 CheckDoubleEq(expected, m.Call(*i, *j));
3748 }
3749 }
3750}
3751
3752
3753TEST(RunFloat64Div) {
3754 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3755 MachineType::Float64());
3756 m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1)));
3757
3758 FOR_FLOAT64_INPUTS(i) {
3759 FOR_FLOAT64_INPUTS(j) {
3760 volatile double expected = *i / *j;
3761 CheckDoubleEq(expected, m.Call(*i, *j));
3762 }
3763 }
3764}
3765
3766
3767TEST(RunFloat64Mod) {
3768 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
3769 MachineType::Float64());
3770 m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
3771
3772 FOR_FLOAT64_INPUTS(i) {
3773 FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(modulo(*i, *j), m.Call(*i, *j)); }
3774 }
3775}
3776
3777
3778TEST(RunDeadFloat32Binops) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003779 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003780
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003781 const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(),
3782 m.machine()->Float32Mul(), m.machine()->Float32Div(),
3783 NULL};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003784
3785 for (int i = 0; ops[i] != NULL; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003786 RawMachineAssemblerTester<int32_t> m;
3787 int constant = 0x53355 + i;
3788 m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f));
3789 m.Return(m.Int32Constant(constant));
3790 CHECK_EQ(constant, m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003791 }
3792}
3793
3794
3795TEST(RunDeadFloat64Binops) {
3796 RawMachineAssemblerTester<int32_t> m;
3797
3798 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(),
3799 m.machine()->Float64Mul(), m.machine()->Float64Div(),
3800 m.machine()->Float64Mod(), NULL};
3801
3802 for (int i = 0; ops[i] != NULL; i++) {
3803 RawMachineAssemblerTester<int32_t> m;
3804 int constant = 0x53355 + i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003805 m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003806 m.Return(m.Int32Constant(constant));
3807 CHECK_EQ(constant, m.Call());
3808 }
3809}
3810
3811
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003812TEST(RunFloat32AddP) {
3813 RawMachineAssemblerTester<int32_t> m;
3814 Float32BinopTester bt(&m);
3815
3816 bt.AddReturn(m.Float32Add(bt.param0, bt.param1));
3817
3818 FOR_FLOAT32_INPUTS(pl) {
3819 FOR_FLOAT32_INPUTS(pr) {
3820 float expected = *pl + *pr;
3821 CheckFloatEq(expected, bt.call(*pl, *pr));
3822 }
3823 }
3824}
3825
3826
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003827TEST(RunFloat64AddP) {
3828 RawMachineAssemblerTester<int32_t> m;
3829 Float64BinopTester bt(&m);
3830
3831 bt.AddReturn(m.Float64Add(bt.param0, bt.param1));
3832
3833 FOR_FLOAT64_INPUTS(pl) {
3834 FOR_FLOAT64_INPUTS(pr) {
3835 double expected = *pl + *pr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003836 CheckDoubleEq(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003837 }
3838 }
3839}
3840
3841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003842TEST(RunFloa32MaxP) {
3843 RawMachineAssemblerTester<int32_t> m;
3844 Float32BinopTester bt(&m);
3845 if (!m.machine()->Float32Max().IsSupported()) return;
3846
3847 bt.AddReturn(m.Float32Max(bt.param0, bt.param1));
3848
3849 FOR_FLOAT32_INPUTS(pl) {
3850 FOR_FLOAT32_INPUTS(pr) {
3851 double expected = *pl > *pr ? *pl : *pr;
3852 CheckDoubleEq(expected, bt.call(*pl, *pr));
3853 }
3854 }
3855}
3856
3857
3858TEST(RunFloat64MaxP) {
3859 RawMachineAssemblerTester<int32_t> m;
3860 Float64BinopTester bt(&m);
3861 if (!m.machine()->Float64Max().IsSupported()) return;
3862
3863 bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
3864
3865 FOR_FLOAT64_INPUTS(pl) {
3866 FOR_FLOAT64_INPUTS(pr) {
3867 double expected = *pl > *pr ? *pl : *pr;
3868 CheckDoubleEq(expected, bt.call(*pl, *pr));
3869 }
3870 }
3871}
3872
3873
3874TEST(RunFloat32MinP) {
3875 RawMachineAssemblerTester<int32_t> m;
3876 Float32BinopTester bt(&m);
3877 if (!m.machine()->Float32Min().IsSupported()) return;
3878
3879 bt.AddReturn(m.Float32Min(bt.param0, bt.param1));
3880
3881 FOR_FLOAT32_INPUTS(pl) {
3882 FOR_FLOAT32_INPUTS(pr) {
3883 double expected = *pl < *pr ? *pl : *pr;
3884 CheckDoubleEq(expected, bt.call(*pl, *pr));
3885 }
3886 }
3887}
3888
3889
3890TEST(RunFloat64MinP) {
3891 RawMachineAssemblerTester<int32_t> m;
3892 Float64BinopTester bt(&m);
3893 if (!m.machine()->Float64Min().IsSupported()) return;
3894
3895 bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
3896
3897 FOR_FLOAT64_INPUTS(pl) {
3898 FOR_FLOAT64_INPUTS(pr) {
3899 double expected = *pl < *pr ? *pl : *pr;
3900 CheckDoubleEq(expected, bt.call(*pl, *pr));
3901 }
3902 }
3903}
3904
3905
3906TEST(RunFloat32SubP) {
3907 RawMachineAssemblerTester<int32_t> m;
3908 Float32BinopTester bt(&m);
3909
3910 bt.AddReturn(m.Float32Sub(bt.param0, bt.param1));
3911
3912 FOR_FLOAT32_INPUTS(pl) {
3913 FOR_FLOAT32_INPUTS(pr) {
3914 float expected = *pl - *pr;
3915 CheckFloatEq(expected, bt.call(*pl, *pr));
3916 }
3917 }
3918}
3919
3920
3921TEST(RunFloat32SubImm1) {
3922 FOR_FLOAT32_INPUTS(i) {
3923 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3924 m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0)));
3925
3926 FOR_FLOAT32_INPUTS(j) {
3927 volatile float expected = *i - *j;
3928 CheckFloatEq(expected, m.Call(*j));
3929 }
3930 }
3931}
3932
3933
3934TEST(RunFloat32SubImm2) {
3935 FOR_FLOAT32_INPUTS(i) {
3936 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
3937 m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i)));
3938
3939 FOR_FLOAT32_INPUTS(j) {
3940 volatile float expected = *j - *i;
3941 CheckFloatEq(expected, m.Call(*j));
3942 }
3943 }
3944}
3945
3946
3947TEST(RunFloat64SubImm1) {
3948 FOR_FLOAT64_INPUTS(i) {
3949 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3950 m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
3951
3952 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i - *j, m.Call(*j)); }
3953 }
3954}
3955
3956
3957TEST(RunFloat64SubImm2) {
3958 FOR_FLOAT64_INPUTS(i) {
3959 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
3960 m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
3961
3962 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j - *i, m.Call(*j)); }
3963 }
3964}
3965
3966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003967TEST(RunFloat64SubP) {
3968 RawMachineAssemblerTester<int32_t> m;
3969 Float64BinopTester bt(&m);
3970
3971 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1));
3972
3973 FOR_FLOAT64_INPUTS(pl) {
3974 FOR_FLOAT64_INPUTS(pr) {
3975 double expected = *pl - *pr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003976 CheckDoubleEq(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003977 }
3978 }
3979}
3980
3981
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003982TEST(RunFloat32MulP) {
3983 RawMachineAssemblerTester<int32_t> m;
3984 Float32BinopTester bt(&m);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003986 bt.AddReturn(m.Float32Mul(bt.param0, bt.param1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003987
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003988 FOR_FLOAT32_INPUTS(pl) {
3989 FOR_FLOAT32_INPUTS(pr) {
3990 float expected = *pl * *pr;
3991 CheckFloatEq(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003992 }
3993 }
3994}
3995
3996
3997TEST(RunFloat64MulP) {
3998 RawMachineAssemblerTester<int32_t> m;
3999 Float64BinopTester bt(&m);
4000
4001 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1));
4002
4003 FOR_FLOAT64_INPUTS(pl) {
4004 FOR_FLOAT64_INPUTS(pr) {
4005 double expected = *pl * *pr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004006 CheckDoubleEq(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004007 }
4008 }
4009}
4010
4011
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004012TEST(RunFloat64MulAndFloat64Add1) {
4013 BufferedRawMachineAssemblerTester<double> m(
4014 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4015 m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
4016 m.Parameter(2)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004017
4018 FOR_FLOAT64_INPUTS(i) {
4019 FOR_FLOAT64_INPUTS(j) {
4020 FOR_FLOAT64_INPUTS(k) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004021 CheckDoubleEq((*i * *j) + *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004022 }
4023 }
4024 }
4025}
4026
4027
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004028TEST(RunFloat64MulAndFloat64Add2) {
4029 BufferedRawMachineAssemblerTester<double> m(
4030 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4031 m.Return(m.Float64Add(m.Parameter(0),
4032 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004034 FOR_FLOAT64_INPUTS(i) {
4035 FOR_FLOAT64_INPUTS(j) {
4036 FOR_FLOAT64_INPUTS(k) {
4037 CheckDoubleEq(*i + (*j * *k), m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004038 }
4039 }
4040 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004041}
4042
4043
4044TEST(RunFloat64MulAndFloat64Sub1) {
4045 BufferedRawMachineAssemblerTester<double> m(
4046 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4047 m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)),
4048 m.Parameter(2)));
4049
4050 FOR_FLOAT64_INPUTS(i) {
4051 FOR_FLOAT64_INPUTS(j) {
4052 FOR_FLOAT64_INPUTS(k) {
4053 CheckDoubleEq((*i * *j) - *k, m.Call(*i, *j, *k));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004054 }
4055 }
4056 }
4057}
4058
4059
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004060TEST(RunFloat64MulAndFloat64Sub2) {
4061 BufferedRawMachineAssemblerTester<double> m(
4062 MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
4063 m.Return(m.Float64Sub(m.Parameter(0),
4064 m.Float64Mul(m.Parameter(1), m.Parameter(2))));
4065
4066 FOR_FLOAT64_INPUTS(i) {
4067 FOR_FLOAT64_INPUTS(j) {
4068 FOR_FLOAT64_INPUTS(k) {
4069 CheckDoubleEq(*i - (*j * *k), m.Call(*i, *j, *k));
4070 }
4071 }
4072 }
4073}
4074
4075
4076TEST(RunFloat64MulImm1) {
4077 FOR_FLOAT64_INPUTS(i) {
4078 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4079 m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
4080
4081 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i * *j, m.Call(*j)); }
4082 }
4083}
4084
4085
4086TEST(RunFloat64MulImm2) {
4087 FOR_FLOAT64_INPUTS(i) {
4088 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
4089 m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
4090
4091 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j * *i, m.Call(*j)); }
4092 }
4093}
4094
4095
4096TEST(RunFloat32DivP) {
4097 RawMachineAssemblerTester<int32_t> m;
4098 Float32BinopTester bt(&m);
4099
4100 bt.AddReturn(m.Float32Div(bt.param0, bt.param1));
4101
4102 FOR_FLOAT32_INPUTS(pl) {
4103 FOR_FLOAT32_INPUTS(pr) {
4104 float expected = *pl / *pr;
4105 CheckFloatEq(expected, bt.call(*pl, *pr));
4106 }
4107 }
4108}
4109
4110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004111TEST(RunFloat64DivP) {
4112 RawMachineAssemblerTester<int32_t> m;
4113 Float64BinopTester bt(&m);
4114
4115 bt.AddReturn(m.Float64Div(bt.param0, bt.param1));
4116
4117 FOR_FLOAT64_INPUTS(pl) {
4118 FOR_FLOAT64_INPUTS(pr) {
4119 double expected = *pl / *pr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004120 CheckDoubleEq(expected, bt.call(*pl, *pr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004121 }
4122 }
4123}
4124
4125
4126TEST(RunFloat64ModP) {
4127 RawMachineAssemblerTester<int32_t> m;
4128 Float64BinopTester bt(&m);
4129
4130 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
4131
4132 FOR_FLOAT64_INPUTS(i) {
4133 FOR_FLOAT64_INPUTS(j) {
4134 double expected = modulo(*i, *j);
4135 double found = bt.call(*i, *j);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004136 CheckDoubleEq(expected, found);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004137 }
4138 }
4139}
4140
4141
4142TEST(RunChangeInt32ToFloat64_A) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004143 int32_t magic = 0x986234;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004144 BufferedRawMachineAssemblerTester<double> m;
4145 m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic)));
4146 CheckDoubleEq(static_cast<double>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004147}
4148
4149
4150TEST(RunChangeInt32ToFloat64_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004151 BufferedRawMachineAssemblerTester<double> m(MachineType::Int32());
4152 m.Return(m.ChangeInt32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004154 FOR_INT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004155}
4156
4157
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004158TEST(RunChangeUint32ToFloat64) {
4159 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32());
4160 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004161
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004162 FOR_UINT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004163}
4164
4165
Ben Murdoch097c5b22016-05-18 11:27:45 +01004166TEST(RunTruncateFloat32ToInt32) {
4167 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float32());
4168 m.Return(m.TruncateFloat32ToInt32(m.Parameter(0)));
4169 FOR_FLOAT32_INPUTS(i) {
4170 if (*i <= static_cast<float>(std::numeric_limits<int32_t>::max()) &&
4171 *i >= static_cast<float>(std::numeric_limits<int32_t>::min())) {
4172 CheckFloatEq(static_cast<int32_t>(*i), m.Call(*i));
4173 }
4174 }
4175}
4176
4177
4178TEST(RunTruncateFloat32ToUint32) {
4179 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float32());
4180 m.Return(m.TruncateFloat32ToUint32(m.Parameter(0)));
4181 {
4182 FOR_UINT32_INPUTS(i) {
4183 float input = static_cast<float>(*i);
4184 // This condition on 'input' is required because
4185 // static_cast<float>(std::numeric_limits<uint32_t>::max()) results in a
4186 // value outside uint32 range.
4187 if (input < static_cast<float>(std::numeric_limits<uint32_t>::max())) {
4188 CHECK_EQ(static_cast<uint32_t>(input), m.Call(input));
4189 }
4190 }
4191 }
4192 {
4193 FOR_FLOAT32_INPUTS(i) {
4194 if (*i <= static_cast<float>(std::numeric_limits<uint32_t>::max()) &&
4195 *i >= static_cast<float>(std::numeric_limits<uint32_t>::min())) {
4196 CheckFloatEq(static_cast<uint32_t>(*i), m.Call(*i));
4197 }
4198 }
4199 }
4200}
4201
4202
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004203TEST(RunChangeFloat64ToInt32_A) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004204 BufferedRawMachineAssemblerTester<int32_t> m;
4205 double magic = 11.1;
4206 m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic)));
4207 CHECK_EQ(static_cast<int32_t>(magic), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004208}
4209
4210
4211TEST(RunChangeFloat64ToInt32_B) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004212 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64());
4213 m.Return(m.ChangeFloat64ToInt32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004214
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004215 // Note we don't check fractional inputs, or inputs outside the range of
4216 // int32, because these Convert operators really should be Change operators.
4217 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
4218
4219 for (int32_t n = 1; n < 31; ++n) {
4220 CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n)));
4221 }
4222
4223 for (int32_t n = 1; n < 31; ++n) {
4224 CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n)));
4225 }
4226}
4227
4228
4229TEST(RunChangeFloat64ToUint32) {
4230 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
4231 m.Return(m.ChangeFloat64ToUint32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004232
4233 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004234 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004235 }
4236
4237 // Check various powers of 2.
4238 for (int32_t n = 1; n < 31; ++n) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004239 { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004240
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004241 { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004242 }
4243 // Note we don't check fractional inputs, because these Convert operators
4244 // really should be Change operators.
4245}
4246
4247
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004248TEST(RunTruncateFloat64ToFloat32) {
4249 BufferedRawMachineAssemblerTester<float> m(MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004250
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004251 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004253 FOR_FLOAT64_INPUTS(i) { CheckFloatEq(DoubleToFloat32(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004254}
4255
4256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004257TEST(RunDeadChangeFloat64ToInt32) {
4258 RawMachineAssemblerTester<int32_t> m;
4259 const int magic = 0x88abcda4;
4260 m.ChangeFloat64ToInt32(m.Float64Constant(999.78));
4261 m.Return(m.Int32Constant(magic));
4262 CHECK_EQ(magic, m.Call());
4263}
4264
4265
4266TEST(RunDeadChangeInt32ToFloat64) {
4267 RawMachineAssemblerTester<int32_t> m;
4268 const int magic = 0x8834abcd;
4269 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888));
4270 m.Return(m.Int32Constant(magic));
4271 CHECK_EQ(magic, m.Call());
4272}
4273
4274
4275TEST(RunLoopPhiInduction2) {
4276 RawMachineAssemblerTester<int32_t> m;
4277
4278 int false_val = 0x10777;
4279
4280 // x = false_val; while(false) { x++; } return x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004281 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004282 Node* false_node = m.Int32Constant(false_val);
4283 m.Goto(&header);
4284 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004285 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004286 m.Branch(m.Int32Constant(0), &body, &end);
4287 m.Bind(&body);
4288 Node* add = m.Int32Add(phi, m.Int32Constant(1));
4289 phi->ReplaceInput(1, add);
4290 m.Goto(&header);
4291 m.Bind(&end);
4292 m.Return(phi);
4293
4294 CHECK_EQ(false_val, m.Call());
4295}
4296
4297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004298TEST(RunFloatDiamond) {
4299 RawMachineAssemblerTester<int32_t> m;
4300
4301 const int magic = 99645;
4302 float buffer = 0.1f;
4303 float constant = 99.99f;
4304
4305 RawMachineLabel blocka, blockb, end;
4306 Node* k1 = m.Float32Constant(constant);
4307 Node* k2 = m.Float32Constant(0 - constant);
4308 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4309 m.Bind(&blocka);
4310 m.Goto(&end);
4311 m.Bind(&blockb);
4312 m.Goto(&end);
4313 m.Bind(&end);
4314 Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1);
4315 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer),
4316 m.IntPtrConstant(0), phi, kNoWriteBarrier);
4317 m.Return(m.Int32Constant(magic));
4318
4319 CHECK_EQ(magic, m.Call());
4320 CHECK(constant == buffer);
4321}
4322
4323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004324TEST(RunDoubleDiamond) {
4325 RawMachineAssemblerTester<int32_t> m;
4326
4327 const int magic = 99645;
4328 double buffer = 0.1;
4329 double constant = 99.99;
4330
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004331 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004332 Node* k1 = m.Float64Constant(constant);
4333 Node* k2 = m.Float64Constant(0 - constant);
4334 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4335 m.Bind(&blocka);
4336 m.Goto(&end);
4337 m.Bind(&blockb);
4338 m.Goto(&end);
4339 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004340 Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1);
4341 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4342 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004343 m.Return(m.Int32Constant(magic));
4344
4345 CHECK_EQ(magic, m.Call());
4346 CHECK_EQ(constant, buffer);
4347}
4348
4349
4350TEST(RunRefDiamond) {
4351 RawMachineAssemblerTester<int32_t> m;
4352
4353 const int magic = 99644;
4354 Handle<String> rexpected =
4355 CcTest::i_isolate()->factory()->InternalizeUtf8String("A");
4356 String* buffer;
4357
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004358 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004359 Node* k1 = m.StringConstant("A");
4360 Node* k2 = m.StringConstant("B");
4361 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4362 m.Bind(&blocka);
4363 m.Goto(&end);
4364 m.Bind(&blockb);
4365 m.Goto(&end);
4366 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004367 Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1);
4368 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer),
4369 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004370 m.Return(m.Int32Constant(magic));
4371
4372 CHECK_EQ(magic, m.Call());
4373 CHECK(rexpected->SameValue(buffer));
4374}
4375
4376
4377TEST(RunDoubleRefDiamond) {
4378 RawMachineAssemblerTester<int32_t> m;
4379
4380 const int magic = 99648;
4381 double dbuffer = 0.1;
4382 double dconstant = 99.99;
4383 Handle<String> rexpected =
4384 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX");
4385 String* rbuffer;
4386
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004387 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004388 Node* d1 = m.Float64Constant(dconstant);
4389 Node* d2 = m.Float64Constant(0 - dconstant);
4390 Node* r1 = m.StringConstant("AX");
4391 Node* r2 = m.StringConstant("BX");
4392 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4393 m.Bind(&blocka);
4394 m.Goto(&end);
4395 m.Bind(&blockb);
4396 m.Goto(&end);
4397 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004398 Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4399 Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1);
4400 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4401 m.Int32Constant(0), dphi, kNoWriteBarrier);
4402 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4403 m.Int32Constant(0), rphi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004404 m.Return(m.Int32Constant(magic));
4405
4406 CHECK_EQ(magic, m.Call());
4407 CHECK_EQ(dconstant, dbuffer);
4408 CHECK(rexpected->SameValue(rbuffer));
4409}
4410
4411
4412TEST(RunDoubleRefDoubleDiamond) {
4413 RawMachineAssemblerTester<int32_t> m;
4414
4415 const int magic = 99649;
4416 double dbuffer = 0.1;
4417 double dconstant = 99.997;
4418 Handle<String> rexpected =
4419 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD");
4420 String* rbuffer;
4421
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004422 RawMachineLabel blocka, blockb, mid, blockd, blocke, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004423 Node* d1 = m.Float64Constant(dconstant);
4424 Node* d2 = m.Float64Constant(0 - dconstant);
4425 Node* r1 = m.StringConstant("AD");
4426 Node* r2 = m.StringConstant("BD");
4427 m.Branch(m.Int32Constant(0), &blocka, &blockb);
4428 m.Bind(&blocka);
4429 m.Goto(&mid);
4430 m.Bind(&blockb);
4431 m.Goto(&mid);
4432 m.Bind(&mid);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004433 Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1);
4434 Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004435 m.Branch(m.Int32Constant(0), &blockd, &blocke);
4436
4437 m.Bind(&blockd);
4438 m.Goto(&end);
4439 m.Bind(&blocke);
4440 m.Goto(&end);
4441 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004442 Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1);
4443 Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004444
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004445 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer),
4446 m.Int32Constant(0), dphi2, kNoWriteBarrier);
4447 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer),
4448 m.Int32Constant(0), rphi2, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004449 m.Return(m.Int32Constant(magic));
4450
4451 CHECK_EQ(magic, m.Call());
4452 CHECK_EQ(dconstant, dbuffer);
4453 CHECK(rexpected->SameValue(rbuffer));
4454}
4455
4456
4457TEST(RunDoubleLoopPhi) {
4458 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004459 RawMachineLabel header, body, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004460
4461 int magic = 99773;
4462 double buffer = 0.99;
4463 double dconstant = 777.1;
4464
4465 Node* zero = m.Int32Constant(0);
4466 Node* dk = m.Float64Constant(dconstant);
4467
4468 m.Goto(&header);
4469 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004470 Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004471 phi->ReplaceInput(1, phi);
4472 m.Branch(zero, &body, &end);
4473 m.Bind(&body);
4474 m.Goto(&header);
4475 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004476 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer),
4477 m.Int32Constant(0), phi, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004478 m.Return(m.Int32Constant(magic));
4479
4480 CHECK_EQ(magic, m.Call());
4481}
4482
4483
4484TEST(RunCountToTenAccRaw) {
4485 RawMachineAssemblerTester<int32_t> m;
4486
4487 Node* zero = m.Int32Constant(0);
4488 Node* ten = m.Int32Constant(10);
4489 Node* one = m.Int32Constant(1);
4490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004491 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004492
4493 m.Goto(&header);
4494
4495 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004496 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4497 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004498 m.Goto(&body);
4499
4500 m.Bind(&body);
4501 Node* next_i = m.Int32Add(i, one);
4502 Node* next_j = m.Int32Add(j, one);
4503 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4504
4505 m.Bind(&body_cont);
4506 i->ReplaceInput(1, next_i);
4507 j->ReplaceInput(1, next_j);
4508 m.Goto(&header);
4509
4510 m.Bind(&end);
4511 m.Return(ten);
4512
4513 CHECK_EQ(10, m.Call());
4514}
4515
4516
4517TEST(RunCountToTenAccRaw2) {
4518 RawMachineAssemblerTester<int32_t> m;
4519
4520 Node* zero = m.Int32Constant(0);
4521 Node* ten = m.Int32Constant(10);
4522 Node* one = m.Int32Constant(1);
4523
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004524 RawMachineLabel header, body, body_cont, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004525
4526 m.Goto(&header);
4527
4528 m.Bind(&header);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004529 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero);
4530 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero);
4531 Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004532 m.Goto(&body);
4533
4534 m.Bind(&body);
4535 Node* next_i = m.Int32Add(i, one);
4536 Node* next_j = m.Int32Add(j, one);
4537 Node* next_k = m.Int32Add(j, one);
4538 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont);
4539
4540 m.Bind(&body_cont);
4541 i->ReplaceInput(1, next_i);
4542 j->ReplaceInput(1, next_j);
4543 k->ReplaceInput(1, next_k);
4544 m.Goto(&header);
4545
4546 m.Bind(&end);
4547 m.Return(ten);
4548
4549 CHECK_EQ(10, m.Call());
4550}
4551
4552
4553TEST(RunAddTree) {
4554 RawMachineAssemblerTester<int32_t> m;
4555 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18};
4556
4557 Node* base = m.PointerConstant(inputs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004558 Node* n0 =
4559 m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t)));
4560 Node* n1 =
4561 m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t)));
4562 Node* n2 =
4563 m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t)));
4564 Node* n3 =
4565 m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t)));
4566 Node* n4 =
4567 m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t)));
4568 Node* n5 =
4569 m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t)));
4570 Node* n6 =
4571 m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t)));
4572 Node* n7 =
4573 m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004574
4575 Node* i1 = m.Int32Add(n0, n1);
4576 Node* i2 = m.Int32Add(n2, n3);
4577 Node* i3 = m.Int32Add(n4, n5);
4578 Node* i4 = m.Int32Add(n6, n7);
4579
4580 Node* i5 = m.Int32Add(i1, i2);
4581 Node* i6 = m.Int32Add(i3, i4);
4582
4583 Node* i7 = m.Int32Add(i5, i6);
4584
4585 m.Return(i7);
4586
4587 CHECK_EQ(116, m.Call());
4588}
4589
4590
4591static const int kFloat64CompareHelperTestCases = 15;
4592static const int kFloat64CompareHelperNodeType = 4;
4593
4594static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m,
4595 int test_case, int node_type, double x,
4596 double y) {
4597 static double buffer[2];
4598 buffer[0] = x;
4599 buffer[1] = y;
4600 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases);
4601 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType);
4602 CHECK(x < y);
4603 bool load_a = node_type / 2 == 1;
4604 bool load_b = node_type % 2 == 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004605 Node* a =
4606 load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0]))
4607 : m->Float64Constant(x);
4608 Node* b =
4609 load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1]))
4610 : m->Float64Constant(y);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004611 Node* cmp = NULL;
4612 bool expected = false;
4613 switch (test_case) {
4614 // Equal tests.
4615 case 0:
4616 cmp = m->Float64Equal(a, b);
4617 expected = false;
4618 break;
4619 case 1:
4620 cmp = m->Float64Equal(a, a);
4621 expected = true;
4622 break;
4623 // LessThan tests.
4624 case 2:
4625 cmp = m->Float64LessThan(a, b);
4626 expected = true;
4627 break;
4628 case 3:
4629 cmp = m->Float64LessThan(b, a);
4630 expected = false;
4631 break;
4632 case 4:
4633 cmp = m->Float64LessThan(a, a);
4634 expected = false;
4635 break;
4636 // LessThanOrEqual tests.
4637 case 5:
4638 cmp = m->Float64LessThanOrEqual(a, b);
4639 expected = true;
4640 break;
4641 case 6:
4642 cmp = m->Float64LessThanOrEqual(b, a);
4643 expected = false;
4644 break;
4645 case 7:
4646 cmp = m->Float64LessThanOrEqual(a, a);
4647 expected = true;
4648 break;
4649 // NotEqual tests.
4650 case 8:
4651 cmp = m->Float64NotEqual(a, b);
4652 expected = true;
4653 break;
4654 case 9:
4655 cmp = m->Float64NotEqual(b, a);
4656 expected = true;
4657 break;
4658 case 10:
4659 cmp = m->Float64NotEqual(a, a);
4660 expected = false;
4661 break;
4662 // GreaterThan tests.
4663 case 11:
4664 cmp = m->Float64GreaterThan(a, a);
4665 expected = false;
4666 break;
4667 case 12:
4668 cmp = m->Float64GreaterThan(a, b);
4669 expected = false;
4670 break;
4671 // GreaterThanOrEqual tests.
4672 case 13:
4673 cmp = m->Float64GreaterThanOrEqual(a, a);
4674 expected = true;
4675 break;
4676 case 14:
4677 cmp = m->Float64GreaterThanOrEqual(b, a);
4678 expected = true;
4679 break;
4680 default:
4681 UNREACHABLE();
4682 }
4683 m->Return(cmp);
4684 return expected;
4685}
4686
4687
4688TEST(RunFloat64Compare) {
4689 double inf = V8_INFINITY;
4690 // All pairs (a1, a2) are of the form a1 < a2.
4691 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22,
4692 -inf, 0.22, 0.22, inf, -inf, inf};
4693
4694 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) {
4695 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType;
4696 node_type++) {
4697 for (size_t input = 0; input < arraysize(inputs); input += 2) {
4698 RawMachineAssemblerTester<int32_t> m;
4699 int expected = Float64CompareHelper(&m, test, node_type, inputs[input],
4700 inputs[input + 1]);
4701 CHECK_EQ(expected, m.Call());
4702 }
4703 }
4704 }
4705}
4706
4707
4708TEST(RunFloat64UnorderedCompare) {
4709 RawMachineAssemblerTester<int32_t> m;
4710
4711 const Operator* operators[] = {m.machine()->Float64Equal(),
4712 m.machine()->Float64LessThan(),
4713 m.machine()->Float64LessThanOrEqual()};
4714
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004715 double nan = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004716
4717 FOR_FLOAT64_INPUTS(i) {
4718 for (size_t o = 0; o < arraysize(operators); ++o) {
4719 for (int j = 0; j < 2; j++) {
4720 RawMachineAssemblerTester<int32_t> m;
4721 Node* a = m.Float64Constant(*i);
4722 Node* b = m.Float64Constant(nan);
4723 if (j == 1) std::swap(a, b);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004724 m.Return(m.AddNode(operators[o], a, b));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004725 CHECK_EQ(0, m.Call());
4726 }
4727 }
4728 }
4729}
4730
4731
4732TEST(RunFloat64Equal) {
4733 double input_a = 0.0;
4734 double input_b = 0.0;
4735
4736 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004737 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4738 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004739 m.Return(m.Float64Equal(a, b));
4740
4741 CompareWrapper cmp(IrOpcode::kFloat64Equal);
4742 FOR_FLOAT64_INPUTS(pl) {
4743 FOR_FLOAT64_INPUTS(pr) {
4744 input_a = *pl;
4745 input_b = *pr;
4746 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4747 CHECK_EQ(expected, m.Call());
4748 }
4749 }
4750}
4751
4752
4753TEST(RunFloat64LessThan) {
4754 double input_a = 0.0;
4755 double input_b = 0.0;
4756
4757 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004758 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64());
4759 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004760 m.Return(m.Float64LessThan(a, b));
4761
4762 CompareWrapper cmp(IrOpcode::kFloat64LessThan);
4763 FOR_FLOAT64_INPUTS(pl) {
4764 FOR_FLOAT64_INPUTS(pr) {
4765 input_a = *pl;
4766 input_b = *pr;
4767 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0;
4768 CHECK_EQ(expected, m.Call());
4769 }
4770 }
4771}
4772
4773
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004774template <typename IntType>
4775static void LoadStoreTruncation(MachineType kRepresentation) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004776 IntType input;
4777
4778 RawMachineAssemblerTester<int32_t> m;
4779 Node* a = m.LoadFromPointer(&input, kRepresentation);
4780 Node* ap1 = m.Int32Add(a, m.Int32Constant(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004781 m.StoreToPointer(&input, kRepresentation.representation(), ap1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004782 m.Return(ap1);
4783
4784 const IntType max = std::numeric_limits<IntType>::max();
4785 const IntType min = std::numeric_limits<IntType>::min();
4786
4787 // Test upper bound.
4788 input = max;
4789 CHECK_EQ(max + 1, m.Call());
4790 CHECK_EQ(min, input);
4791
4792 // Test lower bound.
4793 input = min;
4794 CHECK_EQ(static_cast<IntType>(max + 2), m.Call());
4795 CHECK_EQ(min + 1, input);
4796
4797 // Test all one byte values that are not one byte bounds.
4798 for (int i = -127; i < 127; i++) {
4799 input = i;
4800 int expected = i >= 0 ? i + 1 : max + (i - min) + 2;
4801 CHECK_EQ(static_cast<IntType>(expected), m.Call());
4802 CHECK_EQ(static_cast<IntType>(i + 1), input);
4803 }
4804}
4805
4806
4807TEST(RunLoadStoreTruncation) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004808 LoadStoreTruncation<int8_t>(MachineType::Int8());
4809 LoadStoreTruncation<int16_t>(MachineType::Int16());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004810}
4811
4812
4813static void IntPtrCompare(intptr_t left, intptr_t right) {
4814 for (int test = 0; test < 7; test++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004815 RawMachineAssemblerTester<bool> m(MachineType::Pointer(),
4816 MachineType::Pointer());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004817 Node* p0 = m.Parameter(0);
4818 Node* p1 = m.Parameter(1);
4819 Node* res = NULL;
4820 bool expected = false;
4821 switch (test) {
4822 case 0:
4823 res = m.IntPtrLessThan(p0, p1);
4824 expected = true;
4825 break;
4826 case 1:
4827 res = m.IntPtrLessThanOrEqual(p0, p1);
4828 expected = true;
4829 break;
4830 case 2:
4831 res = m.IntPtrEqual(p0, p1);
4832 expected = false;
4833 break;
4834 case 3:
4835 res = m.IntPtrGreaterThanOrEqual(p0, p1);
4836 expected = false;
4837 break;
4838 case 4:
4839 res = m.IntPtrGreaterThan(p0, p1);
4840 expected = false;
4841 break;
4842 case 5:
4843 res = m.IntPtrEqual(p0, p0);
4844 expected = true;
4845 break;
4846 case 6:
4847 res = m.IntPtrNotEqual(p0, p1);
4848 expected = true;
4849 break;
4850 default:
4851 UNREACHABLE();
4852 break;
4853 }
4854 m.Return(res);
4855 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left),
4856 reinterpret_cast<int32_t*>(right)));
4857 }
4858}
4859
4860
4861TEST(RunIntPtrCompare) {
4862 intptr_t min = std::numeric_limits<intptr_t>::min();
4863 intptr_t max = std::numeric_limits<intptr_t>::max();
4864 // An ascending chain of intptr_t
4865 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max};
4866 for (size_t i = 0; i < arraysize(inputs) - 1; i++) {
4867 IntPtrCompare(inputs[i], inputs[i + 1]);
4868 }
4869}
4870
4871
4872TEST(RunTestIntPtrArithmetic) {
4873 static const int kInputSize = 10;
4874 int32_t inputs[kInputSize];
4875 int32_t outputs[kInputSize];
4876 for (int i = 0; i < kInputSize; i++) {
4877 inputs[i] = i;
4878 outputs[i] = -1;
4879 }
4880 RawMachineAssemblerTester<int32_t*> m;
4881 Node* input = m.PointerConstant(&inputs[0]);
4882 Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004883 Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004884 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004885 m.Store(MachineRepresentation::kWord32, output,
4886 m.Load(MachineType::Int32(), input), kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004887 input = m.IntPtrAdd(input, elem_size);
4888 output = m.IntPtrSub(output, elem_size);
4889 }
4890 m.Return(input);
4891 CHECK_EQ(&inputs[kInputSize], m.Call());
4892 for (int i = 0; i < kInputSize; i++) {
4893 CHECK_EQ(i, inputs[i]);
4894 CHECK_EQ(kInputSize - i - 1, outputs[i]);
4895 }
4896}
4897
4898
4899TEST(RunSpillLotsOfThings) {
4900 static const int kInputSize = 1000;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004901 RawMachineAssemblerTester<int32_t> m;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004902 Node* accs[kInputSize];
4903 int32_t outputs[kInputSize];
4904 Node* one = m.Int32Constant(1);
4905 Node* acc = one;
4906 for (int i = 0; i < kInputSize; i++) {
4907 acc = m.Int32Add(acc, one);
4908 accs[i] = acc;
4909 }
4910 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004911 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004912 }
4913 m.Return(one);
4914 m.Call();
4915 for (int i = 0; i < kInputSize; i++) {
4916 CHECK_EQ(outputs[i], i + 2);
4917 }
4918}
4919
4920
4921TEST(RunSpillConstantsAndParameters) {
4922 static const int kInputSize = 1000;
4923 static const int32_t kBase = 987;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004924 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
4925 MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004926 int32_t outputs[kInputSize];
4927 Node* csts[kInputSize];
4928 Node* accs[kInputSize];
4929 Node* acc = m.Int32Constant(0);
4930 for (int i = 0; i < kInputSize; i++) {
4931 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i));
4932 }
4933 for (int i = 0; i < kInputSize; i++) {
4934 acc = m.Int32Add(acc, csts[i]);
4935 accs[i] = acc;
4936 }
4937 for (int i = 0; i < kInputSize; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004938 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004939 }
4940 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1))));
4941 FOR_INT32_INPUTS(i) {
4942 FOR_INT32_INPUTS(j) {
4943 int32_t expected = *i + *j;
4944 for (int k = 0; k < kInputSize; k++) {
4945 expected += kBase + k;
4946 }
4947 CHECK_EQ(expected, m.Call(*i, *j));
4948 expected = 0;
4949 for (int k = 0; k < kInputSize; k++) {
4950 expected += kBase + k;
4951 CHECK_EQ(expected, outputs[k]);
4952 }
4953 }
4954 }
4955}
4956
4957
4958TEST(RunNewSpaceConstantsInPhi) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004959 RawMachineAssemblerTester<Object*> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004960
4961 Isolate* isolate = CcTest::i_isolate();
4962 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2);
4963 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3);
4964 Node* true_node = m.HeapConstant(true_val);
4965 Node* false_node = m.HeapConstant(false_val);
4966
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004967 RawMachineLabel blocka, blockb, end;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004968 m.Branch(m.Parameter(0), &blocka, &blockb);
4969 m.Bind(&blocka);
4970 m.Goto(&end);
4971 m.Bind(&blockb);
4972 m.Goto(&end);
4973
4974 m.Bind(&end);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004975 Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004976 m.Return(phi);
4977
4978 CHECK_EQ(*false_val, m.Call(0));
4979 CHECK_EQ(*true_val, m.Call(1));
4980}
4981
4982
4983TEST(RunInt32AddWithOverflowP) {
4984 int32_t actual_val = -1;
4985 RawMachineAssemblerTester<int32_t> m;
4986 Int32BinopTester bt(&m);
4987 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
4988 Node* val = m.Projection(0, add);
4989 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004990 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004991 bt.AddReturn(ovf);
4992 FOR_INT32_INPUTS(i) {
4993 FOR_INT32_INPUTS(j) {
4994 int32_t expected_val;
4995 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
4996 CHECK_EQ(expected_ovf, bt.call(*i, *j));
4997 CHECK_EQ(expected_val, actual_val);
4998 }
4999 }
5000}
5001
5002
5003TEST(RunInt32AddWithOverflowImm) {
5004 int32_t actual_val = -1, expected_val = 0;
5005 FOR_INT32_INPUTS(i) {
5006 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005007 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005008 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5009 Node* val = m.Projection(0, add);
5010 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005011 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005012 m.Return(ovf);
5013 FOR_INT32_INPUTS(j) {
5014 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5015 CHECK_EQ(expected_ovf, m.Call(*j));
5016 CHECK_EQ(expected_val, actual_val);
5017 }
5018 }
5019 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005020 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005021 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5022 Node* val = m.Projection(0, add);
5023 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005024 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005025 m.Return(ovf);
5026 FOR_INT32_INPUTS(j) {
5027 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5028 CHECK_EQ(expected_ovf, m.Call(*j));
5029 CHECK_EQ(expected_val, actual_val);
5030 }
5031 }
5032 FOR_INT32_INPUTS(j) {
5033 RawMachineAssemblerTester<int32_t> m;
5034 Node* add =
5035 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5036 Node* val = m.Projection(0, add);
5037 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005038 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005039 m.Return(ovf);
5040 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val);
5041 CHECK_EQ(expected_ovf, m.Call());
5042 CHECK_EQ(expected_val, actual_val);
5043 }
5044 }
5045}
5046
5047
5048TEST(RunInt32AddWithOverflowInBranchP) {
5049 int constant = 911777;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005050 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005051 RawMachineAssemblerTester<int32_t> m;
5052 Int32BinopTester bt(&m);
5053 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1);
5054 Node* ovf = m.Projection(1, add);
5055 m.Branch(ovf, &blocka, &blockb);
5056 m.Bind(&blocka);
5057 bt.AddReturn(m.Int32Constant(constant));
5058 m.Bind(&blockb);
5059 Node* val = m.Projection(0, add);
5060 bt.AddReturn(val);
5061 FOR_INT32_INPUTS(i) {
5062 FOR_INT32_INPUTS(j) {
5063 int32_t expected;
5064 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant;
5065 CHECK_EQ(expected, bt.call(*i, *j));
5066 }
5067 }
5068}
5069
5070
5071TEST(RunInt32SubWithOverflowP) {
5072 int32_t actual_val = -1;
5073 RawMachineAssemblerTester<int32_t> m;
5074 Int32BinopTester bt(&m);
5075 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1);
5076 Node* val = m.Projection(0, add);
5077 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005078 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005079 bt.AddReturn(ovf);
5080 FOR_INT32_INPUTS(i) {
5081 FOR_INT32_INPUTS(j) {
5082 int32_t expected_val;
5083 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5084 CHECK_EQ(expected_ovf, bt.call(*i, *j));
5085 CHECK_EQ(expected_val, actual_val);
5086 }
5087 }
5088}
5089
5090
5091TEST(RunInt32SubWithOverflowImm) {
5092 int32_t actual_val = -1, expected_val = 0;
5093 FOR_INT32_INPUTS(i) {
5094 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005095 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005096 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0));
5097 Node* val = m.Projection(0, add);
5098 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005099 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005100 m.Return(ovf);
5101 FOR_INT32_INPUTS(j) {
5102 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5103 CHECK_EQ(expected_ovf, m.Call(*j));
5104 CHECK_EQ(expected_val, actual_val);
5105 }
5106 }
5107 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005108 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005109 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i));
5110 Node* val = m.Projection(0, add);
5111 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005112 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005113 m.Return(ovf);
5114 FOR_INT32_INPUTS(j) {
5115 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val);
5116 CHECK_EQ(expected_ovf, m.Call(*j));
5117 CHECK_EQ(expected_val, actual_val);
5118 }
5119 }
5120 FOR_INT32_INPUTS(j) {
5121 RawMachineAssemblerTester<int32_t> m;
5122 Node* add =
5123 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j));
5124 Node* val = m.Projection(0, add);
5125 Node* ovf = m.Projection(1, add);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005126 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005127 m.Return(ovf);
5128 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val);
5129 CHECK_EQ(expected_ovf, m.Call());
5130 CHECK_EQ(expected_val, actual_val);
5131 }
5132 }
5133}
5134
5135
5136TEST(RunInt32SubWithOverflowInBranchP) {
5137 int constant = 911999;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005138 RawMachineLabel blocka, blockb;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005139 RawMachineAssemblerTester<int32_t> m;
5140 Int32BinopTester bt(&m);
5141 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1);
5142 Node* ovf = m.Projection(1, sub);
5143 m.Branch(ovf, &blocka, &blockb);
5144 m.Bind(&blocka);
5145 bt.AddReturn(m.Int32Constant(constant));
5146 m.Bind(&blockb);
5147 Node* val = m.Projection(0, sub);
5148 bt.AddReturn(val);
5149 FOR_INT32_INPUTS(i) {
5150 FOR_INT32_INPUTS(j) {
5151 int32_t expected;
5152 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant;
5153 CHECK_EQ(expected, bt.call(*i, *j));
5154 }
5155 }
5156}
5157
5158
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005159TEST(RunWord64EqualInBranchP) {
5160 int64_t input;
5161 RawMachineLabel blocka, blockb;
5162 RawMachineAssemblerTester<int64_t> m;
5163 if (!m.machine()->Is64()) return;
5164 Node* value = m.LoadFromPointer(&input, MachineType::Int64());
5165 m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb);
5166 m.Bind(&blocka);
5167 m.Return(m.Int32Constant(1));
5168 m.Bind(&blockb);
5169 m.Return(m.Int32Constant(2));
5170 input = V8_INT64_C(0);
5171 CHECK_EQ(1, m.Call());
5172 input = V8_INT64_C(1);
5173 CHECK_EQ(2, m.Call());
5174 input = V8_INT64_C(0x100000000);
5175 CHECK_EQ(2, m.Call());
5176}
5177
5178
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005179TEST(RunChangeInt32ToInt64P) {
5180 if (kPointerSize < 8) return;
5181 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005182 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5183 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
5184 m.ChangeInt32ToInt64(m.Parameter(0)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005185 m.Return(m.Int32Constant(0));
5186 FOR_INT32_INPUTS(i) {
5187 int64_t expected = *i;
5188 CHECK_EQ(0, m.Call(*i));
5189 CHECK_EQ(expected, actual);
5190 }
5191}
5192
5193
5194TEST(RunChangeUint32ToUint64P) {
5195 if (kPointerSize < 8) return;
5196 int64_t actual = -1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005197 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
5198 m.StoreToPointer(&actual, MachineRepresentation::kWord64,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005199 m.ChangeUint32ToUint64(m.Parameter(0)));
5200 m.Return(m.Int32Constant(0));
5201 FOR_UINT32_INPUTS(i) {
5202 int64_t expected = static_cast<uint64_t>(*i);
5203 CHECK_EQ(0, m.Call(*i));
5204 CHECK_EQ(expected, actual);
5205 }
5206}
5207
5208
5209TEST(RunTruncateInt64ToInt32P) {
5210 if (kPointerSize < 8) return;
5211 int64_t expected = -1;
5212 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005213 m.Return(m.TruncateInt64ToInt32(
5214 m.LoadFromPointer(&expected, MachineType::Int64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005215 FOR_UINT32_INPUTS(i) {
5216 FOR_UINT32_INPUTS(j) {
5217 expected = (static_cast<uint64_t>(*j) << 32) | *i;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005218 CHECK_EQ(static_cast<int32_t>(expected), m.Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005219 }
5220 }
5221}
5222
5223
5224TEST(RunTruncateFloat64ToInt32P) {
5225 struct {
5226 double from;
5227 double raw;
5228 } kValues[] = {{0, 0},
5229 {0.5, 0},
5230 {-0.5, 0},
5231 {1.5, 1},
5232 {-1.5, -1},
5233 {5.5, 5},
5234 {-5.0, -5},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005235 {std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005236 {std::numeric_limits<double>::infinity(), 0},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005237 {-std::numeric_limits<double>::quiet_NaN(), 0},
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005238 {-std::numeric_limits<double>::infinity(), 0},
5239 {4.94065645841e-324, 0},
5240 {-4.94065645841e-324, 0},
5241 {0.9999999999999999, 0},
5242 {-0.9999999999999999, 0},
5243 {4294967296.0, 0},
5244 {-4294967296.0, 0},
5245 {9223372036854775000.0, 4294966272.0},
5246 {-9223372036854775000.0, -4294966272.0},
5247 {4.5036e+15, 372629504},
5248 {-4.5036e+15, -372629504},
5249 {287524199.5377777, 0x11234567},
5250 {-287524199.5377777, -0x11234567},
5251 {2300193596.302222, 2300193596.0},
5252 {-2300193596.302222, -2300193596.0},
5253 {4600387192.604444, 305419896},
5254 {-4600387192.604444, -305419896},
5255 {4823855600872397.0, 1737075661},
5256 {-4823855600872397.0, -1737075661},
5257 {4503603922337791.0, -1},
5258 {-4503603922337791.0, 1},
5259 {4503601774854143.0, 2147483647},
5260 {-4503601774854143.0, -2147483647},
5261 {9007207844675582.0, -2},
5262 {-9007207844675582.0, 2},
5263 {2.4178527921507624e+24, -536870912},
5264 {-2.4178527921507624e+24, 536870912},
5265 {2.417853945072267e+24, -536870912},
5266 {-2.417853945072267e+24, 536870912},
5267 {4.8357055843015248e+24, -1073741824},
5268 {-4.8357055843015248e+24, 1073741824},
5269 {4.8357078901445341e+24, -1073741824},
5270 {-4.8357078901445341e+24, 1073741824},
5271 {2147483647.0, 2147483647.0},
5272 {-2147483648.0, -2147483648.0},
5273 {9.6714111686030497e+24, -2147483648.0},
5274 {-9.6714111686030497e+24, -2147483648.0},
5275 {9.6714157802890681e+24, -2147483648.0},
5276 {-9.6714157802890681e+24, -2147483648.0},
5277 {1.9342813113834065e+25, 2147483648.0},
5278 {-1.9342813113834065e+25, 2147483648.0},
5279 {3.868562622766813e+25, 0},
5280 {-3.868562622766813e+25, 0},
5281 {1.7976931348623157e+308, 0},
5282 {-1.7976931348623157e+308, 0}};
5283 double input = -1.0;
5284 RawMachineAssemblerTester<int32_t> m;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005285 m.Return(m.TruncateFloat64ToInt32(
5286 TruncationMode::kJavaScript,
5287 m.LoadFromPointer(&input, MachineType::Float64())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005288 for (size_t i = 0; i < arraysize(kValues); ++i) {
5289 input = kValues[i].from;
5290 uint64_t expected = static_cast<int64_t>(kValues[i].raw);
5291 CHECK_EQ(static_cast<int>(expected), m.Call());
5292 }
5293}
5294
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005295
5296TEST(RunChangeFloat32ToFloat64) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005297 BufferedRawMachineAssemblerTester<double> m(MachineType::Float32());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005299 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005300
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005301 FOR_FLOAT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005302}
5303
5304
5305TEST(RunFloat32Constant) {
5306 FOR_FLOAT32_INPUTS(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005307 BufferedRawMachineAssemblerTester<float> m;
5308 m.Return(m.Float32Constant(*i));
5309 CheckFloatEq(*i, m.Call());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005310 }
5311}
5312
5313
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005314TEST(RunFloat64ExtractLowWord32) {
5315 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5316 m.Return(m.Float64ExtractLowWord32(m.Parameter(0)));
5317 FOR_FLOAT64_INPUTS(i) {
5318 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i));
5319 CHECK_EQ(expected, m.Call(*i));
5320 }
5321}
5322
5323
5324TEST(RunFloat64ExtractHighWord32) {
5325 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64());
5326 m.Return(m.Float64ExtractHighWord32(m.Parameter(0)));
5327 FOR_FLOAT64_INPUTS(i) {
5328 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32);
5329 CHECK_EQ(expected, m.Call(*i));
5330 }
5331}
5332
5333
5334TEST(RunFloat64InsertLowWord32) {
5335 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5336 MachineType::Int32());
5337 m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1)));
5338 FOR_FLOAT64_INPUTS(i) {
5339 FOR_INT32_INPUTS(j) {
5340 double expected = bit_cast<double>(
5341 (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) |
5342 (static_cast<uint64_t>(bit_cast<uint32_t>(*j))));
5343 CheckDoubleEq(expected, m.Call(*i, *j));
5344 }
5345 }
5346}
5347
5348
5349TEST(RunFloat64InsertHighWord32) {
5350 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(),
5351 MachineType::Uint32());
5352 m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1)));
5353 FOR_FLOAT64_INPUTS(i) {
5354 FOR_UINT32_INPUTS(j) {
5355 uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) |
5356 (static_cast<uint64_t>(*j) << 32);
5357
5358 CheckDoubleEq(bit_cast<double>(expected), m.Call(*i, *j));
5359 }
5360 }
5361}
5362
5363
5364TEST(RunFloat32Abs) {
5365 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5366 m.Return(m.Float32Abs(m.Parameter(0)));
5367 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::abs(*i), m.Call(*i)); }
5368}
5369
5370
5371TEST(RunFloat64Abs) {
5372 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5373 m.Return(m.Float64Abs(m.Parameter(0)));
5374 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::abs(*i), m.Call(*i)); }
5375}
5376
5377
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005378static double two_30 = 1 << 30; // 2^30 is a smi boundary.
5379static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary.
5380static double kValues[] = {0.1,
5381 0.2,
5382 0.49999999999999994,
5383 0.5,
5384 0.7,
5385 1.0 - std::numeric_limits<double>::epsilon(),
5386 -0.1,
5387 -0.49999999999999994,
5388 -0.5,
5389 -0.7,
5390 1.1,
5391 1.0 + std::numeric_limits<double>::epsilon(),
5392 1.5,
5393 1.7,
5394 -1,
5395 -1 + std::numeric_limits<double>::epsilon(),
5396 -1 - std::numeric_limits<double>::epsilon(),
5397 -1.1,
5398 -1.5,
5399 -1.7,
5400 std::numeric_limits<double>::min(),
5401 -std::numeric_limits<double>::min(),
5402 std::numeric_limits<double>::max(),
5403 -std::numeric_limits<double>::max(),
5404 std::numeric_limits<double>::infinity(),
5405 -std::numeric_limits<double>::infinity(),
5406 two_30,
5407 two_30 + 0.1,
5408 two_30 + 0.5,
5409 two_30 + 0.7,
5410 two_30 - 1,
5411 two_30 - 1 + 0.1,
5412 two_30 - 1 + 0.5,
5413 two_30 - 1 + 0.7,
5414 -two_30,
5415 -two_30 + 0.1,
5416 -two_30 + 0.5,
5417 -two_30 + 0.7,
5418 -two_30 + 1,
5419 -two_30 + 1 + 0.1,
5420 -two_30 + 1 + 0.5,
5421 -two_30 + 1 + 0.7,
5422 two_52,
5423 two_52 + 0.1,
5424 two_52 + 0.5,
5425 two_52 + 0.5,
5426 two_52 + 0.7,
5427 two_52 + 0.7,
5428 two_52 - 1,
5429 two_52 - 1 + 0.1,
5430 two_52 - 1 + 0.5,
5431 two_52 - 1 + 0.7,
5432 -two_52,
5433 -two_52 + 0.1,
5434 -two_52 + 0.5,
5435 -two_52 + 0.7,
5436 -two_52 + 1,
5437 -two_52 + 1 + 0.1,
5438 -two_52 + 1 + 0.5,
5439 -two_52 + 1 + 0.7,
5440 two_30,
5441 two_30 - 0.1,
5442 two_30 - 0.5,
5443 two_30 - 0.7,
5444 two_30 - 1,
5445 two_30 - 1 - 0.1,
5446 two_30 - 1 - 0.5,
5447 two_30 - 1 - 0.7,
5448 -two_30,
5449 -two_30 - 0.1,
5450 -two_30 - 0.5,
5451 -two_30 - 0.7,
5452 -two_30 + 1,
5453 -two_30 + 1 - 0.1,
5454 -two_30 + 1 - 0.5,
5455 -two_30 + 1 - 0.7,
5456 two_52,
5457 two_52 - 0.1,
5458 two_52 - 0.5,
5459 two_52 - 0.5,
5460 two_52 - 0.7,
5461 two_52 - 0.7,
5462 two_52 - 1,
5463 two_52 - 1 - 0.1,
5464 two_52 - 1 - 0.5,
5465 two_52 - 1 - 0.7,
5466 -two_52,
5467 -two_52 - 0.1,
5468 -two_52 - 0.5,
5469 -two_52 - 0.7,
5470 -two_52 + 1,
5471 -two_52 + 1 - 0.1,
5472 -two_52 + 1 - 0.5,
5473 -two_52 + 1 - 0.7};
5474
5475
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005476TEST(RunFloat32RoundDown) {
5477 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5478 if (!m.machine()->Float32RoundDown().IsSupported()) return;
5479
5480 m.Return(m.Float32RoundDown(m.Parameter(0)));
5481
5482 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), m.Call(*i)); }
5483}
5484
5485
5486TEST(RunFloat64RoundDown1) {
5487 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5488 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5489
5490 m.Return(m.Float64RoundDown(m.Parameter(0)));
5491
5492 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), m.Call(*i)); }
5493}
5494
5495
5496TEST(RunFloat64RoundDown2) {
5497 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5498 if (!m.machine()->Float64RoundDown().IsSupported()) return;
5499 m.Return(m.Float64Sub(m.Float64Constant(-0.0),
5500 m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0),
5501 m.Parameter(0)))));
5502
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005503 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005504 CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005505 }
5506}
5507
5508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005509TEST(RunFloat32RoundUp) {
5510 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5511 if (!m.machine()->Float32RoundUp().IsSupported()) return;
5512 m.Return(m.Float32RoundUp(m.Parameter(0)));
5513
5514 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), m.Call(*i)); }
5515}
5516
5517
5518TEST(RunFloat64RoundUp) {
5519 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5520 if (!m.machine()->Float64RoundUp().IsSupported()) return;
5521 m.Return(m.Float64RoundUp(m.Parameter(0)));
5522
5523 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), m.Call(*i)); }
5524}
5525
5526
5527TEST(RunFloat32RoundTiesEven) {
5528 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5529 if (!m.machine()->Float32RoundTiesEven().IsSupported()) return;
5530 m.Return(m.Float32RoundTiesEven(m.Parameter(0)));
5531
5532 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), m.Call(*i)); }
5533}
5534
5535
5536TEST(RunFloat64RoundTiesEven) {
5537 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5538 if (!m.machine()->Float64RoundTiesEven().IsSupported()) return;
5539 m.Return(m.Float64RoundTiesEven(m.Parameter(0)));
5540
5541 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), m.Call(*i)); }
5542}
5543
5544
5545TEST(RunFloat32RoundTruncate) {
5546 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
5547 if (!m.machine()->Float32RoundTruncate().IsSupported()) return;
5548
5549 m.Return(m.Float32RoundTruncate(m.Parameter(0)));
5550
5551 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), m.Call(*i)); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005552}
5553
5554
5555TEST(RunFloat64RoundTruncate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005556 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5557 if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
5558 m.Return(m.Float64RoundTruncate(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005559 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005560 CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005561 }
5562}
5563
5564
5565TEST(RunFloat64RoundTiesAway) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005566 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
5567 if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
5568 m.Return(m.Float64RoundTiesAway(m.Parameter(0)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005569 for (size_t i = 0; i < arraysize(kValues); ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005570 CHECK_EQ(round(kValues[i]), m.Call(kValues[i]));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005571 }
5572}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005573
5574
5575#if !USE_SIMULATOR
5576
5577namespace {
5578
5579int32_t const kMagicFoo0 = 0xdeadbeef;
5580
5581
5582int32_t foo0() { return kMagicFoo0; }
5583
5584
5585int32_t foo1(int32_t x) { return x; }
5586
5587
5588int32_t foo2(int32_t x, int32_t y) { return x - y; }
5589
5590
5591int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
5592 int32_t g, int32_t h) {
5593 return a + b + c + d + e + f + g + h;
5594}
5595
5596} // namespace
5597
5598
5599TEST(RunCallCFunction0) {
5600 auto* foo0_ptr = &foo0;
5601 RawMachineAssemblerTester<int32_t> m;
5602 Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer());
5603 m.Return(m.CallCFunction0(MachineType::Int32(), function));
5604 CHECK_EQ(kMagicFoo0, m.Call());
5605}
5606
5607
5608TEST(RunCallCFunction1) {
5609 auto* foo1_ptr = &foo1;
5610 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5611 Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer());
5612 m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(),
5613 function, m.Parameter(0)));
5614 FOR_INT32_INPUTS(i) {
5615 int32_t const expected = *i;
5616 CHECK_EQ(expected, m.Call(expected));
5617 }
5618}
5619
5620
5621TEST(RunCallCFunction2) {
5622 auto* foo2_ptr = &foo2;
5623 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
5624 MachineType::Int32());
5625 Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer());
5626 m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(),
5627 MachineType::Int32(), function, m.Parameter(0),
5628 m.Parameter(1)));
5629 FOR_INT32_INPUTS(i) {
5630 int32_t const x = *i;
5631 FOR_INT32_INPUTS(j) {
5632 int32_t const y = *j;
5633 CHECK_EQ(x - y, m.Call(x, y));
5634 }
5635 }
5636}
5637
5638
5639TEST(RunCallCFunction8) {
5640 auto* foo8_ptr = &foo8;
5641 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5642 Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer());
5643 Node* param = m.Parameter(0);
5644 m.Return(m.CallCFunction8(
5645 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5646 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5647 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
5648 function, param, param, param, param, param, param, param, param));
5649 FOR_INT32_INPUTS(i) {
5650 int32_t const x = *i;
5651 CHECK_EQ(x * 8, m.Call(x));
5652 }
5653}
5654#endif // USE_SIMULATOR
5655
Ben Murdoch097c5b22016-05-18 11:27:45 +01005656template <typename T>
5657void TestExternalReferenceFunction(
5658 BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
5659 T (*comparison)(T)) {
5660 T parameter;
5661
5662 Node* function = m->ExternalConstant(ref);
5663 m->CallCFunction1(MachineType::Pointer(), MachineType::Pointer(), function,
5664 m->PointerConstant(&parameter));
5665 m->Return(m->Int32Constant(4356));
5666 FOR_FLOAT64_INPUTS(i) {
5667 parameter = *i;
5668 m->Call();
5669 CheckDoubleEq(comparison(*i), parameter);
5670 }
5671}
5672
5673TEST(RunCallExternalReferenceF32Trunc) {
5674 BufferedRawMachineAssemblerTester<int32_t> m;
5675 ExternalReference ref =
5676 ExternalReference::f32_trunc_wrapper_function(m.isolate());
5677 TestExternalReferenceFunction<float>(&m, ref, truncf);
5678}
5679
5680TEST(RunCallExternalReferenceF32Floor) {
5681 BufferedRawMachineAssemblerTester<int32_t> m;
5682 ExternalReference ref =
5683 ExternalReference::f32_floor_wrapper_function(m.isolate());
5684 TestExternalReferenceFunction<float>(&m, ref, floorf);
5685}
5686
5687TEST(RunCallExternalReferenceF32Ceil) {
5688 BufferedRawMachineAssemblerTester<int32_t> m;
5689 ExternalReference ref =
5690 ExternalReference::f32_ceil_wrapper_function(m.isolate());
5691 TestExternalReferenceFunction<float>(&m, ref, ceilf);
5692}
5693
5694TEST(RunCallExternalReferenceF32RoundTiesEven) {
5695 BufferedRawMachineAssemblerTester<int32_t> m;
5696 ExternalReference ref =
5697 ExternalReference::f32_nearest_int_wrapper_function(m.isolate());
5698 TestExternalReferenceFunction<float>(&m, ref, nearbyintf);
5699}
5700
5701TEST(RunCallExternalReferenceF64Trunc) {
5702 BufferedRawMachineAssemblerTester<int32_t> m;
5703 ExternalReference ref =
5704 ExternalReference::f64_trunc_wrapper_function(m.isolate());
5705 TestExternalReferenceFunction<double>(&m, ref, trunc);
5706}
5707
5708TEST(RunCallExternalReferenceF64Floor) {
5709 BufferedRawMachineAssemblerTester<int32_t> m;
5710 ExternalReference ref =
5711 ExternalReference::f64_floor_wrapper_function(m.isolate());
5712 TestExternalReferenceFunction<double>(&m, ref, floor);
5713}
5714
5715TEST(RunCallExternalReferenceF64Ceil) {
5716 BufferedRawMachineAssemblerTester<int32_t> m;
5717 ExternalReference ref =
5718 ExternalReference::f64_ceil_wrapper_function(m.isolate());
5719 TestExternalReferenceFunction<double>(&m, ref, ceil);
5720}
5721
5722TEST(RunCallExternalReferenceF64RoundTiesEven) {
5723 BufferedRawMachineAssemblerTester<int32_t> m;
5724 ExternalReference ref =
5725 ExternalReference::f64_nearest_int_wrapper_function(m.isolate());
5726 TestExternalReferenceFunction<double>(&m, ref, nearbyint);
5727}
5728
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005729#if V8_TARGET_ARCH_64_BIT
5730// TODO(titzer): run int64 tests on all platforms when supported.
5731TEST(RunCheckedLoadInt64) {
5732 int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL};
5733 RawMachineAssemblerTester<int64_t> m(MachineType::Int32());
5734 Node* base = m.PointerConstant(buffer);
5735 Node* index = m.Parameter(0);
5736 Node* length = m.Int32Constant(16);
5737 Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base,
5738 index, length);
5739 m.Return(load);
5740
5741 CHECK_EQ(buffer[0], m.Call(0));
5742 CHECK_EQ(buffer[1], m.Call(8));
5743 CHECK_EQ(0, m.Call(16));
5744}
5745
5746
5747TEST(RunCheckedStoreInt64) {
5748 const int64_t write = 0x5566778899aabbLL;
5749 const int64_t before = 0x33bbccddeeff0011LL;
5750 int64_t buffer[] = {before, before};
5751 RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
5752 Node* base = m.PointerConstant(buffer);
5753 Node* index = m.Parameter(0);
5754 Node* length = m.Int32Constant(16);
5755 Node* value = m.Int64Constant(write);
5756 Node* store =
5757 m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base,
5758 index, length, value);
5759 USE(store);
5760 m.Return(m.Int32Constant(11));
5761
5762 CHECK_EQ(11, m.Call(16));
5763 CHECK_EQ(before, buffer[0]);
5764 CHECK_EQ(before, buffer[1]);
5765
5766 CHECK_EQ(11, m.Call(0));
5767 CHECK_EQ(write, buffer[0]);
5768 CHECK_EQ(before, buffer[1]);
5769
5770 CHECK_EQ(11, m.Call(8));
5771 CHECK_EQ(write, buffer[0]);
5772 CHECK_EQ(write, buffer[1]);
5773}
5774
5775
5776TEST(RunBitcastInt64ToFloat64) {
5777 int64_t input = 1;
5778 double output = 0.0;
5779 RawMachineAssemblerTester<int32_t> m;
5780 m.StoreToPointer(
5781 &output, MachineRepresentation::kFloat64,
5782 m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64())));
5783 m.Return(m.Int32Constant(11));
5784 FOR_INT64_INPUTS(i) {
5785 input = *i;
5786 CHECK_EQ(11, m.Call());
5787 double expected = bit_cast<double>(input);
5788 CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output));
5789 }
5790}
5791
5792
5793TEST(RunBitcastFloat64ToInt64) {
5794 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5795
5796 m.Return(m.BitcastFloat64ToInt64(m.Parameter(0)));
5797 FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); }
5798}
5799
5800
5801TEST(RunTryTruncateFloat32ToInt64WithoutCheck) {
5802 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5803 m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0)));
5804
5805 FOR_INT64_INPUTS(i) {
5806 float input = static_cast<float>(*i);
5807 if (input < static_cast<float>(INT64_MAX) &&
5808 input >= static_cast<float>(INT64_MIN)) {
5809 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5810 }
5811 }
5812}
5813
5814
5815TEST(RunTryTruncateFloat32ToInt64WithCheck) {
5816 int64_t success = 0;
5817 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32());
5818 Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0));
5819 Node* val = m.Projection(0, trunc);
5820 Node* check = m.Projection(1, trunc);
5821 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5822 m.Return(val);
5823
5824 FOR_FLOAT32_INPUTS(i) {
5825 if (*i < static_cast<float>(INT64_MAX) &&
5826 *i >= static_cast<float>(INT64_MIN)) {
5827 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5828 CHECK_NE(0, success);
5829 } else {
5830 m.Call(*i);
5831 CHECK_EQ(0, success);
5832 }
5833 }
5834}
5835
5836
5837TEST(RunTryTruncateFloat64ToInt64WithoutCheck) {
5838 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5839 m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0)));
5840
5841 FOR_INT64_INPUTS(i) {
5842 double input = static_cast<double>(*i);
5843 CHECK_EQ(static_cast<int64_t>(input), m.Call(input));
5844 }
5845}
5846
5847
5848TEST(RunTryTruncateFloat64ToInt64WithCheck) {
5849 int64_t success = 0;
5850 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5851 Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0));
5852 Node* val = m.Projection(0, trunc);
5853 Node* check = m.Projection(1, trunc);
5854 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5855 m.Return(val);
5856
5857 FOR_FLOAT64_INPUTS(i) {
5858 if (*i < static_cast<double>(INT64_MAX) &&
5859 *i >= static_cast<double>(INT64_MIN)) {
5860 // Conversions within this range should succeed.
5861 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i));
5862 CHECK_NE(0, success);
5863 } else {
5864 m.Call(*i);
5865 CHECK_EQ(0, success);
5866 }
5867 }
5868}
5869
5870
5871TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
5872 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5873 m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
5874
5875 FOR_UINT64_INPUTS(i) {
5876 float input = static_cast<float>(*i);
5877 // This condition on 'input' is required because
5878 // static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
5879 if (input < static_cast<float>(UINT64_MAX)) {
5880 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5881 }
5882 }
5883}
5884
5885
5886TEST(RunTryTruncateFloat32ToUint64WithCheck) {
5887 int64_t success = 0;
5888 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
5889 Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0));
5890 Node* val = m.Projection(0, trunc);
5891 Node* check = m.Projection(1, trunc);
5892 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5893 m.Return(val);
5894
5895 FOR_FLOAT32_INPUTS(i) {
5896 if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
5897 // Conversions within this range should succeed.
5898 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5899 CHECK_NE(0, success);
5900 } else {
5901 m.Call(*i);
5902 CHECK_EQ(0, success);
5903 }
5904 }
5905}
5906
5907
5908TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
5909 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64());
5910 m.Return(m.TruncateFloat64ToUint64(m.Parameter(0)));
5911
5912 FOR_UINT64_INPUTS(j) {
5913 double input = static_cast<double>(*j);
5914
5915 if (input < static_cast<float>(UINT64_MAX)) {
5916 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
5917 }
5918 }
5919}
5920
5921
5922TEST(RunTryTruncateFloat64ToUint64WithCheck) {
5923 int64_t success = 0;
5924 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64());
5925 Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0));
5926 Node* val = m.Projection(0, trunc);
5927 Node* check = m.Projection(1, trunc);
5928 m.StoreToPointer(&success, MachineRepresentation::kWord64, check);
5929 m.Return(val);
5930
5931 FOR_FLOAT64_INPUTS(i) {
5932 if (*i < 18446744073709551616.0 && *i > -1) {
5933 // Conversions within this range should succeed.
5934 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
5935 CHECK_NE(0, success);
5936 } else {
5937 m.Call(*i);
5938 CHECK_EQ(0, success);
5939 }
5940 }
5941}
5942
5943
5944TEST(RunRoundInt64ToFloat32) {
5945 BufferedRawMachineAssemblerTester<float> m(MachineType::Int64());
5946 m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
5947 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
5948}
5949
5950
5951TEST(RunRoundInt64ToFloat64) {
5952 BufferedRawMachineAssemblerTester<double> m(MachineType::Int64());
5953 m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
5954 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); }
5955}
5956
5957
5958TEST(RunRoundUint64ToFloat64) {
5959 struct {
5960 uint64_t input;
5961 uint64_t expected;
5962 } values[] = {{0x0, 0x0},
5963 {0x1, 0x3ff0000000000000},
5964 {0xffffffff, 0x41efffffffe00000},
5965 {0x1b09788b, 0x41bb09788b000000},
5966 {0x4c5fce8, 0x419317f3a0000000},
5967 {0xcc0de5bf, 0x41e981bcb7e00000},
5968 {0x2, 0x4000000000000000},
5969 {0x3, 0x4008000000000000},
5970 {0x4, 0x4010000000000000},
5971 {0x5, 0x4014000000000000},
5972 {0x8, 0x4020000000000000},
5973 {0x9, 0x4022000000000000},
5974 {0xffffffffffffffff, 0x43f0000000000000},
5975 {0xfffffffffffffffe, 0x43f0000000000000},
5976 {0xfffffffffffffffd, 0x43f0000000000000},
5977 {0x100000000, 0x41f0000000000000},
5978 {0xffffffff00000000, 0x43efffffffe00000},
5979 {0x1b09788b00000000, 0x43bb09788b000000},
5980 {0x4c5fce800000000, 0x439317f3a0000000},
5981 {0xcc0de5bf00000000, 0x43e981bcb7e00000},
5982 {0x200000000, 0x4200000000000000},
5983 {0x300000000, 0x4208000000000000},
5984 {0x400000000, 0x4210000000000000},
5985 {0x500000000, 0x4214000000000000},
5986 {0x800000000, 0x4220000000000000},
5987 {0x900000000, 0x4222000000000000},
5988 {0x273a798e187937a3, 0x43c39d3cc70c3c9c},
5989 {0xece3af835495a16b, 0x43ed9c75f06a92b4},
5990 {0xb668ecc11223344, 0x43a6cd1d98224467},
5991 {0x9e, 0x4063c00000000000},
5992 {0x43, 0x4050c00000000000},
5993 {0xaf73, 0x40e5ee6000000000},
5994 {0x116b, 0x40b16b0000000000},
5995 {0x658ecc, 0x415963b300000000},
5996 {0x2b3b4c, 0x41459da600000000},
5997 {0x88776655, 0x41e10eeccaa00000},
5998 {0x70000000, 0x41dc000000000000},
5999 {0x7200000, 0x419c800000000000},
6000 {0x7fffffff, 0x41dfffffffc00000},
6001 {0x56123761, 0x41d5848dd8400000},
6002 {0x7fffff00, 0x41dfffffc0000000},
6003 {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc},
6004 {0x80000000eeeeeeee, 0x43e00000001dddde},
6005 {0x88888888dddddddd, 0x43e11111111bbbbc},
6006 {0xa0000000dddddddd, 0x43e40000001bbbbc},
6007 {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555},
6008 {0xe0000000aaaaaaaa, 0x43ec000000155555},
6009 {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde},
6010 {0xfffffffdeeeeeeee, 0x43efffffffbdddde},
6011 {0xf0000000dddddddd, 0x43ee0000001bbbbc},
6012 {0x7fffffdddddddd, 0x435ffffff7777777},
6013 {0x3fffffaaaaaaaa, 0x434fffffd5555555},
6014 {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa},
6015 {0xfffff, 0x412ffffe00000000},
6016 {0x7ffff, 0x411ffffc00000000},
6017 {0x3ffff, 0x410ffff800000000},
6018 {0x1ffff, 0x40fffff000000000},
6019 {0xffff, 0x40efffe000000000},
6020 {0x7fff, 0x40dfffc000000000},
6021 {0x3fff, 0x40cfff8000000000},
6022 {0x1fff, 0x40bfff0000000000},
6023 {0xfff, 0x40affe0000000000},
6024 {0x7ff, 0x409ffc0000000000},
6025 {0x3ff, 0x408ff80000000000},
6026 {0x1ff, 0x407ff00000000000},
6027 {0x3fffffffffff, 0x42cfffffffffff80},
6028 {0x1fffffffffff, 0x42bfffffffffff00},
6029 {0xfffffffffff, 0x42affffffffffe00},
6030 {0x7ffffffffff, 0x429ffffffffffc00},
6031 {0x3ffffffffff, 0x428ffffffffff800},
6032 {0x1ffffffffff, 0x427ffffffffff000},
6033 {0x8000008000000000, 0x43e0000010000000},
6034 {0x8000008000000001, 0x43e0000010000000},
6035 {0x8000000000000400, 0x43e0000000000000},
6036 {0x8000000000000401, 0x43e0000000000001}};
6037
6038 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64());
6039 m.Return(m.RoundUint64ToFloat64(m.Parameter(0)));
6040
6041 for (size_t i = 0; i < arraysize(values); i++) {
6042 CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input));
6043 }
6044}
6045
6046
6047TEST(RunRoundUint64ToFloat32) {
6048 struct {
6049 uint64_t input;
6050 uint32_t expected;
6051 } values[] = {{0x0, 0x0},
6052 {0x1, 0x3f800000},
6053 {0xffffffff, 0x4f800000},
6054 {0x1b09788b, 0x4dd84bc4},
6055 {0x4c5fce8, 0x4c98bf9d},
6056 {0xcc0de5bf, 0x4f4c0de6},
6057 {0x2, 0x40000000},
6058 {0x3, 0x40400000},
6059 {0x4, 0x40800000},
6060 {0x5, 0x40a00000},
6061 {0x8, 0x41000000},
6062 {0x9, 0x41100000},
6063 {0xffffffffffffffff, 0x5f800000},
6064 {0xfffffffffffffffe, 0x5f800000},
6065 {0xfffffffffffffffd, 0x5f800000},
6066 {0x0, 0x0},
6067 {0x100000000, 0x4f800000},
6068 {0xffffffff00000000, 0x5f800000},
6069 {0x1b09788b00000000, 0x5dd84bc4},
6070 {0x4c5fce800000000, 0x5c98bf9d},
6071 {0xcc0de5bf00000000, 0x5f4c0de6},
6072 {0x200000000, 0x50000000},
6073 {0x300000000, 0x50400000},
6074 {0x400000000, 0x50800000},
6075 {0x500000000, 0x50a00000},
6076 {0x800000000, 0x51000000},
6077 {0x900000000, 0x51100000},
6078 {0x273a798e187937a3, 0x5e1ce9e6},
6079 {0xece3af835495a16b, 0x5f6ce3b0},
6080 {0xb668ecc11223344, 0x5d3668ed},
6081 {0x9e, 0x431e0000},
6082 {0x43, 0x42860000},
6083 {0xaf73, 0x472f7300},
6084 {0x116b, 0x458b5800},
6085 {0x658ecc, 0x4acb1d98},
6086 {0x2b3b4c, 0x4a2ced30},
6087 {0x88776655, 0x4f087766},
6088 {0x70000000, 0x4ee00000},
6089 {0x7200000, 0x4ce40000},
6090 {0x7fffffff, 0x4f000000},
6091 {0x56123761, 0x4eac246f},
6092 {0x7fffff00, 0x4efffffe},
6093 {0x761c4761eeeeeeee, 0x5eec388f},
6094 {0x80000000eeeeeeee, 0x5f000000},
6095 {0x88888888dddddddd, 0x5f088889},
6096 {0xa0000000dddddddd, 0x5f200000},
6097 {0xddddddddaaaaaaaa, 0x5f5dddde},
6098 {0xe0000000aaaaaaaa, 0x5f600000},
6099 {0xeeeeeeeeeeeeeeee, 0x5f6eeeef},
6100 {0xfffffffdeeeeeeee, 0x5f800000},
6101 {0xf0000000dddddddd, 0x5f700000},
6102 {0x7fffffdddddddd, 0x5b000000},
6103 {0x3fffffaaaaaaaa, 0x5a7fffff},
6104 {0x1fffffaaaaaaaa, 0x59fffffd},
6105 {0xfffff, 0x497ffff0},
6106 {0x7ffff, 0x48ffffe0},
6107 {0x3ffff, 0x487fffc0},
6108 {0x1ffff, 0x47ffff80},
6109 {0xffff, 0x477fff00},
6110 {0x7fff, 0x46fffe00},
6111 {0x3fff, 0x467ffc00},
6112 {0x1fff, 0x45fff800},
6113 {0xfff, 0x457ff000},
6114 {0x7ff, 0x44ffe000},
6115 {0x3ff, 0x447fc000},
6116 {0x1ff, 0x43ff8000},
6117 {0x3fffffffffff, 0x56800000},
6118 {0x1fffffffffff, 0x56000000},
6119 {0xfffffffffff, 0x55800000},
6120 {0x7ffffffffff, 0x55000000},
6121 {0x3ffffffffff, 0x54800000},
6122 {0x1ffffffffff, 0x54000000},
6123 {0x8000008000000000, 0x5f000000},
6124 {0x8000008000000001, 0x5f000001},
6125 {0x8000000000000400, 0x5f000000},
6126 {0x8000000000000401, 0x5f000000}};
6127
6128 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64());
6129 m.Return(m.RoundUint64ToFloat32(m.Parameter(0)));
6130
6131 for (size_t i = 0; i < arraysize(values); i++) {
6132 CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input));
6133 }
6134}
6135
6136
6137#endif
6138
6139
6140TEST(RunBitcastFloat32ToInt32) {
6141 float input = 32.25;
6142 RawMachineAssemblerTester<int32_t> m;
6143 m.Return(m.BitcastFloat32ToInt32(
6144 m.LoadFromPointer(&input, MachineType::Float32())));
6145 FOR_FLOAT32_INPUTS(i) {
6146 input = *i;
6147 int32_t expected = bit_cast<int32_t>(input);
6148 CHECK_EQ(expected, m.Call());
6149 }
6150}
6151
6152
Ben Murdoch097c5b22016-05-18 11:27:45 +01006153TEST(RunRoundInt32ToFloat32) {
6154 BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
6155 m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
6156 FOR_INT32_INPUTS(i) {
6157 volatile float expected = static_cast<float>(*i);
6158 CHECK_EQ(expected, m.Call(*i));
6159 }
6160}
6161
6162
6163TEST(RunRoundUint32ToFloat32) {
6164 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint32());
6165 m.Return(m.RoundUint32ToFloat32(m.Parameter(0)));
6166 FOR_UINT32_INPUTS(i) {
6167 volatile float expected = static_cast<float>(*i);
6168 CHECK_EQ(expected, m.Call(*i));
6169 }
6170}
6171
6172
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006173TEST(RunBitcastInt32ToFloat32) {
6174 int32_t input = 1;
6175 float output = 0.0;
6176 RawMachineAssemblerTester<int32_t> m;
6177 m.StoreToPointer(
6178 &output, MachineRepresentation::kFloat32,
6179 m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32())));
6180 m.Return(m.Int32Constant(11));
6181 FOR_INT32_INPUTS(i) {
6182 input = *i;
6183 CHECK_EQ(11, m.Call());
6184 float expected = bit_cast<float>(input);
6185 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output));
6186 }
6187}
6188
6189
6190TEST(RunComputedCodeObject) {
6191 GraphBuilderTester<int32_t> a;
6192 a.Return(a.Int32Constant(33));
6193 a.End();
6194 Handle<Code> code_a = a.GetCode();
6195
6196 GraphBuilderTester<int32_t> b;
6197 b.Return(b.Int32Constant(44));
6198 b.End();
6199 Handle<Code> code_b = b.GetCode();
6200
6201 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6202 RawMachineLabel tlabel;
6203 RawMachineLabel flabel;
6204 RawMachineLabel merge;
6205 r.Branch(r.Parameter(0), &tlabel, &flabel);
6206 r.Bind(&tlabel);
6207 Node* fa = r.HeapConstant(code_a);
6208 r.Goto(&merge);
6209 r.Bind(&flabel);
6210 Node* fb = r.HeapConstant(code_b);
6211 r.Goto(&merge);
6212 r.Bind(&merge);
6213 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6214
6215 // TODO(titzer): all this descriptor hackery is just to call the above
6216 // functions as code objects instead of direct addresses.
6217 CSignature0<int32_t> sig;
6218 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig);
6219 LinkageLocation ret[] = {c->GetReturnLocation(0)};
6220 Signature<LinkageLocation> loc(1, 0, ret);
6221 CallDescriptor* desc = new (r.zone()) CallDescriptor( // --
6222 CallDescriptor::kCallCodeObject, // kind
6223 MachineType::AnyTagged(), // target_type
6224 c->GetInputLocation(0), // target_loc
6225 &sig, // machine_sig
6226 &loc, // location_sig
6227 0, // stack count
6228 Operator::kNoProperties, // properties
6229 c->CalleeSavedRegisters(), // callee saved
6230 c->CalleeSavedFPRegisters(), // callee saved FP
6231 CallDescriptor::kNoFlags, // flags
6232 "c-call-as-code");
6233 Node* call = r.AddNode(r.common()->Call(desc), phi);
6234 r.Return(call);
6235
6236 CHECK_EQ(33, r.Call(1));
6237 CHECK_EQ(44, r.Call(0));
6238}
6239
Ben Murdoch097c5b22016-05-18 11:27:45 +01006240TEST(ParentFramePointer) {
6241 RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
6242 RawMachineLabel tlabel;
6243 RawMachineLabel flabel;
6244 RawMachineLabel merge;
6245 Node* frame = r.LoadFramePointer();
6246 Node* parent_frame = r.LoadParentFramePointer();
6247 frame = r.Load(MachineType::IntPtr(), frame);
6248 r.Branch(r.WordEqual(frame, parent_frame), &tlabel, &flabel);
6249 r.Bind(&tlabel);
6250 Node* fa = r.Int32Constant(1);
6251 r.Goto(&merge);
6252 r.Bind(&flabel);
6253 Node* fb = r.Int32Constant(0);
6254 r.Goto(&merge);
6255 r.Bind(&merge);
6256 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
6257 r.Return(phi);
6258 CHECK_EQ(1, r.Call(1));
6259}
6260
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006261} // namespace compiler
6262} // namespace internal
6263} // namespace v8