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