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