1fa0b10842f849e2a51b88c3ade8c39938f3e7c4
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / arm / instruction-selector-arm-unittest.cc
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 <limits>
6
7 #include "test/unittests/compiler/instruction-selector-unittest.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12
13 namespace {
14
15 typedef RawMachineAssembler::Label MLabel;
16 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
17
18
19 // Data processing instructions.
20 struct DPI {
21   Constructor constructor;
22   const char* constructor_name;
23   ArchOpcode arch_opcode;
24   ArchOpcode reverse_arch_opcode;
25   ArchOpcode test_arch_opcode;
26 };
27
28
29 std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
30   return os << dpi.constructor_name;
31 }
32
33
34 static const DPI kDPIs[] = {
35     {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
36     {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
37     {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
38     {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
39     {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
40
41
42 // Data processing instructions with overflow.
43 struct ODPI {
44   Constructor constructor;
45   const char* constructor_name;
46   ArchOpcode arch_opcode;
47   ArchOpcode reverse_arch_opcode;
48 };
49
50
51 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
52   return os << odpi.constructor_name;
53 }
54
55
56 static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
57                                "Int32AddWithOverflow", kArmAdd, kArmAdd},
58                               {&RawMachineAssembler::Int32SubWithOverflow,
59                                "Int32SubWithOverflow", kArmSub, kArmRsb}};
60
61
62 // Shifts.
63 struct Shift {
64   Constructor constructor;
65   const char* constructor_name;
66   int32_t i_low;          // lowest possible immediate
67   int32_t i_high;         // highest possible immediate
68   AddressingMode i_mode;  // Operand2_R_<shift>_I
69   AddressingMode r_mode;  // Operand2_R_<shift>_R
70 };
71
72
73 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
74   return os << shift.constructor_name;
75 }
76
77
78 static const Shift kShifts[] = {
79     {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
80      kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
81     {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
82      kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
83     {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
84      kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
85     {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
86      kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
87
88
89 // Immediates (random subset).
90 static const int32_t kImmediates[] = {
91     std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216,
92     -2080374784,                         -1996488704, -1879048192, -1459617792,
93     -1358954496,                         -1342177265, -1275068414, -1073741818,
94     -1073741777,                         -855638016,  -805306368,  -402653184,
95     -268435444,                          -16777216,   0,           35,
96     61,                                  105,         116,         171,
97     245,                                 255,         692,         1216,
98     1248,                                1520,        1600,        1888,
99     3744,                                4080,        5888,        8384,
100     9344,                                9472,        9792,        13312,
101     15040,                               15360,       20736,       22272,
102     23296,                               32000,       33536,       37120,
103     45824,                               47872,       56320,       59392,
104     65280,                               72704,       101376,      147456,
105     161792,                              164864,      167936,      173056,
106     195584,                              209920,      212992,      356352,
107     655360,                              704512,      716800,      851968,
108     901120,                              1044480,     1523712,     2572288,
109     3211264,                             3588096,     3833856,     3866624,
110     4325376,                             5177344,     6488064,     7012352,
111     7471104,                             14090240,    16711680,    19398656,
112     22282240,                            28573696,    30408704,    30670848,
113     43253760,                            54525952,    55312384,    56623104,
114     68157440,                            115343360,   131072000,   187695104,
115     188743680,                           195035136,   197132288,   203423744,
116     218103808,                           267386880,   268435470,   285212672,
117     402653185,                           415236096,   595591168,   603979776,
118     603979778,                           629145600,   1073741835,  1073741855,
119     1073741861,                          1073741884,  1157627904,  1476395008,
120     1476395010,                          1610612741,  2030043136,  2080374785,
121     2097152000};
122
123 }  // namespace
124
125
126 // -----------------------------------------------------------------------------
127 // Data processing instructions.
128
129
130 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
131
132
133 TEST_P(InstructionSelectorDPITest, Parameters) {
134   const DPI dpi = GetParam();
135   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
136   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
137   Stream s = m.Build();
138   ASSERT_EQ(1U, s.size());
139   EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
140   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
141   EXPECT_EQ(2U, s[0]->InputCount());
142   EXPECT_EQ(1U, s[0]->OutputCount());
143 }
144
145
146 TEST_P(InstructionSelectorDPITest, Immediate) {
147   const DPI dpi = GetParam();
148   TRACED_FOREACH(int32_t, imm, kImmediates) {
149     StreamBuilder m(this, kMachInt32, kMachInt32);
150     m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
151     Stream s = m.Build();
152     ASSERT_EQ(1U, s.size());
153     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
154     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
155     ASSERT_EQ(2U, s[0]->InputCount());
156     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
157     EXPECT_EQ(1U, s[0]->OutputCount());
158   }
159   TRACED_FOREACH(int32_t, imm, kImmediates) {
160     StreamBuilder m(this, kMachInt32, kMachInt32);
161     m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
162     Stream s = m.Build();
163     ASSERT_EQ(1U, s.size());
164     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
165     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
166     ASSERT_EQ(2U, s[0]->InputCount());
167     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
168     EXPECT_EQ(1U, s[0]->OutputCount());
169   }
170 }
171
172
173 TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
174   const DPI dpi = GetParam();
175   TRACED_FOREACH(Shift, shift, kShifts) {
176     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
177     m.Return((m.*dpi.constructor)(
178         m.Parameter(0),
179         (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
180     Stream s = m.Build();
181     ASSERT_EQ(1U, s.size());
182     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
183     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
184     EXPECT_EQ(3U, s[0]->InputCount());
185     EXPECT_EQ(1U, s[0]->OutputCount());
186   }
187   TRACED_FOREACH(Shift, shift, kShifts) {
188     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
189     m.Return((m.*dpi.constructor)(
190         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
191         m.Parameter(2)));
192     Stream s = m.Build();
193     ASSERT_EQ(1U, s.size());
194     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
195     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
196     EXPECT_EQ(3U, s[0]->InputCount());
197     EXPECT_EQ(1U, s[0]->OutputCount());
198   }
199 }
200
201
202 TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
203   const DPI dpi = GetParam();
204   TRACED_FOREACH(Shift, shift, kShifts) {
205     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
206       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
207       m.Return((m.*dpi.constructor)(
208           m.Parameter(0),
209           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
210       Stream s = m.Build();
211       ASSERT_EQ(1U, s.size());
212       EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
213       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
214       ASSERT_EQ(3U, s[0]->InputCount());
215       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
216       EXPECT_EQ(1U, s[0]->OutputCount());
217     }
218   }
219   TRACED_FOREACH(Shift, shift, kShifts) {
220     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
221       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
222       m.Return((m.*dpi.constructor)(
223           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
224           m.Parameter(1)));
225       Stream s = m.Build();
226       ASSERT_EQ(1U, s.size());
227       EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
228       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
229       ASSERT_EQ(3U, s[0]->InputCount());
230       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
231       EXPECT_EQ(1U, s[0]->OutputCount());
232     }
233   }
234 }
235
236
237 TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
238   const DPI dpi = GetParam();
239   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
240   MLabel a, b;
241   m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
242   m.Bind(&a);
243   m.Return(m.Int32Constant(1));
244   m.Bind(&b);
245   m.Return(m.Int32Constant(0));
246   Stream s = m.Build();
247   ASSERT_EQ(1U, s.size());
248   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
249   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
250   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
251   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
252 }
253
254
255 TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
256   const DPI dpi = GetParam();
257   TRACED_FOREACH(int32_t, imm, kImmediates) {
258     StreamBuilder m(this, kMachInt32, kMachInt32);
259     MLabel a, b;
260     m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
261              &b);
262     m.Bind(&a);
263     m.Return(m.Int32Constant(1));
264     m.Bind(&b);
265     m.Return(m.Int32Constant(0));
266     Stream s = m.Build();
267     ASSERT_EQ(1U, s.size());
268     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
269     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
270     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
271     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
272   }
273   TRACED_FOREACH(int32_t, imm, kImmediates) {
274     StreamBuilder m(this, kMachInt32, kMachInt32);
275     MLabel a, b;
276     m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
277              &b);
278     m.Bind(&a);
279     m.Return(m.Int32Constant(1));
280     m.Bind(&b);
281     m.Return(m.Int32Constant(0));
282     Stream s = m.Build();
283     ASSERT_EQ(1U, s.size());
284     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
285     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
286     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
287     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
288   }
289 }
290
291
292 TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
293   const DPI dpi = GetParam();
294   TRACED_FOREACH(Shift, shift, kShifts) {
295     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
296     MLabel a, b;
297     m.Branch((m.*dpi.constructor)(
298                  m.Parameter(0),
299                  (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
300              &a, &b);
301     m.Bind(&a);
302     m.Return(m.Int32Constant(1));
303     m.Bind(&b);
304     m.Return(m.Int32Constant(0));
305     Stream s = m.Build();
306     ASSERT_EQ(1U, s.size());
307     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
308     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
309     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
310     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
311   }
312   TRACED_FOREACH(Shift, shift, kShifts) {
313     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
314     MLabel a, b;
315     m.Branch((m.*dpi.constructor)(
316                  (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
317                  m.Parameter(2)),
318              &a, &b);
319     m.Bind(&a);
320     m.Return(m.Int32Constant(1));
321     m.Bind(&b);
322     m.Return(m.Int32Constant(0));
323     Stream s = m.Build();
324     ASSERT_EQ(1U, s.size());
325     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
326     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
327     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
328     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
329   }
330 }
331
332
333 TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
334   const DPI dpi = GetParam();
335   TRACED_FOREACH(Shift, shift, kShifts) {
336     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
337       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
338       MLabel a, b;
339       m.Branch((m.*dpi.constructor)(m.Parameter(0),
340                                     (m.*shift.constructor)(
341                                         m.Parameter(1), m.Int32Constant(imm))),
342                &a, &b);
343       m.Bind(&a);
344       m.Return(m.Int32Constant(1));
345       m.Bind(&b);
346       m.Return(m.Int32Constant(0));
347       Stream s = m.Build();
348       ASSERT_EQ(1U, s.size());
349       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
350       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
351       ASSERT_EQ(5U, s[0]->InputCount());
352       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
353       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
354       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
355     }
356   }
357   TRACED_FOREACH(Shift, shift, kShifts) {
358     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
359       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
360       MLabel a, b;
361       m.Branch((m.*dpi.constructor)(
362                    (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
363                    m.Parameter(1)),
364                &a, &b);
365       m.Bind(&a);
366       m.Return(m.Int32Constant(1));
367       m.Bind(&b);
368       m.Return(m.Int32Constant(0));
369       Stream s = m.Build();
370       ASSERT_EQ(1U, s.size());
371       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
372       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
373       ASSERT_EQ(5U, s[0]->InputCount());
374       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
375       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
376       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
377     }
378   }
379 }
380
381
382 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
383   const DPI dpi = GetParam();
384   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
385   MLabel a, b;
386   m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
387                          m.Int32Constant(0)),
388            &a, &b);
389   m.Bind(&a);
390   m.Return(m.Int32Constant(1));
391   m.Bind(&b);
392   m.Return(m.Int32Constant(0));
393   Stream s = m.Build();
394   ASSERT_EQ(1U, s.size());
395   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
396   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
397   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
398   EXPECT_EQ(kEqual, s[0]->flags_condition());
399 }
400
401
402 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
403   const DPI dpi = GetParam();
404   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
405   MLabel a, b;
406   m.Branch(
407       m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
408                        m.Int32Constant(0)),
409       &a, &b);
410   m.Bind(&a);
411   m.Return(m.Int32Constant(1));
412   m.Bind(&b);
413   m.Return(m.Int32Constant(0));
414   Stream s = m.Build();
415   ASSERT_EQ(1U, s.size());
416   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
417   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
418   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
419   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
420 }
421
422
423 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
424   const DPI dpi = GetParam();
425   TRACED_FOREACH(int32_t, imm, kImmediates) {
426     StreamBuilder m(this, kMachInt32, kMachInt32);
427     MLabel a, b;
428     m.Branch(m.Word32Equal(
429                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
430                  m.Int32Constant(0)),
431              &a, &b);
432     m.Bind(&a);
433     m.Return(m.Int32Constant(1));
434     m.Bind(&b);
435     m.Return(m.Int32Constant(0));
436     Stream s = m.Build();
437     ASSERT_EQ(1U, s.size());
438     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
439     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
440     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
441     EXPECT_EQ(kEqual, s[0]->flags_condition());
442   }
443   TRACED_FOREACH(int32_t, imm, kImmediates) {
444     StreamBuilder m(this, kMachInt32, kMachInt32);
445     MLabel a, b;
446     m.Branch(m.Word32Equal(
447                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
448                  m.Int32Constant(0)),
449              &a, &b);
450     m.Bind(&a);
451     m.Return(m.Int32Constant(1));
452     m.Bind(&b);
453     m.Return(m.Int32Constant(0));
454     Stream s = m.Build();
455     ASSERT_EQ(1U, s.size());
456     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
457     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
458     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
459     EXPECT_EQ(kEqual, s[0]->flags_condition());
460   }
461 }
462
463
464 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
465   const DPI dpi = GetParam();
466   TRACED_FOREACH(int32_t, imm, kImmediates) {
467     StreamBuilder m(this, kMachInt32, kMachInt32);
468     MLabel a, b;
469     m.Branch(m.Word32NotEqual(
470                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
471                  m.Int32Constant(0)),
472              &a, &b);
473     m.Bind(&a);
474     m.Return(m.Int32Constant(1));
475     m.Bind(&b);
476     m.Return(m.Int32Constant(0));
477     Stream s = m.Build();
478     ASSERT_EQ(1U, s.size());
479     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
480     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
481     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
482     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
483   }
484   TRACED_FOREACH(int32_t, imm, kImmediates) {
485     StreamBuilder m(this, kMachInt32, kMachInt32);
486     MLabel a, b;
487     m.Branch(m.Word32NotEqual(
488                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
489                  m.Int32Constant(0)),
490              &a, &b);
491     m.Bind(&a);
492     m.Return(m.Int32Constant(1));
493     m.Bind(&b);
494     m.Return(m.Int32Constant(0));
495     Stream s = m.Build();
496     ASSERT_EQ(1U, s.size());
497     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
498     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
499     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
500     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
501   }
502 }
503
504
505 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
506                         ::testing::ValuesIn(kDPIs));
507
508
509 // -----------------------------------------------------------------------------
510 // Data processing instructions with overflow.
511
512
513 typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
514
515
516 TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
517   const ODPI odpi = GetParam();
518   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
519   m.Return(
520       m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
521   Stream s = m.Build();
522   ASSERT_EQ(1U, s.size());
523   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
524   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
525   EXPECT_EQ(2U, s[0]->InputCount());
526   EXPECT_LE(1U, s[0]->OutputCount());
527   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
528   EXPECT_EQ(kOverflow, s[0]->flags_condition());
529 }
530
531
532 TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
533   const ODPI odpi = GetParam();
534   TRACED_FOREACH(int32_t, imm, kImmediates) {
535     StreamBuilder m(this, kMachInt32, kMachInt32);
536     m.Return(m.Projection(
537         1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
538     Stream s = m.Build();
539     ASSERT_EQ(1U, s.size());
540     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
541     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
542     ASSERT_EQ(2U, s[0]->InputCount());
543     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
544     EXPECT_LE(1U, s[0]->OutputCount());
545     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
546     EXPECT_EQ(kOverflow, s[0]->flags_condition());
547   }
548   TRACED_FOREACH(int32_t, imm, kImmediates) {
549     StreamBuilder m(this, kMachInt32, kMachInt32);
550     m.Return(m.Projection(
551         1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
552     Stream s = m.Build();
553     ASSERT_EQ(1U, s.size());
554     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
555     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
556     ASSERT_EQ(2U, s[0]->InputCount());
557     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
558     EXPECT_LE(1U, s[0]->OutputCount());
559     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
560     EXPECT_EQ(kOverflow, s[0]->flags_condition());
561   }
562 }
563
564
565 TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
566   const ODPI odpi = GetParam();
567   TRACED_FOREACH(Shift, shift, kShifts) {
568     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
569     m.Return(m.Projection(
570         1, (m.*odpi.constructor)(
571                m.Parameter(0),
572                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
573     Stream s = m.Build();
574     ASSERT_EQ(1U, s.size());
575     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
576     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
577     EXPECT_EQ(3U, s[0]->InputCount());
578     EXPECT_LE(1U, s[0]->OutputCount());
579     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
580     EXPECT_EQ(kOverflow, s[0]->flags_condition());
581   }
582   TRACED_FOREACH(Shift, shift, kShifts) {
583     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
584     m.Return(m.Projection(
585         1, (m.*odpi.constructor)(
586                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
587                m.Parameter(0))));
588     Stream s = m.Build();
589     ASSERT_EQ(1U, s.size());
590     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
591     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
592     EXPECT_EQ(3U, s[0]->InputCount());
593     EXPECT_LE(1U, s[0]->OutputCount());
594     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
595     EXPECT_EQ(kOverflow, s[0]->flags_condition());
596   }
597 }
598
599
600 TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
601   const ODPI odpi = GetParam();
602   TRACED_FOREACH(Shift, shift, kShifts) {
603     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
604       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
605       m.Return(m.Projection(
606           1, (m.*odpi.constructor)(m.Parameter(0),
607                                    (m.*shift.constructor)(
608                                        m.Parameter(1), m.Int32Constant(imm)))));
609       Stream s = m.Build();
610       ASSERT_EQ(1U, s.size());
611       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
612       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
613       ASSERT_EQ(3U, s[0]->InputCount());
614       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
615       EXPECT_LE(1U, s[0]->OutputCount());
616       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
617       EXPECT_EQ(kOverflow, s[0]->flags_condition());
618     }
619   }
620   TRACED_FOREACH(Shift, shift, kShifts) {
621     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
622       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
623       m.Return(m.Projection(
624           1, (m.*odpi.constructor)(
625                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
626                  m.Parameter(0))));
627       Stream s = m.Build();
628       ASSERT_EQ(1U, s.size());
629       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
630       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
631       ASSERT_EQ(3U, s[0]->InputCount());
632       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
633       EXPECT_LE(1U, s[0]->OutputCount());
634       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
635       EXPECT_EQ(kOverflow, s[0]->flags_condition());
636     }
637   }
638 }
639
640
641 TEST_P(InstructionSelectorODPITest, ValWithParameters) {
642   const ODPI odpi = GetParam();
643   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
644   m.Return(
645       m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
646   Stream s = m.Build();
647   ASSERT_EQ(1U, s.size());
648   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
649   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
650   EXPECT_EQ(2U, s[0]->InputCount());
651   EXPECT_LE(1U, s[0]->OutputCount());
652   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
653 }
654
655
656 TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
657   const ODPI odpi = GetParam();
658   TRACED_FOREACH(int32_t, imm, kImmediates) {
659     StreamBuilder m(this, kMachInt32, kMachInt32);
660     m.Return(m.Projection(
661         0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
662     Stream s = m.Build();
663     ASSERT_EQ(1U, s.size());
664     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
665     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
666     ASSERT_EQ(2U, s[0]->InputCount());
667     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
668     EXPECT_LE(1U, s[0]->OutputCount());
669     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
670   }
671   TRACED_FOREACH(int32_t, imm, kImmediates) {
672     StreamBuilder m(this, kMachInt32, kMachInt32);
673     m.Return(m.Projection(
674         0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
675     Stream s = m.Build();
676     ASSERT_EQ(1U, s.size());
677     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
678     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
679     ASSERT_EQ(2U, s[0]->InputCount());
680     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
681     EXPECT_LE(1U, s[0]->OutputCount());
682     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
683   }
684 }
685
686
687 TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
688   const ODPI odpi = GetParam();
689   TRACED_FOREACH(Shift, shift, kShifts) {
690     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
691     m.Return(m.Projection(
692         0, (m.*odpi.constructor)(
693                m.Parameter(0),
694                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
695     Stream s = m.Build();
696     ASSERT_EQ(1U, s.size());
697     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
698     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
699     EXPECT_EQ(3U, s[0]->InputCount());
700     EXPECT_LE(1U, s[0]->OutputCount());
701     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
702   }
703   TRACED_FOREACH(Shift, shift, kShifts) {
704     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
705     m.Return(m.Projection(
706         0, (m.*odpi.constructor)(
707                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
708                m.Parameter(0))));
709     Stream s = m.Build();
710     ASSERT_EQ(1U, s.size());
711     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
712     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
713     EXPECT_EQ(3U, s[0]->InputCount());
714     EXPECT_LE(1U, s[0]->OutputCount());
715     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
716   }
717 }
718
719
720 TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
721   const ODPI odpi = GetParam();
722   TRACED_FOREACH(Shift, shift, kShifts) {
723     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
724       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
725       m.Return(m.Projection(
726           0, (m.*odpi.constructor)(m.Parameter(0),
727                                    (m.*shift.constructor)(
728                                        m.Parameter(1), m.Int32Constant(imm)))));
729       Stream s = m.Build();
730       ASSERT_EQ(1U, s.size());
731       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
732       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
733       ASSERT_EQ(3U, s[0]->InputCount());
734       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
735       EXPECT_LE(1U, s[0]->OutputCount());
736       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
737     }
738   }
739   TRACED_FOREACH(Shift, shift, kShifts) {
740     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
741       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
742       m.Return(m.Projection(
743           0, (m.*odpi.constructor)(
744                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
745                  m.Parameter(0))));
746       Stream s = m.Build();
747       ASSERT_EQ(1U, s.size());
748       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
749       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
750       ASSERT_EQ(3U, s[0]->InputCount());
751       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
752       EXPECT_LE(1U, s[0]->OutputCount());
753       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
754     }
755   }
756 }
757
758
759 TEST_P(InstructionSelectorODPITest, BothWithParameters) {
760   const ODPI odpi = GetParam();
761   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
762   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
763   m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
764   Stream s = m.Build();
765   ASSERT_LE(1U, s.size());
766   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
767   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
768   EXPECT_EQ(2U, s[0]->InputCount());
769   EXPECT_EQ(2U, s[0]->OutputCount());
770   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
771   EXPECT_EQ(kOverflow, s[0]->flags_condition());
772 }
773
774
775 TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
776   const ODPI odpi = GetParam();
777   TRACED_FOREACH(int32_t, imm, kImmediates) {
778     StreamBuilder m(this, kMachInt32, kMachInt32);
779     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
780     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
781     Stream s = m.Build();
782     ASSERT_LE(1U, s.size());
783     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
784     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
785     ASSERT_EQ(2U, s[0]->InputCount());
786     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
787     EXPECT_EQ(2U, s[0]->OutputCount());
788     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
789     EXPECT_EQ(kOverflow, s[0]->flags_condition());
790   }
791   TRACED_FOREACH(int32_t, imm, kImmediates) {
792     StreamBuilder m(this, kMachInt32, kMachInt32);
793     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
794     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
795     Stream s = m.Build();
796     ASSERT_LE(1U, s.size());
797     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
798     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
799     ASSERT_EQ(2U, s[0]->InputCount());
800     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
801     EXPECT_EQ(2U, s[0]->OutputCount());
802     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
803     EXPECT_EQ(kOverflow, s[0]->flags_condition());
804   }
805 }
806
807
808 TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
809   const ODPI odpi = GetParam();
810   TRACED_FOREACH(Shift, shift, kShifts) {
811     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
812     Node* n = (m.*odpi.constructor)(
813         m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
814     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
815     Stream s = m.Build();
816     ASSERT_LE(1U, s.size());
817     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
818     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
819     EXPECT_EQ(3U, s[0]->InputCount());
820     EXPECT_EQ(2U, s[0]->OutputCount());
821     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
822     EXPECT_EQ(kOverflow, s[0]->flags_condition());
823   }
824   TRACED_FOREACH(Shift, shift, kShifts) {
825     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
826     Node* n = (m.*odpi.constructor)(
827         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
828     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
829     Stream s = m.Build();
830     ASSERT_LE(1U, s.size());
831     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
832     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
833     EXPECT_EQ(3U, s[0]->InputCount());
834     EXPECT_EQ(2U, s[0]->OutputCount());
835     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
836     EXPECT_EQ(kOverflow, s[0]->flags_condition());
837   }
838 }
839
840
841 TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
842   const ODPI odpi = GetParam();
843   TRACED_FOREACH(Shift, shift, kShifts) {
844     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
845       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
846       Node* n = (m.*odpi.constructor)(
847           m.Parameter(0),
848           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
849       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
850       Stream s = m.Build();
851       ASSERT_LE(1U, s.size());
852       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
853       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
854       ASSERT_EQ(3U, s[0]->InputCount());
855       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
856       EXPECT_EQ(2U, s[0]->OutputCount());
857       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
858       EXPECT_EQ(kOverflow, s[0]->flags_condition());
859     }
860   }
861   TRACED_FOREACH(Shift, shift, kShifts) {
862     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
863       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
864       Node* n = (m.*odpi.constructor)(
865           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
866           m.Parameter(1));
867       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
868       Stream s = m.Build();
869       ASSERT_LE(1U, s.size());
870       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
871       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
872       ASSERT_EQ(3U, s[0]->InputCount());
873       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
874       EXPECT_EQ(2U, s[0]->OutputCount());
875       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
876       EXPECT_EQ(kOverflow, s[0]->flags_condition());
877     }
878   }
879 }
880
881
882 TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
883   const ODPI odpi = GetParam();
884   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
885   MLabel a, b;
886   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
887   m.Branch(m.Projection(1, n), &a, &b);
888   m.Bind(&a);
889   m.Return(m.Int32Constant(0));
890   m.Bind(&b);
891   m.Return(m.Projection(0, n));
892   Stream s = m.Build();
893   ASSERT_EQ(1U, s.size());
894   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
895   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
896   EXPECT_EQ(4U, s[0]->InputCount());
897   EXPECT_EQ(1U, s[0]->OutputCount());
898   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
899   EXPECT_EQ(kOverflow, s[0]->flags_condition());
900 }
901
902
903 TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
904   const ODPI odpi = GetParam();
905   TRACED_FOREACH(int32_t, imm, kImmediates) {
906     StreamBuilder m(this, kMachInt32, kMachInt32);
907     MLabel a, b;
908     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
909     m.Branch(m.Projection(1, n), &a, &b);
910     m.Bind(&a);
911     m.Return(m.Int32Constant(0));
912     m.Bind(&b);
913     m.Return(m.Projection(0, n));
914     Stream s = m.Build();
915     ASSERT_EQ(1U, s.size());
916     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
917     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
918     ASSERT_EQ(4U, s[0]->InputCount());
919     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
920     EXPECT_EQ(1U, s[0]->OutputCount());
921     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
922     EXPECT_EQ(kOverflow, s[0]->flags_condition());
923   }
924   TRACED_FOREACH(int32_t, imm, kImmediates) {
925     StreamBuilder m(this, kMachInt32, kMachInt32);
926     MLabel a, b;
927     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
928     m.Branch(m.Projection(1, n), &a, &b);
929     m.Bind(&a);
930     m.Return(m.Int32Constant(0));
931     m.Bind(&b);
932     m.Return(m.Projection(0, n));
933     Stream s = m.Build();
934     ASSERT_EQ(1U, s.size());
935     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
936     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
937     ASSERT_EQ(4U, s[0]->InputCount());
938     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
939     EXPECT_EQ(1U, s[0]->OutputCount());
940     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
941     EXPECT_EQ(kOverflow, s[0]->flags_condition());
942   }
943 }
944
945
946 TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
947   const ODPI odpi = GetParam();
948   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
949   MLabel a, b;
950   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
951   m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
952   m.Bind(&a);
953   m.Return(m.Projection(0, n));
954   m.Bind(&b);
955   m.Return(m.Int32Constant(0));
956   Stream s = m.Build();
957   ASSERT_EQ(1U, s.size());
958   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
959   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
960   EXPECT_EQ(4U, s[0]->InputCount());
961   EXPECT_EQ(1U, s[0]->OutputCount());
962   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
963   EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
964 }
965
966
967 TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
968   const ODPI odpi = GetParam();
969   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
970   MLabel a, b;
971   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
972   m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
973   m.Bind(&a);
974   m.Return(m.Projection(0, n));
975   m.Bind(&b);
976   m.Return(m.Int32Constant(0));
977   Stream s = m.Build();
978   ASSERT_EQ(1U, s.size());
979   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
980   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
981   EXPECT_EQ(4U, s[0]->InputCount());
982   EXPECT_EQ(1U, s[0]->OutputCount());
983   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
984   EXPECT_EQ(kOverflow, s[0]->flags_condition());
985 }
986
987
988 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
989                         ::testing::ValuesIn(kODPIs));
990
991
992 // -----------------------------------------------------------------------------
993 // Shifts.
994
995
996 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
997
998
999 TEST_P(InstructionSelectorShiftTest, Parameters) {
1000   const Shift shift = GetParam();
1001   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1002   m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
1003   Stream s = m.Build();
1004   ASSERT_EQ(1U, s.size());
1005   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1006   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1007   EXPECT_EQ(2U, s[0]->InputCount());
1008   EXPECT_EQ(1U, s[0]->OutputCount());
1009 }
1010
1011
1012 TEST_P(InstructionSelectorShiftTest, Immediate) {
1013   const Shift shift = GetParam();
1014   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1015     StreamBuilder m(this, kMachInt32, kMachInt32);
1016     m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
1017     Stream s = m.Build();
1018     ASSERT_EQ(1U, s.size());
1019     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1020     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1021     ASSERT_EQ(2U, s[0]->InputCount());
1022     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1023     EXPECT_EQ(1U, s[0]->OutputCount());
1024   }
1025 }
1026
1027
1028 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
1029   const Shift shift = GetParam();
1030   {
1031     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1032     m.Return(
1033         m.Word32Equal(m.Parameter(0),
1034                       (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
1035     Stream s = m.Build();
1036     ASSERT_EQ(1U, s.size());
1037     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1038     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1039     EXPECT_EQ(3U, s[0]->InputCount());
1040     EXPECT_EQ(1U, s[0]->OutputCount());
1041     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1042     EXPECT_EQ(kEqual, s[0]->flags_condition());
1043   }
1044   {
1045     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1046     m.Return(
1047         m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
1048                       m.Parameter(0)));
1049     Stream s = m.Build();
1050     ASSERT_EQ(1U, s.size());
1051     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1052     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1053     EXPECT_EQ(3U, s[0]->InputCount());
1054     EXPECT_EQ(1U, s[0]->OutputCount());
1055     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1056     EXPECT_EQ(kEqual, s[0]->flags_condition());
1057   }
1058 }
1059
1060
1061 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
1062   const Shift shift = GetParam();
1063   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1064     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1065     m.Return(m.Word32Equal(
1066         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
1067         m.Parameter(0)));
1068     Stream s = m.Build();
1069     ASSERT_EQ(1U, s.size());
1070     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1071     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1072     ASSERT_EQ(3U, s[0]->InputCount());
1073     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1074     EXPECT_EQ(1U, s[0]->OutputCount());
1075     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1076     EXPECT_EQ(kEqual, s[0]->flags_condition());
1077   }
1078   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1079     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1080     m.Return(m.Word32Equal(
1081         m.Parameter(0),
1082         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
1083     Stream s = m.Build();
1084     ASSERT_EQ(1U, s.size());
1085     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1086     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1087     ASSERT_EQ(3U, s[0]->InputCount());
1088     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1089     EXPECT_EQ(1U, s[0]->OutputCount());
1090     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1091     EXPECT_EQ(kEqual, s[0]->flags_condition());
1092   }
1093 }
1094
1095
1096 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
1097   const Shift shift = GetParam();
1098   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1099   m.Return(
1100       m.Word32Equal(m.Int32Constant(0),
1101                     (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1102   Stream s = m.Build();
1103   ASSERT_EQ(1U, s.size());
1104   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1105   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1106   EXPECT_EQ(2U, s[0]->InputCount());
1107   EXPECT_EQ(2U, s[0]->OutputCount());
1108   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1109   EXPECT_EQ(kEqual, s[0]->flags_condition());
1110 }
1111
1112
1113 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
1114   const Shift shift = GetParam();
1115   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1116     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1117     m.Return(m.Word32Equal(
1118         m.Int32Constant(0),
1119         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1120     Stream s = m.Build();
1121     ASSERT_EQ(1U, s.size());
1122     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1123     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1124     ASSERT_EQ(2U, s[0]->InputCount());
1125     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1126     EXPECT_EQ(2U, s[0]->OutputCount());
1127     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1128     EXPECT_EQ(kEqual, s[0]->flags_condition());
1129   }
1130 }
1131
1132
1133 TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
1134   const Shift shift = GetParam();
1135   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1136   m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1137   Stream s = m.Build();
1138   ASSERT_EQ(1U, s.size());
1139   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1140   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1141   EXPECT_EQ(2U, s[0]->InputCount());
1142   EXPECT_EQ(1U, s[0]->OutputCount());
1143 }
1144
1145
1146 TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
1147   const Shift shift = GetParam();
1148   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1149     StreamBuilder m(this, kMachInt32, kMachInt32);
1150     m.Return(m.Word32Not(
1151         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1152     Stream s = m.Build();
1153     ASSERT_EQ(1U, s.size());
1154     EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1155     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1156     ASSERT_EQ(2U, s[0]->InputCount());
1157     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1158     EXPECT_EQ(1U, s[0]->OutputCount());
1159   }
1160 }
1161
1162
1163 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
1164   const Shift shift = GetParam();
1165   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1166   m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
1167                                            m.Parameter(1), m.Parameter(2)))));
1168   Stream s = m.Build();
1169   ASSERT_EQ(1U, s.size());
1170   EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1171   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1172   EXPECT_EQ(3U, s[0]->InputCount());
1173   EXPECT_EQ(1U, s[0]->OutputCount());
1174 }
1175
1176
1177 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
1178   const Shift shift = GetParam();
1179   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1180     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1181     m.Return(m.Word32And(m.Parameter(0),
1182                          m.Word32Not((m.*shift.constructor)(
1183                              m.Parameter(1), m.Int32Constant(imm)))));
1184     Stream s = m.Build();
1185     ASSERT_EQ(1U, s.size());
1186     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1187     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1188     ASSERT_EQ(3U, s[0]->InputCount());
1189     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1190     EXPECT_EQ(1U, s[0]->OutputCount());
1191   }
1192 }
1193
1194
1195 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
1196                         ::testing::ValuesIn(kShifts));
1197
1198
1199 // -----------------------------------------------------------------------------
1200 // Memory access instructions.
1201
1202
1203 namespace {
1204
1205 struct MemoryAccess {
1206   MachineType type;
1207   ArchOpcode ldr_opcode;
1208   ArchOpcode str_opcode;
1209   bool (InstructionSelectorTest::Stream::*val_predicate)(
1210       const InstructionOperand*) const;
1211   const int32_t immediates[40];
1212 };
1213
1214
1215 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
1216   return os << memacc.type;
1217 }
1218
1219
1220 static const MemoryAccess kMemoryAccesses[] = {
1221     {kMachInt8,
1222      kArmLdrsb,
1223      kArmStrb,
1224      &InstructionSelectorTest::Stream::IsInteger,
1225      {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
1226       -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
1227       115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
1228     {kMachUint8,
1229      kArmLdrb,
1230      kArmStrb,
1231      &InstructionSelectorTest::Stream::IsInteger,
1232      {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
1233       -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
1234       39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
1235     {kMachInt16,
1236      kArmLdrsh,
1237      kArmStrh,
1238      &InstructionSelectorTest::Stream::IsInteger,
1239      {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
1240       -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
1241       102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
1242     {kMachUint16,
1243      kArmLdrh,
1244      kArmStrh,
1245      &InstructionSelectorTest::Stream::IsInteger,
1246      {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
1247       -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
1248       114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
1249     {kMachInt32,
1250      kArmLdr,
1251      kArmStr,
1252      &InstructionSelectorTest::Stream::IsInteger,
1253      {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
1254       -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
1255       93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
1256     {kMachFloat32,
1257      kArmVldrF32,
1258      kArmVstrF32,
1259      &InstructionSelectorTest::Stream::IsDouble,
1260      {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
1261       -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
1262       24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
1263     {kMachFloat64,
1264      kArmVldrF64,
1265      kArmVstrF64,
1266      &InstructionSelectorTest::Stream::IsDouble,
1267      {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
1268       -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
1269       108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
1270
1271 }  // namespace
1272
1273
1274 typedef InstructionSelectorTestWithParam<MemoryAccess>
1275     InstructionSelectorMemoryAccessTest;
1276
1277
1278 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
1279   const MemoryAccess memacc = GetParam();
1280   StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
1281   m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
1282   Stream s = m.Build();
1283   ASSERT_EQ(1U, s.size());
1284   EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1285   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1286   EXPECT_EQ(2U, s[0]->InputCount());
1287   ASSERT_EQ(1U, s[0]->OutputCount());
1288   EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1289 }
1290
1291
1292 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
1293   const MemoryAccess memacc = GetParam();
1294   TRACED_FOREACH(int32_t, index, memacc.immediates) {
1295     StreamBuilder m(this, memacc.type, kMachPtr);
1296     m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
1297     Stream s = m.Build();
1298     ASSERT_EQ(1U, s.size());
1299     EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1300     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1301     ASSERT_EQ(2U, s[0]->InputCount());
1302     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1303     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1304     ASSERT_EQ(1U, s[0]->OutputCount());
1305     EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1306   }
1307 }
1308
1309
1310 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
1311   const MemoryAccess memacc = GetParam();
1312   StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
1313   m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
1314   m.Return(m.Int32Constant(0));
1315   Stream s = m.Build();
1316   ASSERT_EQ(1U, s.size());
1317   EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1318   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1319   EXPECT_EQ(3U, s[0]->InputCount());
1320   EXPECT_EQ(0U, s[0]->OutputCount());
1321 }
1322
1323
1324 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
1325   const MemoryAccess memacc = GetParam();
1326   TRACED_FOREACH(int32_t, index, memacc.immediates) {
1327     StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
1328     m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
1329             m.Parameter(1));
1330     m.Return(m.Int32Constant(0));
1331     Stream s = m.Build();
1332     ASSERT_EQ(1U, s.size());
1333     EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1334     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1335     ASSERT_EQ(3U, s[0]->InputCount());
1336     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1337     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1338     EXPECT_EQ(0U, s[0]->OutputCount());
1339   }
1340 }
1341
1342
1343 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1344                         InstructionSelectorMemoryAccessTest,
1345                         ::testing::ValuesIn(kMemoryAccesses));
1346
1347
1348 // -----------------------------------------------------------------------------
1349 // Conversions.
1350
1351
1352 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
1353   StreamBuilder m(this, kMachFloat64, kMachFloat32);
1354   m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
1355   Stream s = m.Build();
1356   ASSERT_EQ(1U, s.size());
1357   EXPECT_EQ(kArmVcvtF64F32, s[0]->arch_opcode());
1358   EXPECT_EQ(1U, s[0]->InputCount());
1359   EXPECT_EQ(1U, s[0]->OutputCount());
1360 }
1361
1362
1363 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
1364   StreamBuilder m(this, kMachFloat32, kMachFloat64);
1365   m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
1366   Stream s = m.Build();
1367   ASSERT_EQ(1U, s.size());
1368   EXPECT_EQ(kArmVcvtF32F64, s[0]->arch_opcode());
1369   EXPECT_EQ(1U, s[0]->InputCount());
1370   EXPECT_EQ(1U, s[0]->OutputCount());
1371 }
1372
1373
1374 // -----------------------------------------------------------------------------
1375 // Comparisons.
1376
1377
1378 namespace {
1379
1380 struct Comparison {
1381   Constructor constructor;
1382   const char* constructor_name;
1383   FlagsCondition flags_condition;
1384   FlagsCondition negated_flags_condition;
1385 };
1386
1387
1388 std::ostream& operator<<(std::ostream& os, const Comparison& cmp) {
1389   return os << cmp.constructor_name;
1390 }
1391
1392
1393 const Comparison kComparisons[] = {
1394     {&RawMachineAssembler::Word32Equal, "Word32Equal", kEqual, kNotEqual},
1395     {&RawMachineAssembler::Int32LessThan, "Int32LessThan", kSignedLessThan,
1396      kSignedGreaterThanOrEqual},
1397     {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
1398      kSignedLessThanOrEqual, kSignedGreaterThan},
1399     {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kUnsignedLessThan,
1400      kUnsignedGreaterThanOrEqual},
1401     {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
1402      kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
1403
1404 }  // namespace
1405
1406
1407 typedef InstructionSelectorTestWithParam<Comparison>
1408     InstructionSelectorComparisonTest;
1409
1410
1411 TEST_P(InstructionSelectorComparisonTest, Parameters) {
1412   const Comparison& cmp = GetParam();
1413   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1414   Node* const p0 = m.Parameter(0);
1415   Node* const p1 = m.Parameter(1);
1416   Node* const r = (m.*cmp.constructor)(p0, p1);
1417   m.Return(r);
1418   Stream const s = m.Build();
1419   ASSERT_EQ(1U, s.size());
1420   EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1421   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1422   ASSERT_EQ(2U, s[0]->InputCount());
1423   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1424   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1425   ASSERT_EQ(1U, s[0]->OutputCount());
1426   EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1427   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1428   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1429 }
1430
1431
1432 TEST_P(InstructionSelectorComparisonTest, Word32EqualWithZero) {
1433   {
1434     const Comparison& cmp = GetParam();
1435     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1436     Node* const p0 = m.Parameter(0);
1437     Node* const p1 = m.Parameter(1);
1438     Node* const r =
1439         m.Word32Equal((m.*cmp.constructor)(p0, p1), m.Int32Constant(0));
1440     m.Return(r);
1441     Stream const s = m.Build();
1442     ASSERT_EQ(1U, s.size());
1443     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1444     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1445     ASSERT_EQ(2U, s[0]->InputCount());
1446     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1447     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1448     ASSERT_EQ(1U, s[0]->OutputCount());
1449     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1450     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1451     EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1452   }
1453   {
1454     const Comparison& cmp = GetParam();
1455     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1456     Node* const p0 = m.Parameter(0);
1457     Node* const p1 = m.Parameter(1);
1458     Node* const r =
1459         m.Word32Equal(m.Int32Constant(0), (m.*cmp.constructor)(p0, p1));
1460     m.Return(r);
1461     Stream const s = m.Build();
1462     ASSERT_EQ(1U, s.size());
1463     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1464     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1465     ASSERT_EQ(2U, s[0]->InputCount());
1466     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1467     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1468     ASSERT_EQ(1U, s[0]->OutputCount());
1469     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1470     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1471     EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1472   }
1473 }
1474
1475
1476 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1477                         InstructionSelectorComparisonTest,
1478                         ::testing::ValuesIn(kComparisons));
1479
1480
1481 // -----------------------------------------------------------------------------
1482 // Floating point comparisons.
1483
1484
1485 const Comparison kFPComparisons[] = {
1486     {&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual},
1487     {&RawMachineAssembler::Float64LessThan, "Float64LessThan",
1488      kUnsignedLessThan, kUnsignedGreaterThanOrEqual},
1489     {&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
1490      kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
1491
1492
1493 typedef InstructionSelectorTestWithParam<Comparison>
1494     InstructionSelectorFPComparisonTest;
1495
1496
1497 TEST_P(InstructionSelectorFPComparisonTest, WithParameters) {
1498   const Comparison& cmp = GetParam();
1499   StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
1500   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
1501   Stream const s = m.Build();
1502   ASSERT_EQ(1U, s.size());
1503   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1504   ASSERT_EQ(2U, s[0]->InputCount());
1505   ASSERT_EQ(1U, s[0]->OutputCount());
1506   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1507   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1508 }
1509
1510
1511 TEST_P(InstructionSelectorFPComparisonTest, NegatedWithParameters) {
1512   const Comparison& cmp = GetParam();
1513   StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
1514   m.Return(
1515       m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))));
1516   Stream const s = m.Build();
1517   ASSERT_EQ(1U, s.size());
1518   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1519   ASSERT_EQ(2U, s[0]->InputCount());
1520   ASSERT_EQ(1U, s[0]->OutputCount());
1521   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1522   EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1523 }
1524
1525
1526 TEST_P(InstructionSelectorFPComparisonTest, WithImmediateZeroOnRight) {
1527   const Comparison& cmp = GetParam();
1528   StreamBuilder m(this, kMachInt32, kMachFloat64);
1529   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0)));
1530   Stream const s = m.Build();
1531   ASSERT_EQ(1U, s.size());
1532   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1533   ASSERT_EQ(2U, s[0]->InputCount());
1534   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1535   ASSERT_EQ(1U, s[0]->OutputCount());
1536   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1537   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1538 }
1539
1540
1541 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1542                         InstructionSelectorFPComparisonTest,
1543                         ::testing::ValuesIn(kFPComparisons));
1544
1545
1546 TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) {
1547   StreamBuilder m(this, kMachInt32, kMachFloat64);
1548   m.Return(m.Float64Equal(m.Float64Constant(0.0), m.Parameter(0)));
1549   Stream s = m.Build();
1550   ASSERT_EQ(1U, s.size());
1551   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1552   EXPECT_EQ(2U, s[0]->InputCount());
1553   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1554   EXPECT_EQ(1U, s[0]->OutputCount());
1555   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1556   EXPECT_EQ(kEqual, s[0]->flags_condition());
1557 }
1558
1559
1560 // -----------------------------------------------------------------------------
1561 // Miscellaneous.
1562
1563
1564 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
1565   StreamBuilder m(this, kMachFloat64, kMachFloat64);
1566   Node* const p0 = m.Parameter(0);
1567   Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
1568   m.Return(n);
1569   Stream s = m.Build();
1570   ASSERT_EQ(1U, s.size());
1571   EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
1572   ASSERT_EQ(1U, s[0]->InputCount());
1573   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1574   ASSERT_EQ(1U, s[0]->OutputCount());
1575   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1576 }
1577
1578
1579 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
1580   {
1581     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1582     Node* const p0 = m.Parameter(0);
1583     Node* const p1 = m.Parameter(1);
1584     Node* const p2 = m.Parameter(2);
1585     Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2));
1586     m.Return(n);
1587     Stream s = m.Build();
1588     ASSERT_EQ(1U, s.size());
1589     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1590     ASSERT_EQ(3U, s[0]->InputCount());
1591     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1592     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1593     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1594     ASSERT_EQ(1U, s[0]->OutputCount());
1595     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1596   }
1597   {
1598     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1599     Node* const p0 = m.Parameter(0);
1600     Node* const p1 = m.Parameter(1);
1601     Node* const p2 = m.Parameter(2);
1602     Node* const n = m.Int32Add(m.Int32Mul(p1, p2), p0);
1603     m.Return(n);
1604     Stream s = m.Build();
1605     ASSERT_EQ(1U, s.size());
1606     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1607     ASSERT_EQ(3U, s[0]->InputCount());
1608     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1609     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1610     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1611     ASSERT_EQ(1U, s[0]->OutputCount());
1612     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1613   }
1614 }
1615
1616
1617 TEST_F(InstructionSelectorTest, Int32AddWithInt32MulHigh) {
1618   {
1619     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1620     Node* const p0 = m.Parameter(0);
1621     Node* const p1 = m.Parameter(1);
1622     Node* const p2 = m.Parameter(2);
1623     Node* const n = m.Int32Add(p0, m.Int32MulHigh(p1, p2));
1624     m.Return(n);
1625     Stream s = m.Build();
1626     ASSERT_EQ(1U, s.size());
1627     EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
1628     ASSERT_EQ(3U, s[0]->InputCount());
1629     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1630     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1631     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1632     ASSERT_EQ(1U, s[0]->OutputCount());
1633     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1634   }
1635   {
1636     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1637     Node* const p0 = m.Parameter(0);
1638     Node* const p1 = m.Parameter(1);
1639     Node* const p2 = m.Parameter(2);
1640     Node* const n = m.Int32Add(m.Int32MulHigh(p1, p2), p0);
1641     m.Return(n);
1642     Stream s = m.Build();
1643     ASSERT_EQ(1U, s.size());
1644     EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
1645     ASSERT_EQ(3U, s[0]->InputCount());
1646     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1647     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1648     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1649     ASSERT_EQ(1U, s[0]->OutputCount());
1650     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1651   }
1652 }
1653
1654
1655 TEST_F(InstructionSelectorTest, Int32AddWithWord32And) {
1656   {
1657     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1658     Node* const p0 = m.Parameter(0);
1659     Node* const p1 = m.Parameter(1);
1660     Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xff)), p1);
1661     m.Return(r);
1662     Stream s = m.Build();
1663     ASSERT_EQ(1U, s.size());
1664     EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
1665     ASSERT_EQ(3U, s[0]->InputCount());
1666     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1667     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1668     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1669     ASSERT_EQ(1U, s[0]->OutputCount());
1670     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1671   }
1672   {
1673     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1674     Node* const p0 = m.Parameter(0);
1675     Node* const p1 = m.Parameter(1);
1676     Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xff)));
1677     m.Return(r);
1678     Stream s = m.Build();
1679     ASSERT_EQ(1U, s.size());
1680     EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
1681     ASSERT_EQ(3U, s[0]->InputCount());
1682     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1683     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1684     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1685     ASSERT_EQ(1U, s[0]->OutputCount());
1686     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1687   }
1688   {
1689     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1690     Node* const p0 = m.Parameter(0);
1691     Node* const p1 = m.Parameter(1);
1692     Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xffff)), p1);
1693     m.Return(r);
1694     Stream s = m.Build();
1695     ASSERT_EQ(1U, s.size());
1696     EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
1697     ASSERT_EQ(3U, s[0]->InputCount());
1698     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1699     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1700     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1701     ASSERT_EQ(1U, s[0]->OutputCount());
1702     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1703   }
1704   {
1705     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1706     Node* const p0 = m.Parameter(0);
1707     Node* const p1 = m.Parameter(1);
1708     Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xffff)));
1709     m.Return(r);
1710     Stream s = m.Build();
1711     ASSERT_EQ(1U, s.size());
1712     EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
1713     ASSERT_EQ(3U, s[0]->InputCount());
1714     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1715     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1716     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1717     ASSERT_EQ(1U, s[0]->OutputCount());
1718     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1719   }
1720 }
1721
1722
1723 TEST_F(InstructionSelectorTest, Int32AddWithWord32SarWithWord32Shl) {
1724   {
1725     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1726     Node* const p0 = m.Parameter(0);
1727     Node* const p1 = m.Parameter(1);
1728     Node* const r = m.Int32Add(
1729         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)),
1730         p1);
1731     m.Return(r);
1732     Stream s = m.Build();
1733     ASSERT_EQ(1U, s.size());
1734     EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
1735     ASSERT_EQ(3U, s[0]->InputCount());
1736     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1737     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1738     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1739     ASSERT_EQ(1U, s[0]->OutputCount());
1740     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1741   }
1742   {
1743     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1744     Node* const p0 = m.Parameter(0);
1745     Node* const p1 = m.Parameter(1);
1746     Node* const r = m.Int32Add(
1747         p1,
1748         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)));
1749     m.Return(r);
1750     Stream s = m.Build();
1751     ASSERT_EQ(1U, s.size());
1752     EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
1753     ASSERT_EQ(3U, s[0]->InputCount());
1754     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1755     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1756     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1757     ASSERT_EQ(1U, s[0]->OutputCount());
1758     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1759   }
1760   {
1761     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1762     Node* const p0 = m.Parameter(0);
1763     Node* const p1 = m.Parameter(1);
1764     Node* const r = m.Int32Add(
1765         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)),
1766         p1);
1767     m.Return(r);
1768     Stream s = m.Build();
1769     ASSERT_EQ(1U, s.size());
1770     EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
1771     ASSERT_EQ(3U, s[0]->InputCount());
1772     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1773     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1774     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1775     ASSERT_EQ(1U, s[0]->OutputCount());
1776     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1777   }
1778   {
1779     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1780     Node* const p0 = m.Parameter(0);
1781     Node* const p1 = m.Parameter(1);
1782     Node* const r = m.Int32Add(
1783         p1,
1784         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)));
1785     m.Return(r);
1786     Stream s = m.Build();
1787     ASSERT_EQ(1U, s.size());
1788     EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
1789     ASSERT_EQ(3U, s[0]->InputCount());
1790     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1791     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1792     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1793     ASSERT_EQ(1U, s[0]->OutputCount());
1794     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1795   }
1796 }
1797
1798
1799 TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
1800   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1801   m.Return(
1802       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1803   Stream s = m.Build();
1804   ASSERT_EQ(2U, s.size());
1805   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1806   ASSERT_EQ(1U, s[0]->OutputCount());
1807   EXPECT_EQ(kArmSub, s[1]->arch_opcode());
1808   ASSERT_EQ(2U, s[1]->InputCount());
1809   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
1810 }
1811
1812
1813 TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
1814   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1815   m.Return(
1816       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1817   Stream s = m.Build(MLS);
1818   ASSERT_EQ(1U, s.size());
1819   EXPECT_EQ(kArmMls, s[0]->arch_opcode());
1820   EXPECT_EQ(1U, s[0]->OutputCount());
1821   EXPECT_EQ(3U, s[0]->InputCount());
1822 }
1823
1824
1825 TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
1826   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1827   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1828   Stream s = m.Build();
1829   ASSERT_EQ(4U, s.size());
1830   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1831   ASSERT_EQ(1U, s[0]->OutputCount());
1832   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1833   ASSERT_EQ(1U, s[1]->OutputCount());
1834   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1835   ASSERT_EQ(2U, s[2]->InputCount());
1836   ASSERT_EQ(1U, s[2]->OutputCount());
1837   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1838   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1839   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1840   ASSERT_EQ(1U, s[3]->InputCount());
1841   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1842 }
1843
1844
1845 TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
1846   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1847   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1848   Stream s = m.Build(SUDIV);
1849   ASSERT_EQ(1U, s.size());
1850   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1851 }
1852
1853
1854 TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
1855   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1856   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1857   Stream s = m.Build();
1858   ASSERT_EQ(6U, s.size());
1859   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1860   ASSERT_EQ(1U, s[0]->OutputCount());
1861   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1862   ASSERT_EQ(1U, s[1]->OutputCount());
1863   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1864   ASSERT_EQ(2U, s[2]->InputCount());
1865   ASSERT_EQ(1U, s[2]->OutputCount());
1866   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1867   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1868   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1869   ASSERT_EQ(1U, s[3]->InputCount());
1870   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1871   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1872   ASSERT_EQ(1U, s[4]->OutputCount());
1873   ASSERT_EQ(2U, s[4]->InputCount());
1874   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1875   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1876   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1877   ASSERT_EQ(1U, s[5]->OutputCount());
1878   ASSERT_EQ(2U, s[5]->InputCount());
1879   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1880   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1881 }
1882
1883
1884 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
1885   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1886   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1887   Stream s = m.Build(SUDIV);
1888   ASSERT_EQ(3U, s.size());
1889   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1890   ASSERT_EQ(1U, s[0]->OutputCount());
1891   ASSERT_EQ(2U, s[0]->InputCount());
1892   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1893   ASSERT_EQ(1U, s[1]->OutputCount());
1894   ASSERT_EQ(2U, s[1]->InputCount());
1895   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1896   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1897   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1898   ASSERT_EQ(1U, s[2]->OutputCount());
1899   ASSERT_EQ(2U, s[2]->InputCount());
1900   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1901   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1902 }
1903
1904
1905 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
1906   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1907   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1908   Stream s = m.Build(MLS, SUDIV);
1909   ASSERT_EQ(2U, s.size());
1910   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1911   ASSERT_EQ(1U, s[0]->OutputCount());
1912   ASSERT_EQ(2U, s[0]->InputCount());
1913   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1914   ASSERT_EQ(1U, s[1]->OutputCount());
1915   ASSERT_EQ(3U, s[1]->InputCount());
1916   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1917   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1918   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1919 }
1920
1921
1922 TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
1923   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1924   m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
1925   Stream s = m.Build();
1926   ASSERT_EQ(1U, s.size());
1927   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1928   EXPECT_EQ(2U, s[0]->InputCount());
1929   EXPECT_EQ(1U, s[0]->OutputCount());
1930 }
1931
1932
1933 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
1934   // x * (2^k + 1) -> x + (x >> k)
1935   TRACED_FORRANGE(int32_t, k, 1, 30) {
1936     StreamBuilder m(this, kMachInt32, kMachInt32);
1937     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
1938     Stream s = m.Build();
1939     ASSERT_EQ(1U, s.size());
1940     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1941     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1942     ASSERT_EQ(3U, s[0]->InputCount());
1943     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1944     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1945     EXPECT_EQ(1U, s[0]->OutputCount());
1946   }
1947   // x * (2^k - 1) -> -x + (x >> k)
1948   TRACED_FORRANGE(int32_t, k, 3, 30) {
1949     StreamBuilder m(this, kMachInt32, kMachInt32);
1950     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
1951     Stream s = m.Build();
1952     ASSERT_EQ(1U, s.size());
1953     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1954     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1955     ASSERT_EQ(3U, s[0]->InputCount());
1956     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1957     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1958     EXPECT_EQ(1U, s[0]->OutputCount());
1959   }
1960   // (2^k + 1) * x -> x + (x >> k)
1961   TRACED_FORRANGE(int32_t, k, 1, 30) {
1962     StreamBuilder m(this, kMachInt32, kMachInt32);
1963     m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
1964     Stream s = m.Build();
1965     ASSERT_EQ(1U, s.size());
1966     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1967     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1968     ASSERT_EQ(3U, s[0]->InputCount());
1969     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1970     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1971     EXPECT_EQ(1U, s[0]->OutputCount());
1972   }
1973   // x * (2^k - 1) -> -x + (x >> k)
1974   TRACED_FORRANGE(int32_t, k, 3, 30) {
1975     StreamBuilder m(this, kMachInt32, kMachInt32);
1976     m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
1977     Stream s = m.Build();
1978     ASSERT_EQ(1U, s.size());
1979     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1980     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1981     ASSERT_EQ(3U, s[0]->InputCount());
1982     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1983     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1984     EXPECT_EQ(1U, s[0]->OutputCount());
1985   }
1986 }
1987
1988
1989 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
1990   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1991   Node* const p0 = m.Parameter(0);
1992   Node* const p1 = m.Parameter(1);
1993   Node* const n = m.Int32MulHigh(p0, p1);
1994   m.Return(n);
1995   Stream s = m.Build();
1996   ASSERT_EQ(1U, s.size());
1997   EXPECT_EQ(kArmSmmul, s[0]->arch_opcode());
1998   ASSERT_EQ(2U, s[0]->InputCount());
1999   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2000   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2001   ASSERT_EQ(1U, s[0]->OutputCount());
2002   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
2003 }
2004
2005
2006 TEST_F(InstructionSelectorTest, Uint32MulHighWithParameters) {
2007   StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
2008   Node* const p0 = m.Parameter(0);
2009   Node* const p1 = m.Parameter(1);
2010   Node* const n = m.Uint32MulHigh(p0, p1);
2011   m.Return(n);
2012   Stream s = m.Build();
2013   ASSERT_EQ(1U, s.size());
2014   EXPECT_EQ(kArmUmull, s[0]->arch_opcode());
2015   ASSERT_EQ(2U, s[0]->InputCount());
2016   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2017   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2018   ASSERT_EQ(2U, s[0]->OutputCount());
2019   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->OutputAt(1)));
2020 }
2021
2022
2023 TEST_F(InstructionSelectorTest, Uint32DivWithParameters) {
2024   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2025   m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
2026   Stream s = m.Build();
2027   ASSERT_EQ(4U, s.size());
2028   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
2029   ASSERT_EQ(1U, s[0]->OutputCount());
2030   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
2031   ASSERT_EQ(1U, s[1]->OutputCount());
2032   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
2033   ASSERT_EQ(2U, s[2]->InputCount());
2034   ASSERT_EQ(1U, s[2]->OutputCount());
2035   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
2036   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2037   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
2038   ASSERT_EQ(1U, s[3]->InputCount());
2039   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
2040 }
2041
2042
2043 TEST_F(InstructionSelectorTest, Uint32DivWithParametersForSUDIV) {
2044   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2045   m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
2046   Stream s = m.Build(SUDIV);
2047   ASSERT_EQ(1U, s.size());
2048   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2049 }
2050
2051
2052 TEST_F(InstructionSelectorTest, Uint32ModWithParameters) {
2053   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2054   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2055   Stream s = m.Build();
2056   ASSERT_EQ(6U, s.size());
2057   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
2058   ASSERT_EQ(1U, s[0]->OutputCount());
2059   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
2060   ASSERT_EQ(1U, s[1]->OutputCount());
2061   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
2062   ASSERT_EQ(2U, s[2]->InputCount());
2063   ASSERT_EQ(1U, s[2]->OutputCount());
2064   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
2065   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2066   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
2067   ASSERT_EQ(1U, s[3]->InputCount());
2068   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
2069   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
2070   ASSERT_EQ(1U, s[4]->OutputCount());
2071   ASSERT_EQ(2U, s[4]->InputCount());
2072   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
2073   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
2074   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
2075   ASSERT_EQ(1U, s[5]->OutputCount());
2076   ASSERT_EQ(2U, s[5]->InputCount());
2077   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
2078   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
2079 }
2080
2081
2082 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIV) {
2083   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2084   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2085   Stream s = m.Build(SUDIV);
2086   ASSERT_EQ(3U, s.size());
2087   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2088   ASSERT_EQ(1U, s[0]->OutputCount());
2089   ASSERT_EQ(2U, s[0]->InputCount());
2090   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
2091   ASSERT_EQ(1U, s[1]->OutputCount());
2092   ASSERT_EQ(2U, s[1]->InputCount());
2093   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2094   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
2095   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
2096   ASSERT_EQ(1U, s[2]->OutputCount());
2097   ASSERT_EQ(2U, s[2]->InputCount());
2098   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
2099   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2100 }
2101
2102
2103 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIVAndMLS) {
2104   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2105   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2106   Stream s = m.Build(MLS, SUDIV);
2107   ASSERT_EQ(2U, s.size());
2108   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2109   ASSERT_EQ(1U, s[0]->OutputCount());
2110   ASSERT_EQ(2U, s[0]->InputCount());
2111   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
2112   ASSERT_EQ(1U, s[1]->OutputCount());
2113   ASSERT_EQ(3U, s[1]->InputCount());
2114   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2115   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
2116   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
2117 }
2118
2119
2120 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
2121   TRACED_FORRANGE(int32_t, width, 1, 32) {
2122     StreamBuilder m(this, kMachInt32, kMachInt32);
2123     m.Return(m.Word32And(m.Parameter(0),
2124                          m.Int32Constant(0xffffffffu >> (32 - width))));
2125     Stream s = m.Build(ARMv7);
2126     ASSERT_EQ(1U, s.size());
2127     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2128     ASSERT_EQ(3U, s[0]->InputCount());
2129     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2130     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2131   }
2132   TRACED_FORRANGE(int32_t, width, 1, 32) {
2133     StreamBuilder m(this, kMachInt32, kMachInt32);
2134     m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
2135                          m.Parameter(0)));
2136     Stream s = m.Build(ARMv7);
2137     ASSERT_EQ(1U, s.size());
2138     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2139     ASSERT_EQ(3U, s[0]->InputCount());
2140     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2141     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2142   }
2143 }
2144
2145
2146 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
2147   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2148     TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
2149       StreamBuilder m(this, kMachInt32, kMachInt32);
2150       m.Return(m.Word32And(
2151           m.Parameter(0),
2152           m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
2153       Stream s = m.Build(ARMv7);
2154       ASSERT_EQ(1U, s.size());
2155       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
2156       ASSERT_EQ(1U, s[0]->OutputCount());
2157       EXPECT_TRUE(
2158           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
2159       ASSERT_EQ(3U, s[0]->InputCount());
2160       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2161       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2162     }
2163   }
2164   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2165     TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
2166       StreamBuilder m(this, kMachInt32, kMachInt32);
2167       m.Return(
2168           m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
2169                       m.Parameter(0)));
2170       Stream s = m.Build(ARMv7);
2171       ASSERT_EQ(1U, s.size());
2172       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
2173       ASSERT_EQ(1U, s[0]->OutputCount());
2174       EXPECT_TRUE(
2175           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
2176       ASSERT_EQ(3U, s[0]->InputCount());
2177       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2178       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2179     }
2180   }
2181 }
2182
2183
2184 TEST_F(InstructionSelectorTest, Word32AndWith0xffff) {
2185   {
2186     StreamBuilder m(this, kMachInt32, kMachInt32);
2187     Node* const p0 = m.Parameter(0);
2188     Node* const r = m.Word32And(p0, m.Int32Constant(0xffff));
2189     m.Return(r);
2190     Stream s = m.Build();
2191     ASSERT_EQ(1U, s.size());
2192     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
2193     ASSERT_EQ(2U, s[0]->InputCount());
2194     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2195     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2196     ASSERT_EQ(1U, s[0]->OutputCount());
2197     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2198   }
2199   {
2200     StreamBuilder m(this, kMachInt32, kMachInt32);
2201     Node* const p0 = m.Parameter(0);
2202     Node* const r = m.Word32And(m.Int32Constant(0xffff), p0);
2203     m.Return(r);
2204     Stream s = m.Build();
2205     ASSERT_EQ(1U, s.size());
2206     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
2207     ASSERT_EQ(2U, s[0]->InputCount());
2208     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2209     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2210     ASSERT_EQ(1U, s[0]->OutputCount());
2211     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2212   }
2213 }
2214
2215
2216 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
2217   {
2218     StreamBuilder m(this, kMachInt32, kMachInt32);
2219     Node* const p0 = m.Parameter(0);
2220     Node* const r =
2221         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
2222     m.Return(r);
2223     Stream s = m.Build();
2224     ASSERT_EQ(1U, s.size());
2225     EXPECT_EQ(kArmSxtb, s[0]->arch_opcode());
2226     ASSERT_EQ(2U, s[0]->InputCount());
2227     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2228     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2229     ASSERT_EQ(1U, s[0]->OutputCount());
2230     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2231   }
2232   {
2233     StreamBuilder m(this, kMachInt32, kMachInt32);
2234     Node* const p0 = m.Parameter(0);
2235     Node* const r =
2236         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
2237     m.Return(r);
2238     Stream s = m.Build();
2239     ASSERT_EQ(1U, s.size());
2240     EXPECT_EQ(kArmSxth, s[0]->arch_opcode());
2241     ASSERT_EQ(2U, s[0]->InputCount());
2242     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2243     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2244     ASSERT_EQ(1U, s[0]->OutputCount());
2245     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2246   }
2247 }
2248
2249
2250 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
2251   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2252     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2253       uint32_t max = 1 << lsb;
2254       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
2255       uint32_t jnk = rng()->NextInt(max);
2256       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2257       StreamBuilder m(this, kMachInt32, kMachInt32);
2258       m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
2259                            m.Int32Constant(lsb)));
2260       Stream s = m.Build(ARMv7);
2261       ASSERT_EQ(1U, s.size());
2262       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2263       ASSERT_EQ(3U, s[0]->InputCount());
2264       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2265       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2266     }
2267   }
2268   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2269     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2270       uint32_t max = 1 << lsb;
2271       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
2272       uint32_t jnk = rng()->NextInt(max);
2273       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2274       StreamBuilder m(this, kMachInt32, kMachInt32);
2275       m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
2276                            m.Int32Constant(lsb)));
2277       Stream s = m.Build(ARMv7);
2278       ASSERT_EQ(1U, s.size());
2279       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2280       ASSERT_EQ(3U, s[0]->InputCount());
2281       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2282       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2283     }
2284   }
2285 }
2286
2287
2288 TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
2289   {
2290     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2291     m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
2292     Stream s = m.Build();
2293     ASSERT_EQ(1U, s.size());
2294     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
2295     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2296     EXPECT_EQ(2U, s[0]->InputCount());
2297     EXPECT_EQ(1U, s[0]->OutputCount());
2298   }
2299   {
2300     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2301     m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
2302     Stream s = m.Build();
2303     ASSERT_EQ(1U, s.size());
2304     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
2305     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2306     EXPECT_EQ(2U, s[0]->InputCount());
2307     EXPECT_EQ(1U, s[0]->OutputCount());
2308   }
2309 }
2310
2311
2312 TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
2313   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2314   m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
2315   Stream s = m.Build();
2316   ASSERT_EQ(1U, s.size());
2317   EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2318   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2319   EXPECT_EQ(2U, s[0]->InputCount());
2320   EXPECT_EQ(1U, s[0]->OutputCount());
2321   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2322   EXPECT_EQ(kEqual, s[0]->flags_condition());
2323 }
2324
2325
2326 TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
2327   TRACED_FOREACH(int32_t, imm, kImmediates) {
2328     if (imm == 0) continue;
2329     StreamBuilder m(this, kMachInt32, kMachInt32);
2330     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
2331     Stream s = m.Build();
2332     ASSERT_EQ(1U, s.size());
2333     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2334     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
2335     ASSERT_EQ(2U, s[0]->InputCount());
2336     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
2337     EXPECT_EQ(1U, s[0]->OutputCount());
2338     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2339     EXPECT_EQ(kEqual, s[0]->flags_condition());
2340   }
2341   TRACED_FOREACH(int32_t, imm, kImmediates) {
2342     if (imm == 0) continue;
2343     StreamBuilder m(this, kMachInt32, kMachInt32);
2344     m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
2345     Stream s = m.Build();
2346     ASSERT_EQ(1U, s.size());
2347     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2348     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
2349     ASSERT_EQ(2U, s[0]->InputCount());
2350     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
2351     EXPECT_EQ(1U, s[0]->OutputCount());
2352     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2353     EXPECT_EQ(kEqual, s[0]->flags_condition());
2354   }
2355 }
2356
2357
2358 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
2359   {
2360     StreamBuilder m(this, kMachInt32, kMachInt32);
2361     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
2362     Stream s = m.Build();
2363     ASSERT_EQ(1U, s.size());
2364     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
2365     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2366     ASSERT_EQ(2U, s[0]->InputCount());
2367     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2368     EXPECT_EQ(1U, s[0]->OutputCount());
2369     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2370     EXPECT_EQ(kEqual, s[0]->flags_condition());
2371   }
2372   {
2373     StreamBuilder m(this, kMachInt32, kMachInt32);
2374     m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
2375     Stream s = m.Build();
2376     ASSERT_EQ(1U, s.size());
2377     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
2378     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2379     ASSERT_EQ(2U, s[0]->InputCount());
2380     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2381     EXPECT_EQ(1U, s[0]->OutputCount());
2382     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2383     EXPECT_EQ(kEqual, s[0]->flags_condition());
2384   }
2385 }
2386
2387
2388 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
2389   StreamBuilder m(this, kMachInt32, kMachInt32);
2390   m.Return(m.Word32Not(m.Parameter(0)));
2391   Stream s = m.Build();
2392   ASSERT_EQ(1U, s.size());
2393   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
2394   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2395   EXPECT_EQ(1U, s[0]->InputCount());
2396   EXPECT_EQ(1U, s[0]->OutputCount());
2397 }
2398
2399
2400 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
2401   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2402     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2403       StreamBuilder m(this, kMachInt32, kMachInt32);
2404       m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
2405                            m.Int32Constant(0xffffffffu >> (32 - width))));
2406       Stream s = m.Build(ARMv7);
2407       ASSERT_EQ(1U, s.size());
2408       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2409       ASSERT_EQ(3U, s[0]->InputCount());
2410       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2411       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2412     }
2413   }
2414   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2415     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2416       StreamBuilder m(this, kMachInt32, kMachInt32);
2417       m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
2418                            m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
2419       Stream s = m.Build(ARMv7);
2420       ASSERT_EQ(1U, s.size());
2421       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2422       ASSERT_EQ(3U, s[0]->InputCount());
2423       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2424       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2425     }
2426   }
2427 }
2428
2429 }  // namespace compiler
2430 }  // namespace internal
2431 }  // namespace v8