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