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