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