Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/cctest/compiler/codegen-tester.h"
6 :
7 : #include "src/base/overflowing-math.h"
8 : #include "src/objects-inl.h"
9 : #include "test/cctest/cctest.h"
10 : #include "test/cctest/compiler/value-helper.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace compiler {
15 :
16 28342 : TEST(CompareWrapper) {
17 : // Who tests the testers?
18 : // If CompareWrapper is broken, then test expectations will be broken.
19 : CompareWrapper wWord32Equal(IrOpcode::kWord32Equal);
20 : CompareWrapper wInt32LessThan(IrOpcode::kInt32LessThan);
21 : CompareWrapper wInt32LessThanOrEqual(IrOpcode::kInt32LessThanOrEqual);
22 : CompareWrapper wUint32LessThan(IrOpcode::kUint32LessThan);
23 : CompareWrapper wUint32LessThanOrEqual(IrOpcode::kUint32LessThanOrEqual);
24 :
25 : {
26 295 : FOR_INT32_INPUTS(pl) {
27 16820 : FOR_INT32_INPUTS(pr) {
28 16820 : int32_t a = *pl;
29 16820 : int32_t b = *pr;
30 16820 : CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
31 16820 : CHECK_EQ(a < b, wInt32LessThan.Int32Compare(a, b));
32 16820 : CHECK_EQ(a <= b, wInt32LessThanOrEqual.Int32Compare(a, b));
33 : }
34 : }
35 : }
36 :
37 : {
38 290 : FOR_UINT32_INPUTS(pl) {
39 16820 : FOR_UINT32_INPUTS(pr) {
40 16820 : uint32_t a = *pl;
41 16820 : uint32_t b = *pr;
42 16820 : CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
43 16820 : CHECK_EQ(a < b, wUint32LessThan.Int32Compare(a, b));
44 16820 : CHECK_EQ(a <= b, wUint32LessThanOrEqual.Int32Compare(a, b));
45 : }
46 : }
47 : }
48 :
49 5 : CHECK_EQ(true, wWord32Equal.Int32Compare(0, 0));
50 5 : CHECK_EQ(true, wWord32Equal.Int32Compare(257, 257));
51 5 : CHECK_EQ(true, wWord32Equal.Int32Compare(65539, 65539));
52 5 : CHECK_EQ(true, wWord32Equal.Int32Compare(-1, -1));
53 5 : CHECK_EQ(true, wWord32Equal.Int32Compare(0xFFFFFFFF, 0xFFFFFFFF));
54 :
55 10 : CHECK_EQ(false, wWord32Equal.Int32Compare(0, 1));
56 10 : CHECK_EQ(false, wWord32Equal.Int32Compare(257, 256));
57 10 : CHECK_EQ(false, wWord32Equal.Int32Compare(65539, 65537));
58 10 : CHECK_EQ(false, wWord32Equal.Int32Compare(-1, -2));
59 5 : CHECK_EQ(false, wWord32Equal.Int32Compare(0xFFFFFFFF, 0xFFFFFFFE));
60 :
61 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(0, 0));
62 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(357, 357));
63 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(75539, 75539));
64 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -1));
65 5 : CHECK_EQ(false, wInt32LessThan.Int32Compare(0xFFFFFFFF, 0xFFFFFFFF));
66 :
67 5 : CHECK_EQ(true, wInt32LessThan.Int32Compare(0, 1));
68 5 : CHECK_EQ(true, wInt32LessThan.Int32Compare(456, 457));
69 5 : CHECK_EQ(true, wInt32LessThan.Int32Compare(85537, 85539));
70 5 : CHECK_EQ(true, wInt32LessThan.Int32Compare(-2, -1));
71 5 : CHECK_EQ(true, wInt32LessThan.Int32Compare(0xFFFFFFFE, 0xFFFFFFFF));
72 :
73 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(1, 0));
74 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(457, 456));
75 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(85539, 85537));
76 10 : CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -2));
77 5 : CHECK_EQ(false, wInt32LessThan.Int32Compare(0xFFFFFFFF, 0xFFFFFFFE));
78 :
79 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 0));
80 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(357, 357));
81 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(75539, 75539));
82 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-1, -1));
83 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xFFFFFFFF, 0xFFFFFFFF));
84 :
85 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 1));
86 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(456, 457));
87 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(85537, 85539));
88 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-2, -1));
89 5 : CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xFFFFFFFE, 0xFFFFFFFF));
90 :
91 10 : CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(1, 0));
92 10 : CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(457, 456));
93 10 : CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(85539, 85537));
94 10 : CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(-1, -2));
95 5 : CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(0xFFFFFFFF, 0xFFFFFFFE));
96 :
97 : // Unsigned comparisons.
98 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(0, 0));
99 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(357, 357));
100 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(75539, 75539));
101 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(-1, -1));
102 5 : CHECK_EQ(false, wUint32LessThan.Int32Compare(0xFFFFFFFF, 0xFFFFFFFF));
103 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(0xFFFFFFFF, 0));
104 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(-2999, 0));
105 :
106 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 1));
107 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(456, 457));
108 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(85537, 85539));
109 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(-11, -10));
110 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(0xFFFFFFFE, 0xFFFFFFFF));
111 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 0xFFFFFFFF));
112 5 : CHECK_EQ(true, wUint32LessThan.Int32Compare(0, -2996));
113 :
114 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(1, 0));
115 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(457, 456));
116 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(85539, 85537));
117 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(-10, -21));
118 10 : CHECK_EQ(false, wUint32LessThan.Int32Compare(0xFFFFFFFF, 0xFFFFFFFE));
119 :
120 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 0));
121 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(357, 357));
122 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(75539, 75539));
123 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-1, -1));
124 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xFFFFFFFF, 0xFFFFFFFF));
125 :
126 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 1));
127 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(456, 457));
128 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(85537, 85539));
129 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -299));
130 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -300));
131 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xFFFFFFFE, 0xFFFFFFFF));
132 5 : CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, -2995));
133 :
134 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(1, 0));
135 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(457, 456));
136 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(85539, 85537));
137 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-130, -170));
138 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(0xFFFFFFFF, 0xFFFFFFFE));
139 10 : CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-2997, 0));
140 :
141 : CompareWrapper wFloat64Equal(IrOpcode::kFloat64Equal);
142 : CompareWrapper wFloat64LessThan(IrOpcode::kFloat64LessThan);
143 : CompareWrapper wFloat64LessThanOrEqual(IrOpcode::kFloat64LessThanOrEqual);
144 :
145 : // Check NaN handling.
146 : double nan = std::numeric_limits<double>::quiet_NaN();
147 : double inf = V8_INFINITY;
148 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 0.0));
149 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 1.0));
150 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, inf));
151 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, -inf));
152 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));
153 :
154 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, nan));
155 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, nan));
156 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, nan));
157 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, nan));
158 5 : CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));
159 :
160 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 0.0));
161 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 1.0));
162 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, inf));
163 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, -inf));
164 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));
165 :
166 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, nan));
167 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, nan));
168 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, nan));
169 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, nan));
170 5 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));
171 :
172 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 0.0));
173 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 1.0));
174 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, inf));
175 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, -inf));
176 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));
177 :
178 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, nan));
179 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, nan));
180 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, nan));
181 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-inf, nan));
182 5 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));
183 :
184 : // Check inf handling.
185 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 0.0));
186 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 1.0));
187 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
188 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));
189 :
190 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, inf));
191 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, inf));
192 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
193 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));
194 :
195 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 0.0));
196 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 1.0));
197 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
198 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));
199 :
200 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(0.0, inf));
201 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(1.0, inf));
202 5 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
203 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));
204 :
205 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 0.0));
206 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 1.0));
207 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
208 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));
209 :
210 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0.0, inf));
211 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(1.0, inf));
212 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
213 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));
214 :
215 : // Check -inf handling.
216 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 0.0));
217 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 1.0));
218 5 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));
219 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));
220 :
221 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, -inf));
222 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, -inf));
223 5 : CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));
224 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));
225 :
226 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 0.0));
227 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 1.0));
228 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));
229 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));
230 :
231 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, -inf));
232 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, -inf));
233 5 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));
234 5 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));
235 :
236 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 0.0));
237 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 1.0));
238 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));
239 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));
240 :
241 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, -inf));
242 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, -inf));
243 5 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));
244 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));
245 :
246 : // Check basic values.
247 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(0, 0));
248 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(257.1, 257.1));
249 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(65539.1, 65539.1));
250 5 : CHECK_EQ(true, wFloat64Equal.Float64Compare(-1.1, -1.1));
251 :
252 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(0, 1));
253 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(257.2, 256.2));
254 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(65539.2, 65537.2));
255 10 : CHECK_EQ(false, wFloat64Equal.Float64Compare(-1.2, -2.2));
256 :
257 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(0, 0));
258 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(357.3, 357.3));
259 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(75539.3, 75539.3));
260 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.3, -1.3));
261 :
262 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(0, 1));
263 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(456.4, 457.4));
264 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(85537.4, 85539.4));
265 5 : CHECK_EQ(true, wFloat64LessThan.Float64Compare(-2.4, -1.4));
266 :
267 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(1, 0));
268 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(457.5, 456.5));
269 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(85539.5, 85537.5));
270 10 : CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.5, -2.5));
271 :
272 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 0));
273 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(357.6, 357.6));
274 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(75539.6, 75539.6));
275 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-1.6, -1.6));
276 :
277 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 1));
278 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(456.7, 457.7));
279 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(85537.7, 85539.7));
280 5 : CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-2.7, -1.7));
281 :
282 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1, 0));
283 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(457.8, 456.8));
284 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(85539.8, 85537.8));
285 10 : CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-1.8, -2.8));
286 5 : }
287 :
288 :
289 150 : void Int32BinopInputShapeTester::TestAllInputShapes() {
290 : Vector<const int32_t> inputs = ValueHelper::int32_vector();
291 : int num_int_inputs = static_cast<int>(inputs.size());
292 : if (num_int_inputs > 16) num_int_inputs = 16; // limit to 16 inputs
293 :
294 2850 : for (int i = -2; i < num_int_inputs; i++) { // for all left shapes
295 10200 : for (int j = -2; j < num_int_inputs; j++) { // for all right shapes
296 12600 : if (i >= 0 && j >= 0) break; // No constant/constant combos
297 : RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
298 10200 : MachineType::Int32());
299 10200 : Node* p0 = m.Parameter(0);
300 10200 : Node* p1 = m.Parameter(1);
301 : Node* n0;
302 : Node* n1;
303 :
304 : // left = Parameter | Load | Constant
305 10200 : if (i == -2) {
306 : n0 = p0;
307 7500 : } else if (i == -1) {
308 2700 : n0 = m.LoadFromPointer(&input_a, MachineType::Int32());
309 : } else {
310 9600 : n0 = m.Int32Constant(inputs[i]);
311 : }
312 :
313 : // right = Parameter | Load | Constant
314 10200 : if (j == -2) {
315 : n1 = p1;
316 7500 : } else if (j == -1) {
317 2700 : n1 = m.LoadFromPointer(&input_b, MachineType::Int32());
318 : } else {
319 9600 : n1 = m.Int32Constant(inputs[j]);
320 : }
321 :
322 10200 : gen->gen(&m, n0, n1);
323 :
324 10200 : if (i >= 0) {
325 9600 : input_a = inputs[i];
326 4800 : RunRight(&m);
327 5400 : } else if (j >= 0) {
328 9600 : input_b = inputs[j];
329 4800 : RunLeft(&m);
330 : } else {
331 600 : Run(&m);
332 : }
333 : }
334 : }
335 150 : }
336 :
337 :
338 600 : void Int32BinopInputShapeTester::Run(RawMachineAssemblerTester<int32_t>* m) {
339 35400 : FOR_INT32_INPUTS(pl) {
340 2018400 : FOR_INT32_INPUTS(pr) {
341 2018400 : input_a = *pl;
342 2018400 : input_b = *pr;
343 2018400 : int32_t expect = gen->expected(input_a, input_b);
344 2018400 : CHECK_EQ(expect, m->Call(input_a, input_b));
345 : }
346 : }
347 600 : }
348 :
349 :
350 4800 : void Int32BinopInputShapeTester::RunLeft(
351 : RawMachineAssemblerTester<int32_t>* m) {
352 283200 : FOR_UINT32_INPUTS(i) {
353 278400 : input_a = *i;
354 278400 : int32_t expect = gen->expected(input_a, input_b);
355 278400 : CHECK_EQ(expect, m->Call(input_a, input_b));
356 : }
357 4800 : }
358 :
359 :
360 4800 : void Int32BinopInputShapeTester::RunRight(
361 : RawMachineAssemblerTester<int32_t>* m) {
362 283200 : FOR_UINT32_INPUTS(i) {
363 278400 : input_b = *i;
364 278400 : int32_t expect = gen->expected(input_a, input_b);
365 278400 : CHECK_EQ(expect, m->Call(input_a, input_b));
366 : }
367 4800 : }
368 :
369 :
370 28342 : TEST(ParametersEqual) {
371 : RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
372 5 : MachineType::Int32());
373 5 : Node* p1 = m.Parameter(1);
374 5 : CHECK(p1);
375 5 : Node* p0 = m.Parameter(0);
376 5 : CHECK(p0);
377 5 : CHECK_EQ(p0, m.Parameter(0));
378 5 : CHECK_EQ(p1, m.Parameter(1));
379 5 : }
380 :
381 :
382 0 : void RunSmiConstant(int32_t v) {
383 : // TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
384 : #if !V8_TARGET_ARCH_X64
385 : if (Smi::IsValid(v)) {
386 : RawMachineAssemblerTester<Object> m;
387 : m.Return(m.NumberConstant(v));
388 : CHECK_EQ(Smi::FromInt(v), m.Call());
389 : }
390 : #endif
391 0 : }
392 :
393 :
394 1195 : void RunNumberConstant(double v) {
395 1195 : RawMachineAssemblerTester<Object> m;
396 : #if V8_TARGET_ARCH_X64
397 : // TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
398 1195 : Handle<Object> number = m.isolate()->factory()->NewNumber(v);
399 3585 : if (number->IsSmi()) return;
400 : #endif
401 200 : m.Return(m.NumberConstant(v));
402 200 : Object result = m.Call();
403 200 : m.CheckNumber(v, result);
404 : }
405 :
406 :
407 28342 : TEST(RunEmpty) {
408 5 : RawMachineAssemblerTester<int32_t> m;
409 5 : m.Return(m.Int32Constant(0));
410 5 : CHECK_EQ(0, m.Call());
411 5 : }
412 :
413 :
414 28342 : TEST(RunInt32Constants) {
415 295 : FOR_INT32_INPUTS(i) {
416 290 : RawMachineAssemblerTester<int32_t> m;
417 290 : m.Return(m.Int32Constant(*i));
418 290 : CHECK_EQ(*i, m.Call());
419 : }
420 5 : }
421 :
422 :
423 28342 : TEST(RunSmiConstants) {
424 170 : for (int32_t i = 1; i < Smi::kMaxValue && i != 0;
425 : i = base::ShlWithWraparound(i, 1)) {
426 : RunSmiConstant(i);
427 : RunSmiConstant(base::MulWithWraparound(3, i));
428 : RunSmiConstant(base::MulWithWraparound(5, i));
429 : RunSmiConstant(base::NegateWithWraparound(i));
430 : RunSmiConstant(i | 1);
431 : RunSmiConstant(i | 3);
432 : }
433 : RunSmiConstant(Smi::kMaxValue);
434 : RunSmiConstant(Smi::kMaxValue - 1);
435 : RunSmiConstant(Smi::kMinValue);
436 : RunSmiConstant(Smi::kMinValue + 1);
437 :
438 : FOR_INT32_INPUTS(i) { RunSmiConstant(*i); }
439 5 : }
440 :
441 :
442 28342 : TEST(RunNumberConstants) {
443 : {
444 5 : FOR_FLOAT64_INPUTS(i) { RunNumberConstant(*i); }
445 : }
446 : {
447 290 : FOR_INT32_INPUTS(i) { RunNumberConstant(*i); }
448 : }
449 :
450 165 : for (int32_t i = 1; i < Smi::kMaxValue && i != 0;
451 : i = base::ShlWithWraparound(i, 1)) {
452 160 : RunNumberConstant(i);
453 160 : RunNumberConstant(base::NegateWithWraparound(i));
454 160 : RunNumberConstant(i | 1);
455 160 : RunNumberConstant(i | 3);
456 : }
457 5 : RunNumberConstant(Smi::kMaxValue);
458 5 : RunNumberConstant(Smi::kMaxValue - 1);
459 5 : RunNumberConstant(Smi::kMinValue);
460 5 : RunNumberConstant(Smi::kMinValue + 1);
461 5 : }
462 :
463 :
464 28342 : TEST(RunEmptyString) {
465 5 : RawMachineAssemblerTester<Object> m;
466 5 : m.Return(m.StringConstant("empty"));
467 5 : m.CheckString("empty", m.Call());
468 5 : }
469 :
470 :
471 28342 : TEST(RunHeapConstant) {
472 5 : RawMachineAssemblerTester<Object> m;
473 5 : m.Return(m.StringConstant("empty"));
474 5 : m.CheckString("empty", m.Call());
475 5 : }
476 :
477 :
478 28342 : TEST(RunHeapNumberConstant) {
479 5 : RawMachineAssemblerTester<void*> m;
480 5 : Handle<HeapObject> number = m.isolate()->factory()->NewHeapNumber(100.5);
481 5 : m.Return(m.HeapConstant(number));
482 : HeapObject result =
483 10 : HeapObject::cast(Object(reinterpret_cast<Address>(m.Call())));
484 10 : CHECK_EQ(result, *number);
485 5 : }
486 :
487 :
488 28342 : TEST(RunParam1) {
489 5 : RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
490 5 : m.Return(m.Parameter(0));
491 :
492 295 : FOR_INT32_INPUTS(i) {
493 290 : int32_t result = m.Call(*i);
494 290 : CHECK_EQ(*i, result);
495 : }
496 5 : }
497 :
498 :
499 28342 : TEST(RunParam2_1) {
500 : RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
501 5 : MachineType::Int32());
502 5 : Node* p0 = m.Parameter(0);
503 5 : Node* p1 = m.Parameter(1);
504 5 : m.Return(p0);
505 : USE(p1);
506 :
507 295 : FOR_INT32_INPUTS(i) {
508 290 : int32_t result = m.Call(*i, -9999);
509 290 : CHECK_EQ(*i, result);
510 : }
511 5 : }
512 :
513 :
514 28342 : TEST(RunParam2_2) {
515 : RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
516 5 : MachineType::Int32());
517 5 : Node* p0 = m.Parameter(0);
518 5 : Node* p1 = m.Parameter(1);
519 5 : m.Return(p1);
520 : USE(p0);
521 :
522 295 : FOR_INT32_INPUTS(i) {
523 290 : int32_t result = m.Call(-7777, *i);
524 290 : CHECK_EQ(*i, result);
525 : }
526 5 : }
527 :
528 :
529 28342 : TEST(RunParam3) {
530 20 : for (int i = 0; i < 3; i++) {
531 : RawMachineAssemblerTester<int32_t> m(
532 15 : MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
533 15 : Node* nodes[] = {m.Parameter(0), m.Parameter(1), m.Parameter(2)};
534 15 : m.Return(nodes[i]);
535 :
536 15 : int p[] = {-99, -77, -88};
537 885 : FOR_INT32_INPUTS(j) {
538 870 : p[i] = *j;
539 870 : int32_t result = m.Call(p[0], p[1], p[2]);
540 870 : CHECK_EQ(*j, result);
541 : }
542 : }
543 5 : }
544 :
545 :
546 28342 : TEST(RunBinopTester) {
547 : {
548 5 : RawMachineAssemblerTester<int32_t> m;
549 : Int32BinopTester bt(&m);
550 5 : bt.AddReturn(bt.param0);
551 :
552 295 : FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(*i, 777)); }
553 : }
554 :
555 : {
556 5 : RawMachineAssemblerTester<int32_t> m;
557 : Int32BinopTester bt(&m);
558 5 : bt.AddReturn(bt.param1);
559 :
560 295 : FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(666, *i)); }
561 : }
562 :
563 : {
564 5 : RawMachineAssemblerTester<int32_t> m;
565 : Float64BinopTester bt(&m);
566 5 : bt.AddReturn(bt.param0);
567 :
568 495 : FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, bt.call(*i, 9.0)); }
569 : }
570 :
571 : {
572 5 : RawMachineAssemblerTester<int32_t> m;
573 : Float64BinopTester bt(&m);
574 5 : bt.AddReturn(bt.param1);
575 :
576 495 : FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, bt.call(-11.25, *i)); }
577 : }
578 5 : }
579 :
580 :
581 : #if V8_TARGET_ARCH_64_BIT
582 : // TODO(ahaas): run int64 tests on all platforms when supported.
583 :
584 : namespace {
585 :
586 : int64_t Add4(int64_t a, int64_t b, int64_t c, int64_t d) {
587 : // Operate on uint64_t values to avoid undefined behavior.
588 : return static_cast<int64_t>(
589 459270 : static_cast<uint64_t>(a) + static_cast<uint64_t>(b) +
590 459270 : static_cast<uint64_t>(c) + static_cast<uint64_t>(d));
591 : }
592 :
593 : int64_t Add3(int64_t a, int64_t b, int64_t c) { return Add4(a, b, c, 0); }
594 :
595 : } // namespace
596 :
597 28342 : TEST(RunBufferedRawMachineAssemblerTesterTester) {
598 : {
599 5 : BufferedRawMachineAssemblerTester<int64_t> m;
600 5 : m.Return(m.Int64Constant(0x12500000000));
601 5 : CHECK_EQ(0x12500000000, m.Call());
602 : }
603 : {
604 5 : BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
605 5 : m.Return(m.Parameter(0));
606 495 : FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, m.Call(*i)); }
607 : }
608 : {
609 : BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
610 5 : MachineType::Int64());
611 5 : m.Return(m.Int64Add(m.Parameter(0), m.Parameter(1)));
612 410 : FOR_INT64_INPUTS(i) {
613 32805 : FOR_INT64_INPUTS(j) {
614 65610 : CHECK_EQ(base::AddWithWraparound(*i, *j), m.Call(*i, *j));
615 65610 : CHECK_EQ(base::AddWithWraparound(*j, *i), m.Call(*j, *i));
616 : }
617 : }
618 : }
619 : {
620 : BufferedRawMachineAssemblerTester<int64_t> m(
621 5 : MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
622 : m.Return(
623 5 : m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
624 410 : FOR_INT64_INPUTS(i) {
625 32805 : FOR_INT64_INPUTS(j) {
626 65610 : CHECK_EQ(Add3(*i, *i, *j), m.Call(*i, *i, *j));
627 65610 : CHECK_EQ(Add3(*i, *j, *i), m.Call(*i, *j, *i));
628 65610 : CHECK_EQ(Add3(*j, *i, *i), m.Call(*j, *i, *i));
629 : }
630 : }
631 : }
632 : {
633 : BufferedRawMachineAssemblerTester<int64_t> m(
634 : MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
635 5 : MachineType::Int64());
636 : m.Return(m.Int64Add(
637 : m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
638 5 : m.Parameter(3)));
639 410 : FOR_INT64_INPUTS(i) {
640 32805 : FOR_INT64_INPUTS(j) {
641 65610 : CHECK_EQ(Add4(*i, *i, *i, *j), m.Call(*i, *i, *i, *j));
642 65610 : CHECK_EQ(Add4(*i, *i, *j, *i), m.Call(*i, *i, *j, *i));
643 65610 : CHECK_EQ(Add4(*i, *j, *i, *i), m.Call(*i, *j, *i, *i));
644 65610 : CHECK_EQ(Add4(*j, *i, *i, *i), m.Call(*j, *i, *i, *i));
645 : }
646 : }
647 : }
648 : {
649 5 : BufferedRawMachineAssemblerTester<void> m;
650 : int64_t result;
651 : m.Store(MachineTypeForC<int64_t>().representation(),
652 : m.PointerConstant(&result), m.Int64Constant(0x12500000000),
653 10 : kNoWriteBarrier);
654 5 : m.Return(m.Int32Constant(0));
655 : m.Call();
656 5 : CHECK_EQ(0x12500000000, result);
657 : }
658 : {
659 5 : BufferedRawMachineAssemblerTester<void> m(MachineType::Float64());
660 : double result;
661 : m.Store(MachineTypeForC<double>().representation(),
662 5 : m.PointerConstant(&result), m.Parameter(0), kNoWriteBarrier);
663 5 : m.Return(m.Int32Constant(0));
664 250 : FOR_FLOAT64_INPUTS(i) {
665 245 : m.Call(*i);
666 735 : CHECK_DOUBLE_EQ(*i, result);
667 : }
668 : }
669 : {
670 : BufferedRawMachineAssemblerTester<void> m(MachineType::Int64(),
671 5 : MachineType::Int64());
672 : int64_t result;
673 : m.Store(MachineTypeForC<int64_t>().representation(),
674 : m.PointerConstant(&result),
675 10 : m.Int64Add(m.Parameter(0), m.Parameter(1)), kNoWriteBarrier);
676 5 : m.Return(m.Int32Constant(0));
677 410 : FOR_INT64_INPUTS(i) {
678 32805 : FOR_INT64_INPUTS(j) {
679 32805 : m.Call(*i, *j);
680 65610 : CHECK_EQ(base::AddWithWraparound(*i, *j), result);
681 :
682 : m.Call(*j, *i);
683 65610 : CHECK_EQ(base::AddWithWraparound(*j, *i), result);
684 : }
685 : }
686 : }
687 : {
688 : BufferedRawMachineAssemblerTester<void> m(
689 5 : MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
690 : int64_t result;
691 : m.Store(
692 : MachineTypeForC<int64_t>().representation(), m.PointerConstant(&result),
693 : m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
694 10 : kNoWriteBarrier);
695 5 : m.Return(m.Int32Constant(0));
696 410 : FOR_INT64_INPUTS(i) {
697 32805 : FOR_INT64_INPUTS(j) {
698 32805 : m.Call(*i, *i, *j);
699 65610 : CHECK_EQ(Add3(*i, *i, *j), result);
700 :
701 : m.Call(*i, *j, *i);
702 65610 : CHECK_EQ(Add3(*i, *j, *i), result);
703 :
704 : m.Call(*j, *i, *i);
705 65610 : CHECK_EQ(Add3(*j, *i, *i), result);
706 : }
707 : }
708 : }
709 : {
710 : BufferedRawMachineAssemblerTester<void> m(
711 : MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
712 5 : MachineType::Int64());
713 : int64_t result;
714 : m.Store(MachineTypeForC<int64_t>().representation(),
715 : m.PointerConstant(&result),
716 : m.Int64Add(m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)),
717 : m.Parameter(2)),
718 : m.Parameter(3)),
719 10 : kNoWriteBarrier);
720 5 : m.Return(m.Int32Constant(0));
721 410 : FOR_INT64_INPUTS(i) {
722 32805 : FOR_INT64_INPUTS(j) {
723 32805 : m.Call(*i, *i, *i, *j);
724 65610 : CHECK_EQ(Add4(*i, *i, *i, *j), result);
725 :
726 : m.Call(*i, *i, *j, *i);
727 65610 : CHECK_EQ(Add4(*i, *i, *j, *i), result);
728 :
729 : m.Call(*i, *j, *i, *i);
730 65610 : CHECK_EQ(Add4(*i, *j, *i, *i), result);
731 :
732 : m.Call(*j, *i, *i, *i);
733 65610 : CHECK_EQ(Add4(*j, *i, *i, *i), result);
734 : }
735 : }
736 : }
737 5 : }
738 :
739 : #endif
740 : } // namespace compiler
741 : } // namespace internal
742 85011 : } // namespace v8
|