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