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 "src/compiler/instruction-selector-unittest.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
11 namespace {
12 
13 typedef RawMachineAssembler::Label MLabel;
14 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
15 
16 
17 // Data processing instructions.
18 struct DPI {
19   Constructor constructor;
20   const char* constructor_name;
21   ArchOpcode arch_opcode;
22   ArchOpcode reverse_arch_opcode;
23   ArchOpcode test_arch_opcode;
24 };
25 
26 
operator <<(std::ostream & os,const DPI & dpi)27 std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
28   return os << dpi.constructor_name;
29 }
30 
31 
32 static const DPI kDPIs[] = {
33     {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
34     {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
35     {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
36     {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
37     {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
38 
39 
40 // Data processing instructions with overflow.
41 struct ODPI {
42   Constructor constructor;
43   const char* constructor_name;
44   ArchOpcode arch_opcode;
45   ArchOpcode reverse_arch_opcode;
46 };
47 
48 
operator <<(std::ostream & os,const ODPI & odpi)49 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
50   return os << odpi.constructor_name;
51 }
52 
53 
54 static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
55                                "Int32AddWithOverflow", kArmAdd, kArmAdd},
56                               {&RawMachineAssembler::Int32SubWithOverflow,
57                                "Int32SubWithOverflow", kArmSub, kArmRsb}};
58 
59 
60 // Shifts.
61 struct Shift {
62   Constructor constructor;
63   const char* constructor_name;
64   int32_t i_low;          // lowest possible immediate
65   int32_t i_high;         // highest possible immediate
66   AddressingMode i_mode;  // Operand2_R_<shift>_I
67   AddressingMode r_mode;  // Operand2_R_<shift>_R
68 };
69 
70 
operator <<(std::ostream & os,const Shift & shift)71 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
72   return os << shift.constructor_name;
73 }
74 
75 
76 static const Shift kShifts[] = {
77     {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
78      kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
79     {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
80      kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
81     {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
82      kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
83     {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
84      kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
85 
86 
87 // Immediates (random subset).
88 static const int32_t kImmediates[] = {
89     -2147483617, -2147483606, -2113929216, -2080374784, -1996488704,
90     -1879048192, -1459617792, -1358954496, -1342177265, -1275068414,
91     -1073741818, -1073741777, -855638016,  -805306368,  -402653184,
92     -268435444,  -16777216,   0,           35,          61,
93     105,         116,         171,         245,         255,
94     692,         1216,        1248,        1520,        1600,
95     1888,        3744,        4080,        5888,        8384,
96     9344,        9472,        9792,        13312,       15040,
97     15360,       20736,       22272,       23296,       32000,
98     33536,       37120,       45824,       47872,       56320,
99     59392,       65280,       72704,       101376,      147456,
100     161792,      164864,      167936,      173056,      195584,
101     209920,      212992,      356352,      655360,      704512,
102     716800,      851968,      901120,      1044480,     1523712,
103     2572288,     3211264,     3588096,     3833856,     3866624,
104     4325376,     5177344,     6488064,     7012352,     7471104,
105     14090240,    16711680,    19398656,    22282240,    28573696,
106     30408704,    30670848,    43253760,    54525952,    55312384,
107     56623104,    68157440,    115343360,   131072000,   187695104,
108     188743680,   195035136,   197132288,   203423744,   218103808,
109     267386880,   268435470,   285212672,   402653185,   415236096,
110     595591168,   603979776,   603979778,   629145600,   1073741835,
111     1073741855,  1073741861,  1073741884,  1157627904,  1476395008,
112     1476395010,  1610612741,  2030043136,  2080374785,  2097152000};
113 
114 }  // namespace
115 
116 
117 // -----------------------------------------------------------------------------
118 // Data processing instructions.
119 
120 
121 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
122 
123 
TEST_P(InstructionSelectorDPITest,Parameters)124 TEST_P(InstructionSelectorDPITest, Parameters) {
125   const DPI dpi = GetParam();
126   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
127   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
128   Stream s = m.Build();
129   ASSERT_EQ(1U, s.size());
130   EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
131   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
132   EXPECT_EQ(2U, s[0]->InputCount());
133   EXPECT_EQ(1U, s[0]->OutputCount());
134 }
135 
136 
TEST_P(InstructionSelectorDPITest,Immediate)137 TEST_P(InstructionSelectorDPITest, Immediate) {
138   const DPI dpi = GetParam();
139   TRACED_FOREACH(int32_t, imm, kImmediates) {
140     StreamBuilder m(this, kMachInt32, kMachInt32);
141     m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
142     Stream s = m.Build();
143     ASSERT_EQ(1U, s.size());
144     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
145     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
146     ASSERT_EQ(2U, s[0]->InputCount());
147     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
148     EXPECT_EQ(1U, s[0]->OutputCount());
149   }
150   TRACED_FOREACH(int32_t, imm, kImmediates) {
151     StreamBuilder m(this, kMachInt32, kMachInt32);
152     m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
153     Stream s = m.Build();
154     ASSERT_EQ(1U, s.size());
155     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
156     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
157     ASSERT_EQ(2U, s[0]->InputCount());
158     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
159     EXPECT_EQ(1U, s[0]->OutputCount());
160   }
161 }
162 
163 
TEST_P(InstructionSelectorDPITest,ShiftByParameter)164 TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
165   const DPI dpi = GetParam();
166   TRACED_FOREACH(Shift, shift, kShifts) {
167     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
168     m.Return((m.*dpi.constructor)(
169         m.Parameter(0),
170         (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
171     Stream s = m.Build();
172     ASSERT_EQ(1U, s.size());
173     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
174     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
175     EXPECT_EQ(3U, s[0]->InputCount());
176     EXPECT_EQ(1U, s[0]->OutputCount());
177   }
178   TRACED_FOREACH(Shift, shift, kShifts) {
179     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
180     m.Return((m.*dpi.constructor)(
181         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
182         m.Parameter(2)));
183     Stream s = m.Build();
184     ASSERT_EQ(1U, s.size());
185     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
186     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
187     EXPECT_EQ(3U, s[0]->InputCount());
188     EXPECT_EQ(1U, s[0]->OutputCount());
189   }
190 }
191 
192 
TEST_P(InstructionSelectorDPITest,ShiftByImmediate)193 TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
194   const DPI dpi = GetParam();
195   TRACED_FOREACH(Shift, shift, kShifts) {
196     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
197       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
198       m.Return((m.*dpi.constructor)(
199           m.Parameter(0),
200           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
201       Stream s = m.Build();
202       ASSERT_EQ(1U, s.size());
203       EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
204       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
205       ASSERT_EQ(3U, s[0]->InputCount());
206       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
207       EXPECT_EQ(1U, s[0]->OutputCount());
208     }
209   }
210   TRACED_FOREACH(Shift, shift, kShifts) {
211     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
212       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
213       m.Return((m.*dpi.constructor)(
214           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
215           m.Parameter(1)));
216       Stream s = m.Build();
217       ASSERT_EQ(1U, s.size());
218       EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
219       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
220       ASSERT_EQ(3U, s[0]->InputCount());
221       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
222       EXPECT_EQ(1U, s[0]->OutputCount());
223     }
224   }
225 }
226 
227 
TEST_P(InstructionSelectorDPITest,BranchWithParameters)228 TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
229   const DPI dpi = GetParam();
230   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
231   MLabel a, b;
232   m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
233   m.Bind(&a);
234   m.Return(m.Int32Constant(1));
235   m.Bind(&b);
236   m.Return(m.Int32Constant(0));
237   Stream s = m.Build();
238   ASSERT_EQ(1U, s.size());
239   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
240   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
241   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
242   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
243 }
244 
245 
TEST_P(InstructionSelectorDPITest,BranchWithImmediate)246 TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
247   const DPI dpi = GetParam();
248   TRACED_FOREACH(int32_t, imm, kImmediates) {
249     StreamBuilder m(this, kMachInt32, kMachInt32);
250     MLabel a, b;
251     m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
252              &b);
253     m.Bind(&a);
254     m.Return(m.Int32Constant(1));
255     m.Bind(&b);
256     m.Return(m.Int32Constant(0));
257     Stream s = m.Build();
258     ASSERT_EQ(1U, s.size());
259     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
260     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
261     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
262     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
263   }
264   TRACED_FOREACH(int32_t, imm, kImmediates) {
265     StreamBuilder m(this, kMachInt32, kMachInt32);
266     MLabel a, b;
267     m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
268              &b);
269     m.Bind(&a);
270     m.Return(m.Int32Constant(1));
271     m.Bind(&b);
272     m.Return(m.Int32Constant(0));
273     Stream s = m.Build();
274     ASSERT_EQ(1U, s.size());
275     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
276     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
277     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
278     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
279   }
280 }
281 
282 
TEST_P(InstructionSelectorDPITest,BranchWithShiftByParameter)283 TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
284   const DPI dpi = GetParam();
285   TRACED_FOREACH(Shift, shift, kShifts) {
286     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
287     MLabel a, b;
288     m.Branch((m.*dpi.constructor)(
289                  m.Parameter(0),
290                  (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
291              &a, &b);
292     m.Bind(&a);
293     m.Return(m.Int32Constant(1));
294     m.Bind(&b);
295     m.Return(m.Int32Constant(0));
296     Stream s = m.Build();
297     ASSERT_EQ(1U, s.size());
298     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
299     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
300     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
301     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
302   }
303   TRACED_FOREACH(Shift, shift, kShifts) {
304     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
305     MLabel a, b;
306     m.Branch((m.*dpi.constructor)(
307                  (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
308                  m.Parameter(2)),
309              &a, &b);
310     m.Bind(&a);
311     m.Return(m.Int32Constant(1));
312     m.Bind(&b);
313     m.Return(m.Int32Constant(0));
314     Stream s = m.Build();
315     ASSERT_EQ(1U, s.size());
316     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
317     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
318     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
319     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
320   }
321 }
322 
323 
TEST_P(InstructionSelectorDPITest,BranchWithShiftByImmediate)324 TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
325   const DPI dpi = GetParam();
326   TRACED_FOREACH(Shift, shift, kShifts) {
327     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
328       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
329       MLabel a, b;
330       m.Branch((m.*dpi.constructor)(m.Parameter(0),
331                                     (m.*shift.constructor)(
332                                         m.Parameter(1), m.Int32Constant(imm))),
333                &a, &b);
334       m.Bind(&a);
335       m.Return(m.Int32Constant(1));
336       m.Bind(&b);
337       m.Return(m.Int32Constant(0));
338       Stream s = m.Build();
339       ASSERT_EQ(1U, s.size());
340       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
341       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
342       ASSERT_EQ(5U, s[0]->InputCount());
343       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
344       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
345       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
346     }
347   }
348   TRACED_FOREACH(Shift, shift, kShifts) {
349     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
350       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
351       MLabel a, b;
352       m.Branch((m.*dpi.constructor)(
353                    (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
354                    m.Parameter(1)),
355                &a, &b);
356       m.Bind(&a);
357       m.Return(m.Int32Constant(1));
358       m.Bind(&b);
359       m.Return(m.Int32Constant(0));
360       Stream s = m.Build();
361       ASSERT_EQ(1U, s.size());
362       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
363       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
364       ASSERT_EQ(5U, s[0]->InputCount());
365       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
366       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
367       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
368     }
369   }
370 }
371 
372 
TEST_P(InstructionSelectorDPITest,BranchIfZeroWithParameters)373 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
374   const DPI dpi = GetParam();
375   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
376   MLabel a, b;
377   m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
378                          m.Int32Constant(0)),
379            &a, &b);
380   m.Bind(&a);
381   m.Return(m.Int32Constant(1));
382   m.Bind(&b);
383   m.Return(m.Int32Constant(0));
384   Stream s = m.Build();
385   ASSERT_EQ(1U, s.size());
386   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
387   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
388   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
389   EXPECT_EQ(kEqual, s[0]->flags_condition());
390 }
391 
392 
TEST_P(InstructionSelectorDPITest,BranchIfNotZeroWithParameters)393 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
394   const DPI dpi = GetParam();
395   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
396   MLabel a, b;
397   m.Branch(
398       m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
399                        m.Int32Constant(0)),
400       &a, &b);
401   m.Bind(&a);
402   m.Return(m.Int32Constant(1));
403   m.Bind(&b);
404   m.Return(m.Int32Constant(0));
405   Stream s = m.Build();
406   ASSERT_EQ(1U, s.size());
407   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
408   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
409   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
410   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
411 }
412 
413 
TEST_P(InstructionSelectorDPITest,BranchIfZeroWithImmediate)414 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
415   const DPI dpi = GetParam();
416   TRACED_FOREACH(int32_t, imm, kImmediates) {
417     StreamBuilder m(this, kMachInt32, kMachInt32);
418     MLabel a, b;
419     m.Branch(m.Word32Equal(
420                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
421                  m.Int32Constant(0)),
422              &a, &b);
423     m.Bind(&a);
424     m.Return(m.Int32Constant(1));
425     m.Bind(&b);
426     m.Return(m.Int32Constant(0));
427     Stream s = m.Build();
428     ASSERT_EQ(1U, s.size());
429     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
430     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
431     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
432     EXPECT_EQ(kEqual, s[0]->flags_condition());
433   }
434   TRACED_FOREACH(int32_t, imm, kImmediates) {
435     StreamBuilder m(this, kMachInt32, kMachInt32);
436     MLabel a, b;
437     m.Branch(m.Word32Equal(
438                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
439                  m.Int32Constant(0)),
440              &a, &b);
441     m.Bind(&a);
442     m.Return(m.Int32Constant(1));
443     m.Bind(&b);
444     m.Return(m.Int32Constant(0));
445     Stream s = m.Build();
446     ASSERT_EQ(1U, s.size());
447     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
448     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
449     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
450     EXPECT_EQ(kEqual, s[0]->flags_condition());
451   }
452 }
453 
454 
TEST_P(InstructionSelectorDPITest,BranchIfNotZeroWithImmediate)455 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
456   const DPI dpi = GetParam();
457   TRACED_FOREACH(int32_t, imm, kImmediates) {
458     StreamBuilder m(this, kMachInt32, kMachInt32);
459     MLabel a, b;
460     m.Branch(m.Word32NotEqual(
461                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
462                  m.Int32Constant(0)),
463              &a, &b);
464     m.Bind(&a);
465     m.Return(m.Int32Constant(1));
466     m.Bind(&b);
467     m.Return(m.Int32Constant(0));
468     Stream s = m.Build();
469     ASSERT_EQ(1U, s.size());
470     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
471     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
472     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
473     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
474   }
475   TRACED_FOREACH(int32_t, imm, kImmediates) {
476     StreamBuilder m(this, kMachInt32, kMachInt32);
477     MLabel a, b;
478     m.Branch(m.Word32NotEqual(
479                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
480                  m.Int32Constant(0)),
481              &a, &b);
482     m.Bind(&a);
483     m.Return(m.Int32Constant(1));
484     m.Bind(&b);
485     m.Return(m.Int32Constant(0));
486     Stream s = m.Build();
487     ASSERT_EQ(1U, s.size());
488     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
489     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
490     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
491     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
492   }
493 }
494 
495 
496 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
497                         ::testing::ValuesIn(kDPIs));
498 
499 
500 // -----------------------------------------------------------------------------
501 // Data processing instructions with overflow.
502 
503 
504 typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
505 
506 
TEST_P(InstructionSelectorODPITest,OvfWithParameters)507 TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
508   const ODPI odpi = GetParam();
509   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
510   m.Return(
511       m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
512   Stream s = m.Build();
513   ASSERT_EQ(1U, s.size());
514   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
515   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
516   EXPECT_EQ(2U, s[0]->InputCount());
517   EXPECT_LE(1U, s[0]->OutputCount());
518   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
519   EXPECT_EQ(kOverflow, s[0]->flags_condition());
520 }
521 
522 
TEST_P(InstructionSelectorODPITest,OvfWithImmediate)523 TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
524   const ODPI odpi = GetParam();
525   TRACED_FOREACH(int32_t, imm, kImmediates) {
526     StreamBuilder m(this, kMachInt32, kMachInt32);
527     m.Return(m.Projection(
528         1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
529     Stream s = m.Build();
530     ASSERT_EQ(1U, s.size());
531     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
532     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
533     ASSERT_EQ(2U, s[0]->InputCount());
534     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
535     EXPECT_LE(1U, s[0]->OutputCount());
536     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
537     EXPECT_EQ(kOverflow, s[0]->flags_condition());
538   }
539   TRACED_FOREACH(int32_t, imm, kImmediates) {
540     StreamBuilder m(this, kMachInt32, kMachInt32);
541     m.Return(m.Projection(
542         1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
543     Stream s = m.Build();
544     ASSERT_EQ(1U, s.size());
545     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
546     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
547     ASSERT_EQ(2U, s[0]->InputCount());
548     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
549     EXPECT_LE(1U, s[0]->OutputCount());
550     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
551     EXPECT_EQ(kOverflow, s[0]->flags_condition());
552   }
553 }
554 
555 
TEST_P(InstructionSelectorODPITest,OvfWithShiftByParameter)556 TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
557   const ODPI odpi = GetParam();
558   TRACED_FOREACH(Shift, shift, kShifts) {
559     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
560     m.Return(m.Projection(
561         1, (m.*odpi.constructor)(
562                m.Parameter(0),
563                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
564     Stream s = m.Build();
565     ASSERT_EQ(1U, s.size());
566     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
567     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
568     EXPECT_EQ(3U, s[0]->InputCount());
569     EXPECT_LE(1U, s[0]->OutputCount());
570     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
571     EXPECT_EQ(kOverflow, s[0]->flags_condition());
572   }
573   TRACED_FOREACH(Shift, shift, kShifts) {
574     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
575     m.Return(m.Projection(
576         1, (m.*odpi.constructor)(
577                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
578                m.Parameter(0))));
579     Stream s = m.Build();
580     ASSERT_EQ(1U, s.size());
581     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
582     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
583     EXPECT_EQ(3U, s[0]->InputCount());
584     EXPECT_LE(1U, s[0]->OutputCount());
585     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
586     EXPECT_EQ(kOverflow, s[0]->flags_condition());
587   }
588 }
589 
590 
TEST_P(InstructionSelectorODPITest,OvfWithShiftByImmediate)591 TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
592   const ODPI odpi = GetParam();
593   TRACED_FOREACH(Shift, shift, kShifts) {
594     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
595       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
596       m.Return(m.Projection(
597           1, (m.*odpi.constructor)(m.Parameter(0),
598                                    (m.*shift.constructor)(
599                                        m.Parameter(1), m.Int32Constant(imm)))));
600       Stream s = m.Build();
601       ASSERT_EQ(1U, s.size());
602       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
603       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
604       ASSERT_EQ(3U, s[0]->InputCount());
605       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
606       EXPECT_LE(1U, s[0]->OutputCount());
607       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
608       EXPECT_EQ(kOverflow, s[0]->flags_condition());
609     }
610   }
611   TRACED_FOREACH(Shift, shift, kShifts) {
612     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
613       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
614       m.Return(m.Projection(
615           1, (m.*odpi.constructor)(
616                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
617                  m.Parameter(0))));
618       Stream s = m.Build();
619       ASSERT_EQ(1U, s.size());
620       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
621       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
622       ASSERT_EQ(3U, s[0]->InputCount());
623       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
624       EXPECT_LE(1U, s[0]->OutputCount());
625       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
626       EXPECT_EQ(kOverflow, s[0]->flags_condition());
627     }
628   }
629 }
630 
631 
TEST_P(InstructionSelectorODPITest,ValWithParameters)632 TEST_P(InstructionSelectorODPITest, ValWithParameters) {
633   const ODPI odpi = GetParam();
634   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
635   m.Return(
636       m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
637   Stream s = m.Build();
638   ASSERT_EQ(1U, s.size());
639   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
640   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
641   EXPECT_EQ(2U, s[0]->InputCount());
642   EXPECT_LE(1U, s[0]->OutputCount());
643   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
644 }
645 
646 
TEST_P(InstructionSelectorODPITest,ValWithImmediate)647 TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
648   const ODPI odpi = GetParam();
649   TRACED_FOREACH(int32_t, imm, kImmediates) {
650     StreamBuilder m(this, kMachInt32, kMachInt32);
651     m.Return(m.Projection(
652         0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
653     Stream s = m.Build();
654     ASSERT_EQ(1U, s.size());
655     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
656     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
657     ASSERT_EQ(2U, s[0]->InputCount());
658     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
659     EXPECT_LE(1U, s[0]->OutputCount());
660     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
661   }
662   TRACED_FOREACH(int32_t, imm, kImmediates) {
663     StreamBuilder m(this, kMachInt32, kMachInt32);
664     m.Return(m.Projection(
665         0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
666     Stream s = m.Build();
667     ASSERT_EQ(1U, s.size());
668     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
669     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
670     ASSERT_EQ(2U, s[0]->InputCount());
671     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
672     EXPECT_LE(1U, s[0]->OutputCount());
673     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
674   }
675 }
676 
677 
TEST_P(InstructionSelectorODPITest,ValWithShiftByParameter)678 TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
679   const ODPI odpi = GetParam();
680   TRACED_FOREACH(Shift, shift, kShifts) {
681     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
682     m.Return(m.Projection(
683         0, (m.*odpi.constructor)(
684                m.Parameter(0),
685                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
686     Stream s = m.Build();
687     ASSERT_EQ(1U, s.size());
688     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
689     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
690     EXPECT_EQ(3U, s[0]->InputCount());
691     EXPECT_LE(1U, s[0]->OutputCount());
692     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
693   }
694   TRACED_FOREACH(Shift, shift, kShifts) {
695     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
696     m.Return(m.Projection(
697         0, (m.*odpi.constructor)(
698                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
699                m.Parameter(0))));
700     Stream s = m.Build();
701     ASSERT_EQ(1U, s.size());
702     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
703     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
704     EXPECT_EQ(3U, s[0]->InputCount());
705     EXPECT_LE(1U, s[0]->OutputCount());
706     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
707   }
708 }
709 
710 
TEST_P(InstructionSelectorODPITest,ValWithShiftByImmediate)711 TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
712   const ODPI odpi = GetParam();
713   TRACED_FOREACH(Shift, shift, kShifts) {
714     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
715       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
716       m.Return(m.Projection(
717           0, (m.*odpi.constructor)(m.Parameter(0),
718                                    (m.*shift.constructor)(
719                                        m.Parameter(1), m.Int32Constant(imm)))));
720       Stream s = m.Build();
721       ASSERT_EQ(1U, s.size());
722       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
723       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
724       ASSERT_EQ(3U, s[0]->InputCount());
725       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
726       EXPECT_LE(1U, s[0]->OutputCount());
727       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
728     }
729   }
730   TRACED_FOREACH(Shift, shift, kShifts) {
731     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
732       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
733       m.Return(m.Projection(
734           0, (m.*odpi.constructor)(
735                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
736                  m.Parameter(0))));
737       Stream s = m.Build();
738       ASSERT_EQ(1U, s.size());
739       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
740       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
741       ASSERT_EQ(3U, s[0]->InputCount());
742       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
743       EXPECT_LE(1U, s[0]->OutputCount());
744       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
745     }
746   }
747 }
748 
749 
TEST_P(InstructionSelectorODPITest,BothWithParameters)750 TEST_P(InstructionSelectorODPITest, BothWithParameters) {
751   const ODPI odpi = GetParam();
752   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
753   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
754   m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
755   Stream s = m.Build();
756   ASSERT_LE(1U, s.size());
757   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
758   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
759   EXPECT_EQ(2U, s[0]->InputCount());
760   EXPECT_EQ(2U, s[0]->OutputCount());
761   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
762   EXPECT_EQ(kOverflow, s[0]->flags_condition());
763 }
764 
765 
TEST_P(InstructionSelectorODPITest,BothWithImmediate)766 TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
767   const ODPI odpi = GetParam();
768   TRACED_FOREACH(int32_t, imm, kImmediates) {
769     StreamBuilder m(this, kMachInt32, kMachInt32);
770     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
771     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
772     Stream s = m.Build();
773     ASSERT_LE(1U, s.size());
774     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
775     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
776     ASSERT_EQ(2U, s[0]->InputCount());
777     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
778     EXPECT_EQ(2U, s[0]->OutputCount());
779     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
780     EXPECT_EQ(kOverflow, s[0]->flags_condition());
781   }
782   TRACED_FOREACH(int32_t, imm, kImmediates) {
783     StreamBuilder m(this, kMachInt32, kMachInt32);
784     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
785     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
786     Stream s = m.Build();
787     ASSERT_LE(1U, s.size());
788     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
789     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
790     ASSERT_EQ(2U, s[0]->InputCount());
791     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
792     EXPECT_EQ(2U, s[0]->OutputCount());
793     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
794     EXPECT_EQ(kOverflow, s[0]->flags_condition());
795   }
796 }
797 
798 
TEST_P(InstructionSelectorODPITest,BothWithShiftByParameter)799 TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
800   const ODPI odpi = GetParam();
801   TRACED_FOREACH(Shift, shift, kShifts) {
802     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
803     Node* n = (m.*odpi.constructor)(
804         m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
805     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
806     Stream s = m.Build();
807     ASSERT_LE(1U, s.size());
808     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
809     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
810     EXPECT_EQ(3U, s[0]->InputCount());
811     EXPECT_EQ(2U, s[0]->OutputCount());
812     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
813     EXPECT_EQ(kOverflow, s[0]->flags_condition());
814   }
815   TRACED_FOREACH(Shift, shift, kShifts) {
816     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
817     Node* n = (m.*odpi.constructor)(
818         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
819     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
820     Stream s = m.Build();
821     ASSERT_LE(1U, s.size());
822     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
823     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
824     EXPECT_EQ(3U, s[0]->InputCount());
825     EXPECT_EQ(2U, s[0]->OutputCount());
826     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
827     EXPECT_EQ(kOverflow, s[0]->flags_condition());
828   }
829 }
830 
831 
TEST_P(InstructionSelectorODPITest,BothWithShiftByImmediate)832 TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
833   const ODPI odpi = GetParam();
834   TRACED_FOREACH(Shift, shift, kShifts) {
835     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
836       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
837       Node* n = (m.*odpi.constructor)(
838           m.Parameter(0),
839           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
840       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
841       Stream s = m.Build();
842       ASSERT_LE(1U, s.size());
843       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
844       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
845       ASSERT_EQ(3U, s[0]->InputCount());
846       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
847       EXPECT_EQ(2U, s[0]->OutputCount());
848       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
849       EXPECT_EQ(kOverflow, s[0]->flags_condition());
850     }
851   }
852   TRACED_FOREACH(Shift, shift, kShifts) {
853     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
854       StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
855       Node* n = (m.*odpi.constructor)(
856           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
857           m.Parameter(1));
858       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
859       Stream s = m.Build();
860       ASSERT_LE(1U, s.size());
861       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
862       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
863       ASSERT_EQ(3U, s[0]->InputCount());
864       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
865       EXPECT_EQ(2U, s[0]->OutputCount());
866       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
867       EXPECT_EQ(kOverflow, s[0]->flags_condition());
868     }
869   }
870 }
871 
872 
TEST_P(InstructionSelectorODPITest,BranchWithParameters)873 TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
874   const ODPI odpi = GetParam();
875   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
876   MLabel a, b;
877   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
878   m.Branch(m.Projection(1, n), &a, &b);
879   m.Bind(&a);
880   m.Return(m.Int32Constant(0));
881   m.Bind(&b);
882   m.Return(m.Projection(0, n));
883   Stream s = m.Build();
884   ASSERT_EQ(1U, s.size());
885   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
886   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
887   EXPECT_EQ(4U, s[0]->InputCount());
888   EXPECT_EQ(1U, s[0]->OutputCount());
889   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
890   EXPECT_EQ(kOverflow, s[0]->flags_condition());
891 }
892 
893 
TEST_P(InstructionSelectorODPITest,BranchWithImmediate)894 TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
895   const ODPI odpi = GetParam();
896   TRACED_FOREACH(int32_t, imm, kImmediates) {
897     StreamBuilder m(this, kMachInt32, kMachInt32);
898     MLabel a, b;
899     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
900     m.Branch(m.Projection(1, n), &a, &b);
901     m.Bind(&a);
902     m.Return(m.Int32Constant(0));
903     m.Bind(&b);
904     m.Return(m.Projection(0, n));
905     Stream s = m.Build();
906     ASSERT_EQ(1U, s.size());
907     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
908     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
909     ASSERT_EQ(4U, s[0]->InputCount());
910     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
911     EXPECT_EQ(1U, s[0]->OutputCount());
912     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
913     EXPECT_EQ(kOverflow, s[0]->flags_condition());
914   }
915   TRACED_FOREACH(int32_t, imm, kImmediates) {
916     StreamBuilder m(this, kMachInt32, kMachInt32);
917     MLabel a, b;
918     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
919     m.Branch(m.Projection(1, n), &a, &b);
920     m.Bind(&a);
921     m.Return(m.Int32Constant(0));
922     m.Bind(&b);
923     m.Return(m.Projection(0, n));
924     Stream s = m.Build();
925     ASSERT_EQ(1U, s.size());
926     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
927     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
928     ASSERT_EQ(4U, s[0]->InputCount());
929     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
930     EXPECT_EQ(1U, s[0]->OutputCount());
931     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
932     EXPECT_EQ(kOverflow, s[0]->flags_condition());
933   }
934 }
935 
936 
TEST_P(InstructionSelectorODPITest,BranchIfZeroWithParameters)937 TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
938   const ODPI odpi = GetParam();
939   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
940   MLabel a, b;
941   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
942   m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
943   m.Bind(&a);
944   m.Return(m.Projection(0, n));
945   m.Bind(&b);
946   m.Return(m.Int32Constant(0));
947   Stream s = m.Build();
948   ASSERT_EQ(1U, s.size());
949   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
950   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
951   EXPECT_EQ(4U, s[0]->InputCount());
952   EXPECT_EQ(1U, s[0]->OutputCount());
953   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
954   EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
955 }
956 
957 
TEST_P(InstructionSelectorODPITest,BranchIfNotZeroWithParameters)958 TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
959   const ODPI odpi = GetParam();
960   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
961   MLabel a, b;
962   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
963   m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
964   m.Bind(&a);
965   m.Return(m.Projection(0, n));
966   m.Bind(&b);
967   m.Return(m.Int32Constant(0));
968   Stream s = m.Build();
969   ASSERT_EQ(1U, s.size());
970   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
971   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
972   EXPECT_EQ(4U, s[0]->InputCount());
973   EXPECT_EQ(1U, s[0]->OutputCount());
974   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
975   EXPECT_EQ(kOverflow, s[0]->flags_condition());
976 }
977 
978 
979 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
980                         ::testing::ValuesIn(kODPIs));
981 
982 
983 // -----------------------------------------------------------------------------
984 // Shifts.
985 
986 
987 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
988 
989 
TEST_P(InstructionSelectorShiftTest,Parameters)990 TEST_P(InstructionSelectorShiftTest, Parameters) {
991   const Shift shift = GetParam();
992   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
993   m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
994   Stream s = m.Build();
995   ASSERT_EQ(1U, s.size());
996   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
997   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
998   EXPECT_EQ(2U, s[0]->InputCount());
999   EXPECT_EQ(1U, s[0]->OutputCount());
1000 }
1001 
1002 
TEST_P(InstructionSelectorShiftTest,Immediate)1003 TEST_P(InstructionSelectorShiftTest, Immediate) {
1004   const Shift shift = GetParam();
1005   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1006     StreamBuilder m(this, kMachInt32, kMachInt32);
1007     m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
1008     Stream s = m.Build();
1009     ASSERT_EQ(1U, s.size());
1010     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1011     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1012     ASSERT_EQ(2U, s[0]->InputCount());
1013     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1014     EXPECT_EQ(1U, s[0]->OutputCount());
1015   }
1016 }
1017 
1018 
TEST_P(InstructionSelectorShiftTest,Word32EqualWithParameter)1019 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
1020   const Shift shift = GetParam();
1021   {
1022     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1023     m.Return(
1024         m.Word32Equal(m.Parameter(0),
1025                       (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
1026     Stream s = m.Build();
1027     ASSERT_EQ(1U, s.size());
1028     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1029     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1030     EXPECT_EQ(3U, s[0]->InputCount());
1031     EXPECT_EQ(1U, s[0]->OutputCount());
1032     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1033     EXPECT_EQ(kEqual, s[0]->flags_condition());
1034   }
1035   {
1036     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1037     m.Return(
1038         m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
1039                       m.Parameter(0)));
1040     Stream s = m.Build();
1041     ASSERT_EQ(1U, s.size());
1042     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1043     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1044     EXPECT_EQ(3U, s[0]->InputCount());
1045     EXPECT_EQ(1U, s[0]->OutputCount());
1046     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1047     EXPECT_EQ(kEqual, s[0]->flags_condition());
1048   }
1049 }
1050 
1051 
TEST_P(InstructionSelectorShiftTest,Word32EqualWithParameterAndImmediate)1052 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
1053   const Shift shift = GetParam();
1054   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1055     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1056     m.Return(m.Word32Equal(
1057         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
1058         m.Parameter(0)));
1059     Stream s = m.Build();
1060     ASSERT_EQ(1U, s.size());
1061     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1062     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1063     ASSERT_EQ(3U, s[0]->InputCount());
1064     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1065     EXPECT_EQ(1U, s[0]->OutputCount());
1066     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1067     EXPECT_EQ(kEqual, s[0]->flags_condition());
1068   }
1069   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1070     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1071     m.Return(m.Word32Equal(
1072         m.Parameter(0),
1073         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
1074     Stream s = m.Build();
1075     ASSERT_EQ(1U, s.size());
1076     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1077     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1078     ASSERT_EQ(3U, s[0]->InputCount());
1079     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1080     EXPECT_EQ(1U, s[0]->OutputCount());
1081     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1082     EXPECT_EQ(kEqual, s[0]->flags_condition());
1083   }
1084 }
1085 
1086 
TEST_P(InstructionSelectorShiftTest,Word32EqualToZeroWithParameters)1087 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
1088   const Shift shift = GetParam();
1089   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1090   m.Return(
1091       m.Word32Equal(m.Int32Constant(0),
1092                     (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1093   Stream s = m.Build();
1094   ASSERT_EQ(1U, s.size());
1095   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1096   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1097   EXPECT_EQ(2U, s[0]->InputCount());
1098   EXPECT_EQ(2U, s[0]->OutputCount());
1099   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1100   EXPECT_EQ(kEqual, s[0]->flags_condition());
1101 }
1102 
1103 
TEST_P(InstructionSelectorShiftTest,Word32EqualToZeroWithImmediate)1104 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
1105   const Shift shift = GetParam();
1106   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1107     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1108     m.Return(m.Word32Equal(
1109         m.Int32Constant(0),
1110         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1111     Stream s = m.Build();
1112     ASSERT_EQ(1U, s.size());
1113     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1114     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1115     ASSERT_EQ(2U, s[0]->InputCount());
1116     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1117     EXPECT_EQ(2U, s[0]->OutputCount());
1118     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1119     EXPECT_EQ(kEqual, s[0]->flags_condition());
1120   }
1121 }
1122 
1123 
TEST_P(InstructionSelectorShiftTest,Word32NotWithParameters)1124 TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
1125   const Shift shift = GetParam();
1126   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1127   m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1128   Stream s = m.Build();
1129   ASSERT_EQ(1U, s.size());
1130   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1131   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1132   EXPECT_EQ(2U, s[0]->InputCount());
1133   EXPECT_EQ(1U, s[0]->OutputCount());
1134 }
1135 
1136 
TEST_P(InstructionSelectorShiftTest,Word32NotWithImmediate)1137 TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
1138   const Shift shift = GetParam();
1139   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1140     StreamBuilder m(this, kMachInt32, kMachInt32);
1141     m.Return(m.Word32Not(
1142         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1143     Stream s = m.Build();
1144     ASSERT_EQ(1U, s.size());
1145     EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1146     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1147     ASSERT_EQ(2U, s[0]->InputCount());
1148     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1149     EXPECT_EQ(1U, s[0]->OutputCount());
1150   }
1151 }
1152 
1153 
TEST_P(InstructionSelectorShiftTest,Word32AndWithWord32NotWithParameters)1154 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
1155   const Shift shift = GetParam();
1156   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1157   m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
1158                                            m.Parameter(1), m.Parameter(2)))));
1159   Stream s = m.Build();
1160   ASSERT_EQ(1U, s.size());
1161   EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1162   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1163   EXPECT_EQ(3U, s[0]->InputCount());
1164   EXPECT_EQ(1U, s[0]->OutputCount());
1165 }
1166 
1167 
TEST_P(InstructionSelectorShiftTest,Word32AndWithWord32NotWithImmediate)1168 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
1169   const Shift shift = GetParam();
1170   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1171     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1172     m.Return(m.Word32And(m.Parameter(0),
1173                          m.Word32Not((m.*shift.constructor)(
1174                              m.Parameter(1), m.Int32Constant(imm)))));
1175     Stream s = m.Build();
1176     ASSERT_EQ(1U, s.size());
1177     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1178     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1179     ASSERT_EQ(3U, s[0]->InputCount());
1180     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1181     EXPECT_EQ(1U, s[0]->OutputCount());
1182   }
1183 }
1184 
1185 
1186 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
1187                         ::testing::ValuesIn(kShifts));
1188 
1189 
1190 // -----------------------------------------------------------------------------
1191 // Memory access instructions.
1192 
1193 
1194 namespace {
1195 
1196 struct MemoryAccess {
1197   MachineType type;
1198   ArchOpcode ldr_opcode;
1199   ArchOpcode str_opcode;
1200   bool (InstructionSelectorTest::Stream::*val_predicate)(
1201       const InstructionOperand*) const;
1202   const int32_t immediates[40];
1203 };
1204 
1205 
operator <<(std::ostream & os,const MemoryAccess & memacc)1206 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
1207   OStringStream ost;
1208   ost << memacc.type;
1209   return os << ost.c_str();
1210 }
1211 
1212 
1213 static const MemoryAccess kMemoryAccesses[] = {
1214     {kMachInt8,
1215      kArmLdrsb,
1216      kArmStrb,
1217      &InstructionSelectorTest::Stream::IsInteger,
1218      {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
1219       -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
1220       115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
1221     {kMachUint8,
1222      kArmLdrb,
1223      kArmStrb,
1224      &InstructionSelectorTest::Stream::IsInteger,
1225      {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
1226       -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
1227       39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
1228     {kMachInt16,
1229      kArmLdrsh,
1230      kArmStrh,
1231      &InstructionSelectorTest::Stream::IsInteger,
1232      {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
1233       -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
1234       102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
1235     {kMachUint16,
1236      kArmLdrh,
1237      kArmStrh,
1238      &InstructionSelectorTest::Stream::IsInteger,
1239      {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
1240       -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
1241       114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
1242     {kMachInt32,
1243      kArmLdr,
1244      kArmStr,
1245      &InstructionSelectorTest::Stream::IsInteger,
1246      {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
1247       -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
1248       93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
1249     {kMachFloat32,
1250      kArmVldr32,
1251      kArmVstr32,
1252      &InstructionSelectorTest::Stream::IsDouble,
1253      {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
1254       -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
1255       24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
1256     {kMachFloat64,
1257      kArmVldr64,
1258      kArmVstr64,
1259      &InstructionSelectorTest::Stream::IsDouble,
1260      {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
1261       -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
1262       108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
1263 
1264 }  // namespace
1265 
1266 
1267 typedef InstructionSelectorTestWithParam<MemoryAccess>
1268     InstructionSelectorMemoryAccessTest;
1269 
1270 
TEST_P(InstructionSelectorMemoryAccessTest,LoadWithParameters)1271 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
1272   const MemoryAccess memacc = GetParam();
1273   StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
1274   m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
1275   Stream s = m.Build();
1276   ASSERT_EQ(1U, s.size());
1277   EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1278   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1279   EXPECT_EQ(2U, s[0]->InputCount());
1280   ASSERT_EQ(1U, s[0]->OutputCount());
1281   EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1282 }
1283 
1284 
TEST_P(InstructionSelectorMemoryAccessTest,LoadWithImmediateIndex)1285 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
1286   const MemoryAccess memacc = GetParam();
1287   TRACED_FOREACH(int32_t, index, memacc.immediates) {
1288     StreamBuilder m(this, memacc.type, kMachPtr);
1289     m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
1290     Stream s = m.Build();
1291     ASSERT_EQ(1U, s.size());
1292     EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1293     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1294     ASSERT_EQ(2U, s[0]->InputCount());
1295     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1296     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1297     ASSERT_EQ(1U, s[0]->OutputCount());
1298     EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1299   }
1300 }
1301 
1302 
TEST_P(InstructionSelectorMemoryAccessTest,StoreWithParameters)1303 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
1304   const MemoryAccess memacc = GetParam();
1305   StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
1306   m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
1307   m.Return(m.Int32Constant(0));
1308   Stream s = m.Build();
1309   ASSERT_EQ(1U, s.size());
1310   EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1311   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1312   EXPECT_EQ(3U, s[0]->InputCount());
1313   EXPECT_EQ(0U, s[0]->OutputCount());
1314 }
1315 
1316 
TEST_P(InstructionSelectorMemoryAccessTest,StoreWithImmediateIndex)1317 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
1318   const MemoryAccess memacc = GetParam();
1319   TRACED_FOREACH(int32_t, index, memacc.immediates) {
1320     StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
1321     m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
1322             m.Parameter(1));
1323     m.Return(m.Int32Constant(0));
1324     Stream s = m.Build();
1325     ASSERT_EQ(1U, s.size());
1326     EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1327     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1328     ASSERT_EQ(3U, s[0]->InputCount());
1329     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1330     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1331     EXPECT_EQ(0U, s[0]->OutputCount());
1332   }
1333 }
1334 
1335 
1336 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1337                         InstructionSelectorMemoryAccessTest,
1338                         ::testing::ValuesIn(kMemoryAccesses));
1339 
1340 
1341 // -----------------------------------------------------------------------------
1342 // Miscellaneous.
1343 
1344 
TEST_F(InstructionSelectorTest,Int32AddWithInt32Mul)1345 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
1346   {
1347     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1348     m.Return(
1349         m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1350     Stream s = m.Build();
1351     ASSERT_EQ(1U, s.size());
1352     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1353     EXPECT_EQ(3U, s[0]->InputCount());
1354     EXPECT_EQ(1U, s[0]->OutputCount());
1355   }
1356   {
1357     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1358     m.Return(
1359         m.Int32Add(m.Int32Mul(m.Parameter(1), m.Parameter(2)), m.Parameter(0)));
1360     Stream s = m.Build();
1361     ASSERT_EQ(1U, s.size());
1362     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1363     EXPECT_EQ(3U, s[0]->InputCount());
1364     EXPECT_EQ(1U, s[0]->OutputCount());
1365   }
1366 }
1367 
1368 
TEST_F(InstructionSelectorTest,Int32DivWithParameters)1369 TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
1370   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1371   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1372   Stream s = m.Build();
1373   ASSERT_EQ(4U, s.size());
1374   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1375   ASSERT_EQ(1U, s[0]->OutputCount());
1376   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1377   ASSERT_EQ(1U, s[1]->OutputCount());
1378   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1379   ASSERT_EQ(2U, s[2]->InputCount());
1380   ASSERT_EQ(1U, s[2]->OutputCount());
1381   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1382   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1383   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1384   ASSERT_EQ(1U, s[3]->InputCount());
1385   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1386 }
1387 
1388 
TEST_F(InstructionSelectorTest,Int32DivWithParametersForSUDIV)1389 TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
1390   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1391   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1392   Stream s = m.Build(SUDIV);
1393   ASSERT_EQ(1U, s.size());
1394   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1395 }
1396 
1397 
TEST_F(InstructionSelectorTest,Int32ModWithParameters)1398 TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
1399   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1400   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1401   Stream s = m.Build();
1402   ASSERT_EQ(6U, s.size());
1403   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1404   ASSERT_EQ(1U, s[0]->OutputCount());
1405   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1406   ASSERT_EQ(1U, s[1]->OutputCount());
1407   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1408   ASSERT_EQ(2U, s[2]->InputCount());
1409   ASSERT_EQ(1U, s[2]->OutputCount());
1410   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1411   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1412   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1413   ASSERT_EQ(1U, s[3]->InputCount());
1414   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1415   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1416   ASSERT_EQ(1U, s[4]->OutputCount());
1417   ASSERT_EQ(2U, s[4]->InputCount());
1418   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1419   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1420   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1421   ASSERT_EQ(1U, s[5]->OutputCount());
1422   ASSERT_EQ(2U, s[5]->InputCount());
1423   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1424   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1425 }
1426 
1427 
TEST_F(InstructionSelectorTest,Int32ModWithParametersForSUDIV)1428 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
1429   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1430   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1431   Stream s = m.Build(SUDIV);
1432   ASSERT_EQ(3U, s.size());
1433   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1434   ASSERT_EQ(1U, s[0]->OutputCount());
1435   ASSERT_EQ(2U, s[0]->InputCount());
1436   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1437   ASSERT_EQ(1U, s[1]->OutputCount());
1438   ASSERT_EQ(2U, s[1]->InputCount());
1439   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1440   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1441   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1442   ASSERT_EQ(1U, s[2]->OutputCount());
1443   ASSERT_EQ(2U, s[2]->InputCount());
1444   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1445   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1446 }
1447 
1448 
TEST_F(InstructionSelectorTest,Int32ModWithParametersForSUDIVAndMLS)1449 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
1450   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1451   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1452   Stream s = m.Build(MLS, SUDIV);
1453   ASSERT_EQ(2U, s.size());
1454   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1455   ASSERT_EQ(1U, s[0]->OutputCount());
1456   ASSERT_EQ(2U, s[0]->InputCount());
1457   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1458   ASSERT_EQ(1U, s[1]->OutputCount());
1459   ASSERT_EQ(3U, s[1]->InputCount());
1460   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1461   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1462   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1463 }
1464 
1465 
TEST_F(InstructionSelectorTest,Int32MulWithParameters)1466 TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
1467   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1468   m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
1469   Stream s = m.Build();
1470   ASSERT_EQ(1U, s.size());
1471   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1472   EXPECT_EQ(2U, s[0]->InputCount());
1473   EXPECT_EQ(1U, s[0]->OutputCount());
1474 }
1475 
1476 
TEST_F(InstructionSelectorTest,Int32MulWithImmediate)1477 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
1478   // x * (2^k + 1) -> x + (x >> k)
1479   TRACED_FORRANGE(int32_t, k, 1, 30) {
1480     StreamBuilder m(this, kMachInt32, kMachInt32);
1481     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
1482     Stream s = m.Build();
1483     ASSERT_EQ(1U, s.size());
1484     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1485     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1486     ASSERT_EQ(3U, s[0]->InputCount());
1487     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1488     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1489     EXPECT_EQ(1U, s[0]->OutputCount());
1490   }
1491   // x * (2^k - 1) -> -x + (x >> k)
1492   TRACED_FORRANGE(int32_t, k, 3, 30) {
1493     StreamBuilder m(this, kMachInt32, kMachInt32);
1494     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
1495     Stream s = m.Build();
1496     ASSERT_EQ(1U, s.size());
1497     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1498     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1499     ASSERT_EQ(3U, s[0]->InputCount());
1500     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1501     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1502     EXPECT_EQ(1U, s[0]->OutputCount());
1503   }
1504   // (2^k + 1) * x -> x + (x >> k)
1505   TRACED_FORRANGE(int32_t, k, 1, 30) {
1506     StreamBuilder m(this, kMachInt32, kMachInt32);
1507     m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
1508     Stream s = m.Build();
1509     ASSERT_EQ(1U, s.size());
1510     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1511     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1512     ASSERT_EQ(3U, s[0]->InputCount());
1513     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1514     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1515     EXPECT_EQ(1U, s[0]->OutputCount());
1516   }
1517   // x * (2^k - 1) -> -x + (x >> k)
1518   TRACED_FORRANGE(int32_t, k, 3, 30) {
1519     StreamBuilder m(this, kMachInt32, kMachInt32);
1520     m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
1521     Stream s = m.Build();
1522     ASSERT_EQ(1U, s.size());
1523     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1524     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1525     ASSERT_EQ(3U, s[0]->InputCount());
1526     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1527     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1528     EXPECT_EQ(1U, s[0]->OutputCount());
1529   }
1530 }
1531 
1532 
TEST_F(InstructionSelectorTest,Int32SubWithInt32Mul)1533 TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
1534   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1535   m.Return(
1536       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1537   Stream s = m.Build();
1538   ASSERT_EQ(2U, s.size());
1539   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1540   ASSERT_EQ(1U, s[0]->OutputCount());
1541   EXPECT_EQ(kArmSub, s[1]->arch_opcode());
1542   ASSERT_EQ(2U, s[1]->InputCount());
1543   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
1544 }
1545 
1546 
TEST_F(InstructionSelectorTest,Int32SubWithInt32MulForMLS)1547 TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
1548   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1549   m.Return(
1550       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1551   Stream s = m.Build(MLS);
1552   ASSERT_EQ(1U, s.size());
1553   EXPECT_EQ(kArmMls, s[0]->arch_opcode());
1554   EXPECT_EQ(1U, s[0]->OutputCount());
1555   EXPECT_EQ(3U, s[0]->InputCount());
1556 }
1557 
1558 
TEST_F(InstructionSelectorTest,Int32UDivWithParameters)1559 TEST_F(InstructionSelectorTest, Int32UDivWithParameters) {
1560   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1561   m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
1562   Stream s = m.Build();
1563   ASSERT_EQ(4U, s.size());
1564   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
1565   ASSERT_EQ(1U, s[0]->OutputCount());
1566   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
1567   ASSERT_EQ(1U, s[1]->OutputCount());
1568   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1569   ASSERT_EQ(2U, s[2]->InputCount());
1570   ASSERT_EQ(1U, s[2]->OutputCount());
1571   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1572   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1573   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
1574   ASSERT_EQ(1U, s[3]->InputCount());
1575   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1576 }
1577 
1578 
TEST_F(InstructionSelectorTest,Int32UDivWithParametersForSUDIV)1579 TEST_F(InstructionSelectorTest, Int32UDivWithParametersForSUDIV) {
1580   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1581   m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
1582   Stream s = m.Build(SUDIV);
1583   ASSERT_EQ(1U, s.size());
1584   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1585 }
1586 
1587 
TEST_F(InstructionSelectorTest,Int32UModWithParameters)1588 TEST_F(InstructionSelectorTest, Int32UModWithParameters) {
1589   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1590   m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1591   Stream s = m.Build();
1592   ASSERT_EQ(6U, s.size());
1593   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
1594   ASSERT_EQ(1U, s[0]->OutputCount());
1595   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
1596   ASSERT_EQ(1U, s[1]->OutputCount());
1597   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1598   ASSERT_EQ(2U, s[2]->InputCount());
1599   ASSERT_EQ(1U, s[2]->OutputCount());
1600   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1601   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1602   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
1603   ASSERT_EQ(1U, s[3]->InputCount());
1604   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1605   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1606   ASSERT_EQ(1U, s[4]->OutputCount());
1607   ASSERT_EQ(2U, s[4]->InputCount());
1608   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1609   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1610   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1611   ASSERT_EQ(1U, s[5]->OutputCount());
1612   ASSERT_EQ(2U, s[5]->InputCount());
1613   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1614   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1615 }
1616 
1617 
TEST_F(InstructionSelectorTest,Int32UModWithParametersForSUDIV)1618 TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIV) {
1619   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1620   m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1621   Stream s = m.Build(SUDIV);
1622   ASSERT_EQ(3U, s.size());
1623   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1624   ASSERT_EQ(1U, s[0]->OutputCount());
1625   ASSERT_EQ(2U, s[0]->InputCount());
1626   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1627   ASSERT_EQ(1U, s[1]->OutputCount());
1628   ASSERT_EQ(2U, s[1]->InputCount());
1629   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1630   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1631   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1632   ASSERT_EQ(1U, s[2]->OutputCount());
1633   ASSERT_EQ(2U, s[2]->InputCount());
1634   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1635   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1636 }
1637 
1638 
TEST_F(InstructionSelectorTest,Int32UModWithParametersForSUDIVAndMLS)1639 TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIVAndMLS) {
1640   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1641   m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1642   Stream s = m.Build(MLS, SUDIV);
1643   ASSERT_EQ(2U, s.size());
1644   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1645   ASSERT_EQ(1U, s[0]->OutputCount());
1646   ASSERT_EQ(2U, s[0]->InputCount());
1647   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1648   ASSERT_EQ(1U, s[1]->OutputCount());
1649   ASSERT_EQ(3U, s[1]->InputCount());
1650   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1651   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1652   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1653 }
1654 
1655 
TEST_F(InstructionSelectorTest,Word32AndWithUbfxImmediateForARMv7)1656 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
1657   TRACED_FORRANGE(int32_t, width, 1, 32) {
1658     StreamBuilder m(this, kMachInt32, kMachInt32);
1659     m.Return(m.Word32And(m.Parameter(0),
1660                          m.Int32Constant(0xffffffffu >> (32 - width))));
1661     Stream s = m.Build(ARMv7);
1662     ASSERT_EQ(1U, s.size());
1663     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1664     ASSERT_EQ(3U, s[0]->InputCount());
1665     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
1666     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1667   }
1668   TRACED_FORRANGE(int32_t, width, 1, 32) {
1669     StreamBuilder m(this, kMachInt32, kMachInt32);
1670     m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
1671                          m.Parameter(0)));
1672     Stream s = m.Build(ARMv7);
1673     ASSERT_EQ(1U, s.size());
1674     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1675     ASSERT_EQ(3U, s[0]->InputCount());
1676     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
1677     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1678   }
1679 }
1680 
1681 
TEST_F(InstructionSelectorTest,Word32AndWithBfcImmediateForARMv7)1682 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
1683   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1684     TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
1685       StreamBuilder m(this, kMachInt32, kMachInt32);
1686       m.Return(m.Word32And(
1687           m.Parameter(0),
1688           m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
1689       Stream s = m.Build(ARMv7);
1690       ASSERT_EQ(1U, s.size());
1691       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
1692       ASSERT_EQ(1U, s[0]->OutputCount());
1693       EXPECT_TRUE(
1694           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
1695       ASSERT_EQ(3U, s[0]->InputCount());
1696       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1697       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1698     }
1699   }
1700   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1701     TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
1702       StreamBuilder m(this, kMachInt32, kMachInt32);
1703       m.Return(
1704           m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
1705                       m.Parameter(0)));
1706       Stream s = m.Build(ARMv7);
1707       ASSERT_EQ(1U, s.size());
1708       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
1709       ASSERT_EQ(1U, s[0]->OutputCount());
1710       EXPECT_TRUE(
1711           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
1712       ASSERT_EQ(3U, s[0]->InputCount());
1713       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1714       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1715     }
1716   }
1717 }
1718 
1719 
TEST_F(InstructionSelectorTest,Word32ShrWithWord32AndWithImmediateForARMv7)1720 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
1721   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1722     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1723       uint32_t max = 1 << lsb;
1724       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
1725       uint32_t jnk = rng()->NextInt(max);
1726       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
1727       StreamBuilder m(this, kMachInt32, kMachInt32);
1728       m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
1729                            m.Int32Constant(lsb)));
1730       Stream s = m.Build(ARMv7);
1731       ASSERT_EQ(1U, s.size());
1732       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1733       ASSERT_EQ(3U, s[0]->InputCount());
1734       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1735       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1736     }
1737   }
1738   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1739     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1740       uint32_t max = 1 << lsb;
1741       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
1742       uint32_t jnk = rng()->NextInt(max);
1743       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
1744       StreamBuilder m(this, kMachInt32, kMachInt32);
1745       m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
1746                            m.Int32Constant(lsb)));
1747       Stream s = m.Build(ARMv7);
1748       ASSERT_EQ(1U, s.size());
1749       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1750       ASSERT_EQ(3U, s[0]->InputCount());
1751       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1752       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1753     }
1754   }
1755 }
1756 
1757 
TEST_F(InstructionSelectorTest,Word32AndWithWord32Not)1758 TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
1759   {
1760     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1761     m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
1762     Stream s = m.Build();
1763     ASSERT_EQ(1U, s.size());
1764     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1765     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1766     EXPECT_EQ(2U, s[0]->InputCount());
1767     EXPECT_EQ(1U, s[0]->OutputCount());
1768   }
1769   {
1770     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1771     m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
1772     Stream s = m.Build();
1773     ASSERT_EQ(1U, s.size());
1774     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1775     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1776     EXPECT_EQ(2U, s[0]->InputCount());
1777     EXPECT_EQ(1U, s[0]->OutputCount());
1778   }
1779 }
1780 
1781 
TEST_F(InstructionSelectorTest,Word32EqualWithParameters)1782 TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
1783   StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1784   m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
1785   Stream s = m.Build();
1786   ASSERT_EQ(1U, s.size());
1787   EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1788   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1789   EXPECT_EQ(2U, s[0]->InputCount());
1790   EXPECT_EQ(1U, s[0]->OutputCount());
1791   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1792   EXPECT_EQ(kEqual, s[0]->flags_condition());
1793 }
1794 
1795 
TEST_F(InstructionSelectorTest,Word32EqualWithImmediate)1796 TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
1797   TRACED_FOREACH(int32_t, imm, kImmediates) {
1798     if (imm == 0) continue;
1799     StreamBuilder m(this, kMachInt32, kMachInt32);
1800     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
1801     Stream s = m.Build();
1802     ASSERT_EQ(1U, s.size());
1803     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1804     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
1805     ASSERT_EQ(2U, s[0]->InputCount());
1806     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1807     EXPECT_EQ(1U, s[0]->OutputCount());
1808     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1809     EXPECT_EQ(kEqual, s[0]->flags_condition());
1810   }
1811   TRACED_FOREACH(int32_t, imm, kImmediates) {
1812     if (imm == 0) continue;
1813     StreamBuilder m(this, kMachInt32, kMachInt32);
1814     m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
1815     Stream s = m.Build();
1816     ASSERT_EQ(1U, s.size());
1817     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1818     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
1819     ASSERT_EQ(2U, s[0]->InputCount());
1820     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1821     EXPECT_EQ(1U, s[0]->OutputCount());
1822     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1823     EXPECT_EQ(kEqual, s[0]->flags_condition());
1824   }
1825 }
1826 
1827 
TEST_F(InstructionSelectorTest,Word32EqualWithZero)1828 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
1829   {
1830     StreamBuilder m(this, kMachInt32, kMachInt32);
1831     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
1832     Stream s = m.Build();
1833     ASSERT_EQ(1U, s.size());
1834     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
1835     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1836     ASSERT_EQ(2U, s[0]->InputCount());
1837     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1838     EXPECT_EQ(1U, s[0]->OutputCount());
1839     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1840     EXPECT_EQ(kEqual, s[0]->flags_condition());
1841   }
1842   {
1843     StreamBuilder m(this, kMachInt32, kMachInt32);
1844     m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
1845     Stream s = m.Build();
1846     ASSERT_EQ(1U, s.size());
1847     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
1848     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1849     ASSERT_EQ(2U, s[0]->InputCount());
1850     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1851     EXPECT_EQ(1U, s[0]->OutputCount());
1852     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1853     EXPECT_EQ(kEqual, s[0]->flags_condition());
1854   }
1855 }
1856 
1857 
TEST_F(InstructionSelectorTest,Word32NotWithParameter)1858 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
1859   StreamBuilder m(this, kMachInt32, kMachInt32);
1860   m.Return(m.Word32Not(m.Parameter(0)));
1861   Stream s = m.Build();
1862   ASSERT_EQ(1U, s.size());
1863   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1864   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1865   EXPECT_EQ(1U, s[0]->InputCount());
1866   EXPECT_EQ(1U, s[0]->OutputCount());
1867 }
1868 
1869 
TEST_F(InstructionSelectorTest,Word32AndWithWord32ShrWithImmediateForARMv7)1870 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
1871   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1872     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1873       StreamBuilder m(this, kMachInt32, kMachInt32);
1874       m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
1875                            m.Int32Constant(0xffffffffu >> (32 - width))));
1876       Stream s = m.Build(ARMv7);
1877       ASSERT_EQ(1U, s.size());
1878       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1879       ASSERT_EQ(3U, s[0]->InputCount());
1880       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1881       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1882     }
1883   }
1884   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1885     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1886       StreamBuilder m(this, kMachInt32, kMachInt32);
1887       m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
1888                            m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
1889       Stream s = m.Build(ARMv7);
1890       ASSERT_EQ(1U, s.size());
1891       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1892       ASSERT_EQ(3U, s[0]->InputCount());
1893       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1894       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1895     }
1896   }
1897 }
1898 }  // namespace compiler
1899 }  // namespace internal
1900 }  // namespace v8
1901