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.
7 #include "test/unittests/compiler/instruction-selector-unittest.h"
15 typedef RawMachineAssembler::Label MLabel;
16 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
19 // Data processing instructions.
21 Constructor constructor;
22 const char* constructor_name;
23 ArchOpcode arch_opcode;
24 ArchOpcode reverse_arch_opcode;
25 ArchOpcode test_arch_opcode;
29 std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
30 return os << dpi.constructor_name;
34 static const DPI kDPIs[] = {
35 {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
36 {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
37 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
38 {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
39 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
42 // Data processing instructions with overflow.
44 Constructor constructor;
45 const char* constructor_name;
46 ArchOpcode arch_opcode;
47 ArchOpcode reverse_arch_opcode;
51 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
52 return os << odpi.constructor_name;
56 static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
57 "Int32AddWithOverflow", kArmAdd, kArmAdd},
58 {&RawMachineAssembler::Int32SubWithOverflow,
59 "Int32SubWithOverflow", kArmSub, kArmRsb}};
64 Constructor constructor;
65 const char* constructor_name;
66 int32_t i_low; // lowest possible immediate
67 int32_t i_high; // highest possible immediate
68 AddressingMode i_mode; // Operand2_R_<shift>_I
69 AddressingMode r_mode; // Operand2_R_<shift>_R
73 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
74 return os << shift.constructor_name;
78 static const Shift kShifts[] = {
79 {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
80 kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
81 {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
82 kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
83 {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
84 kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
85 {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
86 kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
89 // Immediates (random subset).
90 static const int32_t kImmediates[] = {
91 std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216,
92 -2080374784, -1996488704, -1879048192, -1459617792,
93 -1358954496, -1342177265, -1275068414, -1073741818,
94 -1073741777, -855638016, -805306368, -402653184,
95 -268435444, -16777216, 0, 35,
98 1248, 1520, 1600, 1888,
99 3744, 4080, 5888, 8384,
100 9344, 9472, 9792, 13312,
101 15040, 15360, 20736, 22272,
102 23296, 32000, 33536, 37120,
103 45824, 47872, 56320, 59392,
104 65280, 72704, 101376, 147456,
105 161792, 164864, 167936, 173056,
106 195584, 209920, 212992, 356352,
107 655360, 704512, 716800, 851968,
108 901120, 1044480, 1523712, 2572288,
109 3211264, 3588096, 3833856, 3866624,
110 4325376, 5177344, 6488064, 7012352,
111 7471104, 14090240, 16711680, 19398656,
112 22282240, 28573696, 30408704, 30670848,
113 43253760, 54525952, 55312384, 56623104,
114 68157440, 115343360, 131072000, 187695104,
115 188743680, 195035136, 197132288, 203423744,
116 218103808, 267386880, 268435470, 285212672,
117 402653185, 415236096, 595591168, 603979776,
118 603979778, 629145600, 1073741835, 1073741855,
119 1073741861, 1073741884, 1157627904, 1476395008,
120 1476395010, 1610612741, 2030043136, 2080374785,
126 // -----------------------------------------------------------------------------
127 // Data processing instructions.
130 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
133 TEST_P(InstructionSelectorDPITest, Parameters) {
134 const DPI dpi = GetParam();
135 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
136 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
137 Stream s = m.Build();
138 ASSERT_EQ(1U, s.size());
139 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
140 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
141 EXPECT_EQ(2U, s[0]->InputCount());
142 EXPECT_EQ(1U, s[0]->OutputCount());
146 TEST_P(InstructionSelectorDPITest, Immediate) {
147 const DPI dpi = GetParam();
148 TRACED_FOREACH(int32_t, imm, kImmediates) {
149 StreamBuilder m(this, kMachInt32, kMachInt32);
150 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
151 Stream s = m.Build();
152 ASSERT_EQ(1U, s.size());
153 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
154 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
155 ASSERT_EQ(2U, s[0]->InputCount());
156 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
157 EXPECT_EQ(1U, s[0]->OutputCount());
159 TRACED_FOREACH(int32_t, imm, kImmediates) {
160 StreamBuilder m(this, kMachInt32, kMachInt32);
161 m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
162 Stream s = m.Build();
163 ASSERT_EQ(1U, s.size());
164 EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
165 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
166 ASSERT_EQ(2U, s[0]->InputCount());
167 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
168 EXPECT_EQ(1U, s[0]->OutputCount());
173 TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
174 const DPI dpi = GetParam();
175 TRACED_FOREACH(Shift, shift, kShifts) {
176 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
177 m.Return((m.*dpi.constructor)(
179 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
180 Stream s = m.Build();
181 ASSERT_EQ(1U, s.size());
182 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
183 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
184 EXPECT_EQ(3U, s[0]->InputCount());
185 EXPECT_EQ(1U, s[0]->OutputCount());
187 TRACED_FOREACH(Shift, shift, kShifts) {
188 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
189 m.Return((m.*dpi.constructor)(
190 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
192 Stream s = m.Build();
193 ASSERT_EQ(1U, s.size());
194 EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
195 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
196 EXPECT_EQ(3U, s[0]->InputCount());
197 EXPECT_EQ(1U, s[0]->OutputCount());
202 TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
203 const DPI dpi = GetParam();
204 TRACED_FOREACH(Shift, shift, kShifts) {
205 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
206 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
207 m.Return((m.*dpi.constructor)(
209 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
210 Stream s = m.Build();
211 ASSERT_EQ(1U, s.size());
212 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
213 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
214 ASSERT_EQ(3U, s[0]->InputCount());
215 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
216 EXPECT_EQ(1U, s[0]->OutputCount());
219 TRACED_FOREACH(Shift, shift, kShifts) {
220 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
221 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
222 m.Return((m.*dpi.constructor)(
223 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
225 Stream s = m.Build();
226 ASSERT_EQ(1U, s.size());
227 EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
228 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
229 ASSERT_EQ(3U, s[0]->InputCount());
230 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
231 EXPECT_EQ(1U, s[0]->OutputCount());
237 TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
238 const DPI dpi = GetParam();
239 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
241 m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
243 m.Return(m.Int32Constant(1));
245 m.Return(m.Int32Constant(0));
246 Stream s = m.Build();
247 ASSERT_EQ(1U, s.size());
248 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
249 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
250 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
251 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
255 TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
256 const DPI dpi = GetParam();
257 TRACED_FOREACH(int32_t, imm, kImmediates) {
258 StreamBuilder m(this, kMachInt32, kMachInt32);
260 m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
263 m.Return(m.Int32Constant(1));
265 m.Return(m.Int32Constant(0));
266 Stream s = m.Build();
267 ASSERT_EQ(1U, s.size());
268 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
269 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
270 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
271 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
273 TRACED_FOREACH(int32_t, imm, kImmediates) {
274 StreamBuilder m(this, kMachInt32, kMachInt32);
276 m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
279 m.Return(m.Int32Constant(1));
281 m.Return(m.Int32Constant(0));
282 Stream s = m.Build();
283 ASSERT_EQ(1U, s.size());
284 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
285 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
286 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
287 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
292 TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
293 const DPI dpi = GetParam();
294 TRACED_FOREACH(Shift, shift, kShifts) {
295 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
297 m.Branch((m.*dpi.constructor)(
299 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
302 m.Return(m.Int32Constant(1));
304 m.Return(m.Int32Constant(0));
305 Stream s = m.Build();
306 ASSERT_EQ(1U, s.size());
307 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
308 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
309 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
310 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
312 TRACED_FOREACH(Shift, shift, kShifts) {
313 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
315 m.Branch((m.*dpi.constructor)(
316 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
320 m.Return(m.Int32Constant(1));
322 m.Return(m.Int32Constant(0));
323 Stream s = m.Build();
324 ASSERT_EQ(1U, s.size());
325 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
326 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
327 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
328 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
333 TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
334 const DPI dpi = GetParam();
335 TRACED_FOREACH(Shift, shift, kShifts) {
336 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
337 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
339 m.Branch((m.*dpi.constructor)(m.Parameter(0),
340 (m.*shift.constructor)(
341 m.Parameter(1), m.Int32Constant(imm))),
344 m.Return(m.Int32Constant(1));
346 m.Return(m.Int32Constant(0));
347 Stream s = m.Build();
348 ASSERT_EQ(1U, s.size());
349 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
350 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
351 ASSERT_EQ(5U, s[0]->InputCount());
352 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
353 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
354 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
357 TRACED_FOREACH(Shift, shift, kShifts) {
358 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
359 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
361 m.Branch((m.*dpi.constructor)(
362 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
366 m.Return(m.Int32Constant(1));
368 m.Return(m.Int32Constant(0));
369 Stream s = m.Build();
370 ASSERT_EQ(1U, s.size());
371 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
372 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
373 ASSERT_EQ(5U, s[0]->InputCount());
374 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
375 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
376 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
382 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
383 const DPI dpi = GetParam();
384 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
386 m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
390 m.Return(m.Int32Constant(1));
392 m.Return(m.Int32Constant(0));
393 Stream s = m.Build();
394 ASSERT_EQ(1U, s.size());
395 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
396 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
397 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
398 EXPECT_EQ(kEqual, s[0]->flags_condition());
402 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
403 const DPI dpi = GetParam();
404 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
407 m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
411 m.Return(m.Int32Constant(1));
413 m.Return(m.Int32Constant(0));
414 Stream s = m.Build();
415 ASSERT_EQ(1U, s.size());
416 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
417 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
418 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
419 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
423 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
424 const DPI dpi = GetParam();
425 TRACED_FOREACH(int32_t, imm, kImmediates) {
426 StreamBuilder m(this, kMachInt32, kMachInt32);
428 m.Branch(m.Word32Equal(
429 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
433 m.Return(m.Int32Constant(1));
435 m.Return(m.Int32Constant(0));
436 Stream s = m.Build();
437 ASSERT_EQ(1U, s.size());
438 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
439 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
440 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
441 EXPECT_EQ(kEqual, s[0]->flags_condition());
443 TRACED_FOREACH(int32_t, imm, kImmediates) {
444 StreamBuilder m(this, kMachInt32, kMachInt32);
446 m.Branch(m.Word32Equal(
447 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
451 m.Return(m.Int32Constant(1));
453 m.Return(m.Int32Constant(0));
454 Stream s = m.Build();
455 ASSERT_EQ(1U, s.size());
456 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
457 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
458 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
459 EXPECT_EQ(kEqual, s[0]->flags_condition());
464 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
465 const DPI dpi = GetParam();
466 TRACED_FOREACH(int32_t, imm, kImmediates) {
467 StreamBuilder m(this, kMachInt32, kMachInt32);
469 m.Branch(m.Word32NotEqual(
470 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
474 m.Return(m.Int32Constant(1));
476 m.Return(m.Int32Constant(0));
477 Stream s = m.Build();
478 ASSERT_EQ(1U, s.size());
479 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
480 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
481 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
482 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
484 TRACED_FOREACH(int32_t, imm, kImmediates) {
485 StreamBuilder m(this, kMachInt32, kMachInt32);
487 m.Branch(m.Word32NotEqual(
488 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
492 m.Return(m.Int32Constant(1));
494 m.Return(m.Int32Constant(0));
495 Stream s = m.Build();
496 ASSERT_EQ(1U, s.size());
497 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
498 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
499 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
500 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
505 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
506 ::testing::ValuesIn(kDPIs));
509 // -----------------------------------------------------------------------------
510 // Data processing instructions with overflow.
513 typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
516 TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
517 const ODPI odpi = GetParam();
518 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
520 m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
521 Stream s = m.Build();
522 ASSERT_EQ(1U, s.size());
523 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
524 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
525 EXPECT_EQ(2U, s[0]->InputCount());
526 EXPECT_LE(1U, s[0]->OutputCount());
527 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
528 EXPECT_EQ(kOverflow, s[0]->flags_condition());
532 TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
533 const ODPI odpi = GetParam();
534 TRACED_FOREACH(int32_t, imm, kImmediates) {
535 StreamBuilder m(this, kMachInt32, kMachInt32);
536 m.Return(m.Projection(
537 1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
538 Stream s = m.Build();
539 ASSERT_EQ(1U, s.size());
540 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
541 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
542 ASSERT_EQ(2U, s[0]->InputCount());
543 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
544 EXPECT_LE(1U, s[0]->OutputCount());
545 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
546 EXPECT_EQ(kOverflow, s[0]->flags_condition());
548 TRACED_FOREACH(int32_t, imm, kImmediates) {
549 StreamBuilder m(this, kMachInt32, kMachInt32);
550 m.Return(m.Projection(
551 1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
552 Stream s = m.Build();
553 ASSERT_EQ(1U, s.size());
554 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
555 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
556 ASSERT_EQ(2U, s[0]->InputCount());
557 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
558 EXPECT_LE(1U, s[0]->OutputCount());
559 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
560 EXPECT_EQ(kOverflow, s[0]->flags_condition());
565 TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
566 const ODPI odpi = GetParam();
567 TRACED_FOREACH(Shift, shift, kShifts) {
568 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
569 m.Return(m.Projection(
570 1, (m.*odpi.constructor)(
572 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
573 Stream s = m.Build();
574 ASSERT_EQ(1U, s.size());
575 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
576 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
577 EXPECT_EQ(3U, s[0]->InputCount());
578 EXPECT_LE(1U, s[0]->OutputCount());
579 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
580 EXPECT_EQ(kOverflow, s[0]->flags_condition());
582 TRACED_FOREACH(Shift, shift, kShifts) {
583 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
584 m.Return(m.Projection(
585 1, (m.*odpi.constructor)(
586 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
588 Stream s = m.Build();
589 ASSERT_EQ(1U, s.size());
590 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
591 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
592 EXPECT_EQ(3U, s[0]->InputCount());
593 EXPECT_LE(1U, s[0]->OutputCount());
594 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
595 EXPECT_EQ(kOverflow, s[0]->flags_condition());
600 TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
601 const ODPI odpi = GetParam();
602 TRACED_FOREACH(Shift, shift, kShifts) {
603 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
604 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
605 m.Return(m.Projection(
606 1, (m.*odpi.constructor)(m.Parameter(0),
607 (m.*shift.constructor)(
608 m.Parameter(1), m.Int32Constant(imm)))));
609 Stream s = m.Build();
610 ASSERT_EQ(1U, s.size());
611 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
612 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
613 ASSERT_EQ(3U, s[0]->InputCount());
614 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
615 EXPECT_LE(1U, s[0]->OutputCount());
616 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
617 EXPECT_EQ(kOverflow, s[0]->flags_condition());
620 TRACED_FOREACH(Shift, shift, kShifts) {
621 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
622 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
623 m.Return(m.Projection(
624 1, (m.*odpi.constructor)(
625 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
627 Stream s = m.Build();
628 ASSERT_EQ(1U, s.size());
629 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
630 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
631 ASSERT_EQ(3U, s[0]->InputCount());
632 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
633 EXPECT_LE(1U, s[0]->OutputCount());
634 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
635 EXPECT_EQ(kOverflow, s[0]->flags_condition());
641 TEST_P(InstructionSelectorODPITest, ValWithParameters) {
642 const ODPI odpi = GetParam();
643 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
645 m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
646 Stream s = m.Build();
647 ASSERT_EQ(1U, s.size());
648 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
649 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
650 EXPECT_EQ(2U, s[0]->InputCount());
651 EXPECT_LE(1U, s[0]->OutputCount());
652 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
656 TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
657 const ODPI odpi = GetParam();
658 TRACED_FOREACH(int32_t, imm, kImmediates) {
659 StreamBuilder m(this, kMachInt32, kMachInt32);
660 m.Return(m.Projection(
661 0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
662 Stream s = m.Build();
663 ASSERT_EQ(1U, s.size());
664 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
665 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
666 ASSERT_EQ(2U, s[0]->InputCount());
667 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
668 EXPECT_LE(1U, s[0]->OutputCount());
669 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
671 TRACED_FOREACH(int32_t, imm, kImmediates) {
672 StreamBuilder m(this, kMachInt32, kMachInt32);
673 m.Return(m.Projection(
674 0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
675 Stream s = m.Build();
676 ASSERT_EQ(1U, s.size());
677 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
678 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
679 ASSERT_EQ(2U, s[0]->InputCount());
680 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
681 EXPECT_LE(1U, s[0]->OutputCount());
682 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
687 TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
688 const ODPI odpi = GetParam();
689 TRACED_FOREACH(Shift, shift, kShifts) {
690 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
691 m.Return(m.Projection(
692 0, (m.*odpi.constructor)(
694 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
695 Stream s = m.Build();
696 ASSERT_EQ(1U, s.size());
697 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
698 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
699 EXPECT_EQ(3U, s[0]->InputCount());
700 EXPECT_LE(1U, s[0]->OutputCount());
701 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
703 TRACED_FOREACH(Shift, shift, kShifts) {
704 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
705 m.Return(m.Projection(
706 0, (m.*odpi.constructor)(
707 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
709 Stream s = m.Build();
710 ASSERT_EQ(1U, s.size());
711 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
712 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
713 EXPECT_EQ(3U, s[0]->InputCount());
714 EXPECT_LE(1U, s[0]->OutputCount());
715 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
720 TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
721 const ODPI odpi = GetParam();
722 TRACED_FOREACH(Shift, shift, kShifts) {
723 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
724 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
725 m.Return(m.Projection(
726 0, (m.*odpi.constructor)(m.Parameter(0),
727 (m.*shift.constructor)(
728 m.Parameter(1), m.Int32Constant(imm)))));
729 Stream s = m.Build();
730 ASSERT_EQ(1U, s.size());
731 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
732 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
733 ASSERT_EQ(3U, s[0]->InputCount());
734 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
735 EXPECT_LE(1U, s[0]->OutputCount());
736 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
739 TRACED_FOREACH(Shift, shift, kShifts) {
740 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
741 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
742 m.Return(m.Projection(
743 0, (m.*odpi.constructor)(
744 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
746 Stream s = m.Build();
747 ASSERT_EQ(1U, s.size());
748 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
749 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
750 ASSERT_EQ(3U, s[0]->InputCount());
751 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
752 EXPECT_LE(1U, s[0]->OutputCount());
753 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
759 TEST_P(InstructionSelectorODPITest, BothWithParameters) {
760 const ODPI odpi = GetParam();
761 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
762 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
763 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
764 Stream s = m.Build();
765 ASSERT_LE(1U, s.size());
766 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
767 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
768 EXPECT_EQ(2U, s[0]->InputCount());
769 EXPECT_EQ(2U, s[0]->OutputCount());
770 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
771 EXPECT_EQ(kOverflow, s[0]->flags_condition());
775 TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
776 const ODPI odpi = GetParam();
777 TRACED_FOREACH(int32_t, imm, kImmediates) {
778 StreamBuilder m(this, kMachInt32, kMachInt32);
779 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
780 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
781 Stream s = m.Build();
782 ASSERT_LE(1U, s.size());
783 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
784 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
785 ASSERT_EQ(2U, s[0]->InputCount());
786 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
787 EXPECT_EQ(2U, s[0]->OutputCount());
788 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
789 EXPECT_EQ(kOverflow, s[0]->flags_condition());
791 TRACED_FOREACH(int32_t, imm, kImmediates) {
792 StreamBuilder m(this, kMachInt32, kMachInt32);
793 Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
794 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
795 Stream s = m.Build();
796 ASSERT_LE(1U, s.size());
797 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
798 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
799 ASSERT_EQ(2U, s[0]->InputCount());
800 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
801 EXPECT_EQ(2U, s[0]->OutputCount());
802 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
803 EXPECT_EQ(kOverflow, s[0]->flags_condition());
808 TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
809 const ODPI odpi = GetParam();
810 TRACED_FOREACH(Shift, shift, kShifts) {
811 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
812 Node* n = (m.*odpi.constructor)(
813 m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
814 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
815 Stream s = m.Build();
816 ASSERT_LE(1U, s.size());
817 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
818 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
819 EXPECT_EQ(3U, s[0]->InputCount());
820 EXPECT_EQ(2U, s[0]->OutputCount());
821 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
822 EXPECT_EQ(kOverflow, s[0]->flags_condition());
824 TRACED_FOREACH(Shift, shift, kShifts) {
825 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
826 Node* n = (m.*odpi.constructor)(
827 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
828 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
829 Stream s = m.Build();
830 ASSERT_LE(1U, s.size());
831 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
832 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
833 EXPECT_EQ(3U, s[0]->InputCount());
834 EXPECT_EQ(2U, s[0]->OutputCount());
835 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
836 EXPECT_EQ(kOverflow, s[0]->flags_condition());
841 TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
842 const ODPI odpi = GetParam();
843 TRACED_FOREACH(Shift, shift, kShifts) {
844 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
845 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
846 Node* n = (m.*odpi.constructor)(
848 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
849 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
850 Stream s = m.Build();
851 ASSERT_LE(1U, s.size());
852 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
853 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
854 ASSERT_EQ(3U, s[0]->InputCount());
855 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
856 EXPECT_EQ(2U, s[0]->OutputCount());
857 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
858 EXPECT_EQ(kOverflow, s[0]->flags_condition());
861 TRACED_FOREACH(Shift, shift, kShifts) {
862 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
863 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
864 Node* n = (m.*odpi.constructor)(
865 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
867 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
868 Stream s = m.Build();
869 ASSERT_LE(1U, s.size());
870 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
871 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
872 ASSERT_EQ(3U, s[0]->InputCount());
873 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
874 EXPECT_EQ(2U, s[0]->OutputCount());
875 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
876 EXPECT_EQ(kOverflow, s[0]->flags_condition());
882 TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
883 const ODPI odpi = GetParam();
884 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
886 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
887 m.Branch(m.Projection(1, n), &a, &b);
889 m.Return(m.Int32Constant(0));
891 m.Return(m.Projection(0, n));
892 Stream s = m.Build();
893 ASSERT_EQ(1U, s.size());
894 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
895 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
896 EXPECT_EQ(4U, s[0]->InputCount());
897 EXPECT_EQ(1U, s[0]->OutputCount());
898 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
899 EXPECT_EQ(kOverflow, s[0]->flags_condition());
903 TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
904 const ODPI odpi = GetParam();
905 TRACED_FOREACH(int32_t, imm, kImmediates) {
906 StreamBuilder m(this, kMachInt32, kMachInt32);
908 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
909 m.Branch(m.Projection(1, n), &a, &b);
911 m.Return(m.Int32Constant(0));
913 m.Return(m.Projection(0, n));
914 Stream s = m.Build();
915 ASSERT_EQ(1U, s.size());
916 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
917 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
918 ASSERT_EQ(4U, s[0]->InputCount());
919 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
920 EXPECT_EQ(1U, s[0]->OutputCount());
921 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
922 EXPECT_EQ(kOverflow, s[0]->flags_condition());
924 TRACED_FOREACH(int32_t, imm, kImmediates) {
925 StreamBuilder m(this, kMachInt32, kMachInt32);
927 Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
928 m.Branch(m.Projection(1, n), &a, &b);
930 m.Return(m.Int32Constant(0));
932 m.Return(m.Projection(0, n));
933 Stream s = m.Build();
934 ASSERT_EQ(1U, s.size());
935 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
936 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
937 ASSERT_EQ(4U, s[0]->InputCount());
938 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
939 EXPECT_EQ(1U, s[0]->OutputCount());
940 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
941 EXPECT_EQ(kOverflow, s[0]->flags_condition());
946 TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
947 const ODPI odpi = GetParam();
948 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
950 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
951 m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
953 m.Return(m.Projection(0, n));
955 m.Return(m.Int32Constant(0));
956 Stream s = m.Build();
957 ASSERT_EQ(1U, s.size());
958 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
959 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
960 EXPECT_EQ(4U, s[0]->InputCount());
961 EXPECT_EQ(1U, s[0]->OutputCount());
962 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
963 EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
967 TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
968 const ODPI odpi = GetParam();
969 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
971 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
972 m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
974 m.Return(m.Projection(0, n));
976 m.Return(m.Int32Constant(0));
977 Stream s = m.Build();
978 ASSERT_EQ(1U, s.size());
979 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
980 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
981 EXPECT_EQ(4U, s[0]->InputCount());
982 EXPECT_EQ(1U, s[0]->OutputCount());
983 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
984 EXPECT_EQ(kOverflow, s[0]->flags_condition());
988 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
989 ::testing::ValuesIn(kODPIs));
992 // -----------------------------------------------------------------------------
996 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
999 TEST_P(InstructionSelectorShiftTest, Parameters) {
1000 const Shift shift = GetParam();
1001 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1002 m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
1003 Stream s = m.Build();
1004 ASSERT_EQ(1U, s.size());
1005 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1006 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1007 EXPECT_EQ(2U, s[0]->InputCount());
1008 EXPECT_EQ(1U, s[0]->OutputCount());
1012 TEST_P(InstructionSelectorShiftTest, Immediate) {
1013 const Shift shift = GetParam();
1014 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1015 StreamBuilder m(this, kMachInt32, kMachInt32);
1016 m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
1017 Stream s = m.Build();
1018 ASSERT_EQ(1U, s.size());
1019 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1020 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1021 ASSERT_EQ(2U, s[0]->InputCount());
1022 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1023 EXPECT_EQ(1U, s[0]->OutputCount());
1028 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
1029 const Shift shift = GetParam();
1031 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1033 m.Word32Equal(m.Parameter(0),
1034 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
1035 Stream s = m.Build();
1036 ASSERT_EQ(1U, s.size());
1037 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1038 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1039 EXPECT_EQ(3U, s[0]->InputCount());
1040 EXPECT_EQ(1U, s[0]->OutputCount());
1041 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1042 EXPECT_EQ(kEqual, s[0]->flags_condition());
1045 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1047 m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
1049 Stream s = m.Build();
1050 ASSERT_EQ(1U, s.size());
1051 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1052 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1053 EXPECT_EQ(3U, s[0]->InputCount());
1054 EXPECT_EQ(1U, s[0]->OutputCount());
1055 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1056 EXPECT_EQ(kEqual, s[0]->flags_condition());
1061 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
1062 const Shift shift = GetParam();
1063 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1064 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1065 m.Return(m.Word32Equal(
1066 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
1068 Stream s = m.Build();
1069 ASSERT_EQ(1U, s.size());
1070 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1071 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1072 ASSERT_EQ(3U, s[0]->InputCount());
1073 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1074 EXPECT_EQ(1U, s[0]->OutputCount());
1075 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1076 EXPECT_EQ(kEqual, s[0]->flags_condition());
1078 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1079 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1080 m.Return(m.Word32Equal(
1082 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
1083 Stream s = m.Build();
1084 ASSERT_EQ(1U, s.size());
1085 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1086 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1087 ASSERT_EQ(3U, s[0]->InputCount());
1088 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1089 EXPECT_EQ(1U, s[0]->OutputCount());
1090 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1091 EXPECT_EQ(kEqual, s[0]->flags_condition());
1096 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
1097 const Shift shift = GetParam();
1098 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1100 m.Word32Equal(m.Int32Constant(0),
1101 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1102 Stream s = m.Build();
1103 ASSERT_EQ(1U, s.size());
1104 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1105 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1106 EXPECT_EQ(2U, s[0]->InputCount());
1107 EXPECT_EQ(2U, s[0]->OutputCount());
1108 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1109 EXPECT_EQ(kEqual, s[0]->flags_condition());
1113 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
1114 const Shift shift = GetParam();
1115 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1116 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1117 m.Return(m.Word32Equal(
1119 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1120 Stream s = m.Build();
1121 ASSERT_EQ(1U, s.size());
1122 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1123 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1124 ASSERT_EQ(2U, s[0]->InputCount());
1125 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1126 EXPECT_EQ(2U, s[0]->OutputCount());
1127 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1128 EXPECT_EQ(kEqual, s[0]->flags_condition());
1133 TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
1134 const Shift shift = GetParam();
1135 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1136 m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1137 Stream s = m.Build();
1138 ASSERT_EQ(1U, s.size());
1139 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1140 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1141 EXPECT_EQ(2U, s[0]->InputCount());
1142 EXPECT_EQ(1U, s[0]->OutputCount());
1146 TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
1147 const Shift shift = GetParam();
1148 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1149 StreamBuilder m(this, kMachInt32, kMachInt32);
1150 m.Return(m.Word32Not(
1151 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1152 Stream s = m.Build();
1153 ASSERT_EQ(1U, s.size());
1154 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1155 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1156 ASSERT_EQ(2U, s[0]->InputCount());
1157 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1158 EXPECT_EQ(1U, s[0]->OutputCount());
1163 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
1164 const Shift shift = GetParam();
1165 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1166 m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
1167 m.Parameter(1), m.Parameter(2)))));
1168 Stream s = m.Build();
1169 ASSERT_EQ(1U, s.size());
1170 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1171 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1172 EXPECT_EQ(3U, s[0]->InputCount());
1173 EXPECT_EQ(1U, s[0]->OutputCount());
1177 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
1178 const Shift shift = GetParam();
1179 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1180 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1181 m.Return(m.Word32And(m.Parameter(0),
1182 m.Word32Not((m.*shift.constructor)(
1183 m.Parameter(1), m.Int32Constant(imm)))));
1184 Stream s = m.Build();
1185 ASSERT_EQ(1U, s.size());
1186 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1187 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1188 ASSERT_EQ(3U, s[0]->InputCount());
1189 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1190 EXPECT_EQ(1U, s[0]->OutputCount());
1195 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
1196 ::testing::ValuesIn(kShifts));
1199 // -----------------------------------------------------------------------------
1200 // Memory access instructions.
1205 struct MemoryAccess {
1207 ArchOpcode ldr_opcode;
1208 ArchOpcode str_opcode;
1209 bool (InstructionSelectorTest::Stream::*val_predicate)(
1210 const InstructionOperand*) const;
1211 const int32_t immediates[40];
1215 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
1216 return os << memacc.type;
1220 static const MemoryAccess kMemoryAccesses[] = {
1224 &InstructionSelectorTest::Stream::IsInteger,
1225 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
1226 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
1227 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
1231 &InstructionSelectorTest::Stream::IsInteger,
1232 {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
1233 -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
1234 39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
1238 &InstructionSelectorTest::Stream::IsInteger,
1239 {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
1240 -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
1241 102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
1245 &InstructionSelectorTest::Stream::IsInteger,
1246 {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
1247 -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
1248 114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
1252 &InstructionSelectorTest::Stream::IsInteger,
1253 {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
1254 -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
1255 93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
1259 &InstructionSelectorTest::Stream::IsDouble,
1260 {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
1261 -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
1262 24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
1266 &InstructionSelectorTest::Stream::IsDouble,
1267 {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
1268 -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
1269 108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
1274 typedef InstructionSelectorTestWithParam<MemoryAccess>
1275 InstructionSelectorMemoryAccessTest;
1278 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
1279 const MemoryAccess memacc = GetParam();
1280 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
1281 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
1282 Stream s = m.Build();
1283 ASSERT_EQ(1U, s.size());
1284 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1285 EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1286 EXPECT_EQ(2U, s[0]->InputCount());
1287 ASSERT_EQ(1U, s[0]->OutputCount());
1288 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1292 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
1293 const MemoryAccess memacc = GetParam();
1294 TRACED_FOREACH(int32_t, index, memacc.immediates) {
1295 StreamBuilder m(this, memacc.type, kMachPtr);
1296 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
1297 Stream s = m.Build();
1298 ASSERT_EQ(1U, s.size());
1299 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
1300 EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1301 ASSERT_EQ(2U, s[0]->InputCount());
1302 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1303 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1304 ASSERT_EQ(1U, s[0]->OutputCount());
1305 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
1310 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
1311 const MemoryAccess memacc = GetParam();
1312 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
1313 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
1314 m.Return(m.Int32Constant(0));
1315 Stream s = m.Build();
1316 ASSERT_EQ(1U, s.size());
1317 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1318 EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
1319 EXPECT_EQ(3U, s[0]->InputCount());
1320 EXPECT_EQ(0U, s[0]->OutputCount());
1324 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
1325 const MemoryAccess memacc = GetParam();
1326 TRACED_FOREACH(int32_t, index, memacc.immediates) {
1327 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
1328 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
1330 m.Return(m.Int32Constant(0));
1331 Stream s = m.Build();
1332 ASSERT_EQ(1U, s.size());
1333 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
1334 EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
1335 ASSERT_EQ(3U, s[0]->InputCount());
1336 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1337 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
1338 EXPECT_EQ(0U, s[0]->OutputCount());
1343 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1344 InstructionSelectorMemoryAccessTest,
1345 ::testing::ValuesIn(kMemoryAccesses));
1348 // -----------------------------------------------------------------------------
1352 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
1353 StreamBuilder m(this, kMachFloat64, kMachFloat32);
1354 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
1355 Stream s = m.Build();
1356 ASSERT_EQ(1U, s.size());
1357 EXPECT_EQ(kArmVcvtF64F32, s[0]->arch_opcode());
1358 EXPECT_EQ(1U, s[0]->InputCount());
1359 EXPECT_EQ(1U, s[0]->OutputCount());
1363 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
1364 StreamBuilder m(this, kMachFloat32, kMachFloat64);
1365 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
1366 Stream s = m.Build();
1367 ASSERT_EQ(1U, s.size());
1368 EXPECT_EQ(kArmVcvtF32F64, s[0]->arch_opcode());
1369 EXPECT_EQ(1U, s[0]->InputCount());
1370 EXPECT_EQ(1U, s[0]->OutputCount());
1374 // -----------------------------------------------------------------------------
1381 Constructor constructor;
1382 const char* constructor_name;
1383 FlagsCondition flags_condition;
1384 FlagsCondition negated_flags_condition;
1388 std::ostream& operator<<(std::ostream& os, const Comparison& cmp) {
1389 return os << cmp.constructor_name;
1393 const Comparison kComparisons[] = {
1394 {&RawMachineAssembler::Word32Equal, "Word32Equal", kEqual, kNotEqual},
1395 {&RawMachineAssembler::Int32LessThan, "Int32LessThan", kSignedLessThan,
1396 kSignedGreaterThanOrEqual},
1397 {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
1398 kSignedLessThanOrEqual, kSignedGreaterThan},
1399 {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kUnsignedLessThan,
1400 kUnsignedGreaterThanOrEqual},
1401 {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
1402 kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
1407 typedef InstructionSelectorTestWithParam<Comparison>
1408 InstructionSelectorComparisonTest;
1411 TEST_P(InstructionSelectorComparisonTest, Parameters) {
1412 const Comparison& cmp = GetParam();
1413 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1414 Node* const p0 = m.Parameter(0);
1415 Node* const p1 = m.Parameter(1);
1416 Node* const r = (m.*cmp.constructor)(p0, p1);
1418 Stream const s = m.Build();
1419 ASSERT_EQ(1U, s.size());
1420 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1421 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1422 ASSERT_EQ(2U, s[0]->InputCount());
1423 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1424 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1425 ASSERT_EQ(1U, s[0]->OutputCount());
1426 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1427 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1428 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1432 TEST_P(InstructionSelectorComparisonTest, Word32EqualWithZero) {
1434 const Comparison& cmp = GetParam();
1435 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1436 Node* const p0 = m.Parameter(0);
1437 Node* const p1 = m.Parameter(1);
1439 m.Word32Equal((m.*cmp.constructor)(p0, p1), m.Int32Constant(0));
1441 Stream const s = m.Build();
1442 ASSERT_EQ(1U, s.size());
1443 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1444 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1445 ASSERT_EQ(2U, s[0]->InputCount());
1446 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1447 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1448 ASSERT_EQ(1U, s[0]->OutputCount());
1449 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1450 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1451 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1454 const Comparison& cmp = GetParam();
1455 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1456 Node* const p0 = m.Parameter(0);
1457 Node* const p1 = m.Parameter(1);
1459 m.Word32Equal(m.Int32Constant(0), (m.*cmp.constructor)(p0, p1));
1461 Stream const s = m.Build();
1462 ASSERT_EQ(1U, s.size());
1463 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1464 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1465 ASSERT_EQ(2U, s[0]->InputCount());
1466 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1467 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
1468 ASSERT_EQ(1U, s[0]->OutputCount());
1469 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
1470 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1471 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1476 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1477 InstructionSelectorComparisonTest,
1478 ::testing::ValuesIn(kComparisons));
1481 // -----------------------------------------------------------------------------
1482 // Floating point comparisons.
1485 const Comparison kFPComparisons[] = {
1486 {&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual},
1487 {&RawMachineAssembler::Float64LessThan, "Float64LessThan",
1488 kUnsignedLessThan, kUnsignedGreaterThanOrEqual},
1489 {&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
1490 kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
1493 typedef InstructionSelectorTestWithParam<Comparison>
1494 InstructionSelectorFPComparisonTest;
1497 TEST_P(InstructionSelectorFPComparisonTest, WithParameters) {
1498 const Comparison& cmp = GetParam();
1499 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
1500 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
1501 Stream const s = m.Build();
1502 ASSERT_EQ(1U, s.size());
1503 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1504 ASSERT_EQ(2U, s[0]->InputCount());
1505 ASSERT_EQ(1U, s[0]->OutputCount());
1506 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1507 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1511 TEST_P(InstructionSelectorFPComparisonTest, NegatedWithParameters) {
1512 const Comparison& cmp = GetParam();
1513 StreamBuilder m(this, kMachInt32, kMachFloat64, kMachFloat64);
1515 m.WordBinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))));
1516 Stream const s = m.Build();
1517 ASSERT_EQ(1U, s.size());
1518 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1519 ASSERT_EQ(2U, s[0]->InputCount());
1520 ASSERT_EQ(1U, s[0]->OutputCount());
1521 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1522 EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
1526 TEST_P(InstructionSelectorFPComparisonTest, WithImmediateZeroOnRight) {
1527 const Comparison& cmp = GetParam();
1528 StreamBuilder m(this, kMachInt32, kMachFloat64);
1529 m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0)));
1530 Stream const s = m.Build();
1531 ASSERT_EQ(1U, s.size());
1532 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1533 ASSERT_EQ(2U, s[0]->InputCount());
1534 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1535 ASSERT_EQ(1U, s[0]->OutputCount());
1536 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1537 EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
1541 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1542 InstructionSelectorFPComparisonTest,
1543 ::testing::ValuesIn(kFPComparisons));
1546 TEST_F(InstructionSelectorTest, Float64EqualWithImmediateZeroOnLeft) {
1547 StreamBuilder m(this, kMachInt32, kMachFloat64);
1548 m.Return(m.Float64Equal(m.Float64Constant(0.0), m.Parameter(0)));
1549 Stream s = m.Build();
1550 ASSERT_EQ(1U, s.size());
1551 EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
1552 EXPECT_EQ(2U, s[0]->InputCount());
1553 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1554 EXPECT_EQ(1U, s[0]->OutputCount());
1555 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1556 EXPECT_EQ(kEqual, s[0]->flags_condition());
1560 // -----------------------------------------------------------------------------
1564 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
1565 StreamBuilder m(this, kMachFloat64, kMachFloat64);
1566 Node* const p0 = m.Parameter(0);
1567 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
1569 Stream s = m.Build();
1570 ASSERT_EQ(1U, s.size());
1571 EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
1572 ASSERT_EQ(1U, s[0]->InputCount());
1573 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1574 ASSERT_EQ(1U, s[0]->OutputCount());
1575 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1579 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
1581 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1582 Node* const p0 = m.Parameter(0);
1583 Node* const p1 = m.Parameter(1);
1584 Node* const p2 = m.Parameter(2);
1585 Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2));
1587 Stream s = m.Build();
1588 ASSERT_EQ(1U, s.size());
1589 EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1590 ASSERT_EQ(3U, s[0]->InputCount());
1591 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1592 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1593 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1594 ASSERT_EQ(1U, s[0]->OutputCount());
1595 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1598 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1599 Node* const p0 = m.Parameter(0);
1600 Node* const p1 = m.Parameter(1);
1601 Node* const p2 = m.Parameter(2);
1602 Node* const n = m.Int32Add(m.Int32Mul(p1, p2), p0);
1604 Stream s = m.Build();
1605 ASSERT_EQ(1U, s.size());
1606 EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1607 ASSERT_EQ(3U, s[0]->InputCount());
1608 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1609 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1610 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1611 ASSERT_EQ(1U, s[0]->OutputCount());
1612 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1617 TEST_F(InstructionSelectorTest, Int32AddWithInt32MulHigh) {
1619 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1620 Node* const p0 = m.Parameter(0);
1621 Node* const p1 = m.Parameter(1);
1622 Node* const p2 = m.Parameter(2);
1623 Node* const n = m.Int32Add(p0, m.Int32MulHigh(p1, p2));
1625 Stream s = m.Build();
1626 ASSERT_EQ(1U, s.size());
1627 EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
1628 ASSERT_EQ(3U, s[0]->InputCount());
1629 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1630 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1631 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1632 ASSERT_EQ(1U, s[0]->OutputCount());
1633 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1636 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1637 Node* const p0 = m.Parameter(0);
1638 Node* const p1 = m.Parameter(1);
1639 Node* const p2 = m.Parameter(2);
1640 Node* const n = m.Int32Add(m.Int32MulHigh(p1, p2), p0);
1642 Stream s = m.Build();
1643 ASSERT_EQ(1U, s.size());
1644 EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
1645 ASSERT_EQ(3U, s[0]->InputCount());
1646 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1647 EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
1648 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
1649 ASSERT_EQ(1U, s[0]->OutputCount());
1650 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1655 TEST_F(InstructionSelectorTest, Int32AddWithWord32And) {
1657 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1658 Node* const p0 = m.Parameter(0);
1659 Node* const p1 = m.Parameter(1);
1660 Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xff)), p1);
1662 Stream s = m.Build();
1663 ASSERT_EQ(1U, s.size());
1664 EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
1665 ASSERT_EQ(3U, s[0]->InputCount());
1666 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1667 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1668 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1669 ASSERT_EQ(1U, s[0]->OutputCount());
1670 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1673 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1674 Node* const p0 = m.Parameter(0);
1675 Node* const p1 = m.Parameter(1);
1676 Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xff)));
1678 Stream s = m.Build();
1679 ASSERT_EQ(1U, s.size());
1680 EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
1681 ASSERT_EQ(3U, s[0]->InputCount());
1682 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1683 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1684 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1685 ASSERT_EQ(1U, s[0]->OutputCount());
1686 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1689 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1690 Node* const p0 = m.Parameter(0);
1691 Node* const p1 = m.Parameter(1);
1692 Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xffff)), p1);
1694 Stream s = m.Build();
1695 ASSERT_EQ(1U, s.size());
1696 EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
1697 ASSERT_EQ(3U, s[0]->InputCount());
1698 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1699 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1700 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1701 ASSERT_EQ(1U, s[0]->OutputCount());
1702 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1705 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1706 Node* const p0 = m.Parameter(0);
1707 Node* const p1 = m.Parameter(1);
1708 Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xffff)));
1710 Stream s = m.Build();
1711 ASSERT_EQ(1U, s.size());
1712 EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
1713 ASSERT_EQ(3U, s[0]->InputCount());
1714 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1715 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1716 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1717 ASSERT_EQ(1U, s[0]->OutputCount());
1718 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1723 TEST_F(InstructionSelectorTest, Int32AddWithWord32SarWithWord32Shl) {
1725 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1726 Node* const p0 = m.Parameter(0);
1727 Node* const p1 = m.Parameter(1);
1728 Node* const r = m.Int32Add(
1729 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)),
1732 Stream s = m.Build();
1733 ASSERT_EQ(1U, s.size());
1734 EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
1735 ASSERT_EQ(3U, s[0]->InputCount());
1736 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1737 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1738 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1739 ASSERT_EQ(1U, s[0]->OutputCount());
1740 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1743 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1744 Node* const p0 = m.Parameter(0);
1745 Node* const p1 = m.Parameter(1);
1746 Node* const r = m.Int32Add(
1748 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)));
1750 Stream s = m.Build();
1751 ASSERT_EQ(1U, s.size());
1752 EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
1753 ASSERT_EQ(3U, s[0]->InputCount());
1754 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1755 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1756 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1757 ASSERT_EQ(1U, s[0]->OutputCount());
1758 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1761 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1762 Node* const p0 = m.Parameter(0);
1763 Node* const p1 = m.Parameter(1);
1764 Node* const r = m.Int32Add(
1765 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)),
1768 Stream s = m.Build();
1769 ASSERT_EQ(1U, s.size());
1770 EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
1771 ASSERT_EQ(3U, s[0]->InputCount());
1772 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1773 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1774 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1775 ASSERT_EQ(1U, s[0]->OutputCount());
1776 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1779 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1780 Node* const p0 = m.Parameter(0);
1781 Node* const p1 = m.Parameter(1);
1782 Node* const r = m.Int32Add(
1784 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)));
1786 Stream s = m.Build();
1787 ASSERT_EQ(1U, s.size());
1788 EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
1789 ASSERT_EQ(3U, s[0]->InputCount());
1790 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
1791 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
1792 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
1793 ASSERT_EQ(1U, s[0]->OutputCount());
1794 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
1799 TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
1800 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1802 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1803 Stream s = m.Build();
1804 ASSERT_EQ(2U, s.size());
1805 EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1806 ASSERT_EQ(1U, s[0]->OutputCount());
1807 EXPECT_EQ(kArmSub, s[1]->arch_opcode());
1808 ASSERT_EQ(2U, s[1]->InputCount());
1809 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
1813 TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
1814 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
1816 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1817 Stream s = m.Build(MLS);
1818 ASSERT_EQ(1U, s.size());
1819 EXPECT_EQ(kArmMls, s[0]->arch_opcode());
1820 EXPECT_EQ(1U, s[0]->OutputCount());
1821 EXPECT_EQ(3U, s[0]->InputCount());
1825 TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
1826 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1827 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1828 Stream s = m.Build();
1829 ASSERT_EQ(4U, s.size());
1830 EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1831 ASSERT_EQ(1U, s[0]->OutputCount());
1832 EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1833 ASSERT_EQ(1U, s[1]->OutputCount());
1834 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1835 ASSERT_EQ(2U, s[2]->InputCount());
1836 ASSERT_EQ(1U, s[2]->OutputCount());
1837 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1838 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1839 EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1840 ASSERT_EQ(1U, s[3]->InputCount());
1841 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1845 TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
1846 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1847 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1848 Stream s = m.Build(SUDIV);
1849 ASSERT_EQ(1U, s.size());
1850 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1854 TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
1855 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1856 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1857 Stream s = m.Build();
1858 ASSERT_EQ(6U, s.size());
1859 EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1860 ASSERT_EQ(1U, s[0]->OutputCount());
1861 EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1862 ASSERT_EQ(1U, s[1]->OutputCount());
1863 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1864 ASSERT_EQ(2U, s[2]->InputCount());
1865 ASSERT_EQ(1U, s[2]->OutputCount());
1866 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1867 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1868 EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1869 ASSERT_EQ(1U, s[3]->InputCount());
1870 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1871 EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1872 ASSERT_EQ(1U, s[4]->OutputCount());
1873 ASSERT_EQ(2U, s[4]->InputCount());
1874 EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1875 EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1876 EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1877 ASSERT_EQ(1U, s[5]->OutputCount());
1878 ASSERT_EQ(2U, s[5]->InputCount());
1879 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1880 EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1884 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
1885 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1886 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1887 Stream s = m.Build(SUDIV);
1888 ASSERT_EQ(3U, s.size());
1889 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1890 ASSERT_EQ(1U, s[0]->OutputCount());
1891 ASSERT_EQ(2U, s[0]->InputCount());
1892 EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1893 ASSERT_EQ(1U, s[1]->OutputCount());
1894 ASSERT_EQ(2U, s[1]->InputCount());
1895 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1896 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1897 EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1898 ASSERT_EQ(1U, s[2]->OutputCount());
1899 ASSERT_EQ(2U, s[2]->InputCount());
1900 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1901 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1905 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
1906 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1907 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1908 Stream s = m.Build(MLS, SUDIV);
1909 ASSERT_EQ(2U, s.size());
1910 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1911 ASSERT_EQ(1U, s[0]->OutputCount());
1912 ASSERT_EQ(2U, s[0]->InputCount());
1913 EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1914 ASSERT_EQ(1U, s[1]->OutputCount());
1915 ASSERT_EQ(3U, s[1]->InputCount());
1916 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1917 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1918 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1922 TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
1923 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1924 m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
1925 Stream s = m.Build();
1926 ASSERT_EQ(1U, s.size());
1927 EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1928 EXPECT_EQ(2U, s[0]->InputCount());
1929 EXPECT_EQ(1U, s[0]->OutputCount());
1933 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
1934 // x * (2^k + 1) -> x + (x >> k)
1935 TRACED_FORRANGE(int32_t, k, 1, 30) {
1936 StreamBuilder m(this, kMachInt32, kMachInt32);
1937 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
1938 Stream s = m.Build();
1939 ASSERT_EQ(1U, s.size());
1940 EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1941 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1942 ASSERT_EQ(3U, s[0]->InputCount());
1943 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1944 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1945 EXPECT_EQ(1U, s[0]->OutputCount());
1947 // x * (2^k - 1) -> -x + (x >> k)
1948 TRACED_FORRANGE(int32_t, k, 3, 30) {
1949 StreamBuilder m(this, kMachInt32, kMachInt32);
1950 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
1951 Stream s = m.Build();
1952 ASSERT_EQ(1U, s.size());
1953 EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1954 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1955 ASSERT_EQ(3U, s[0]->InputCount());
1956 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1957 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1958 EXPECT_EQ(1U, s[0]->OutputCount());
1960 // (2^k + 1) * x -> x + (x >> k)
1961 TRACED_FORRANGE(int32_t, k, 1, 30) {
1962 StreamBuilder m(this, kMachInt32, kMachInt32);
1963 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
1964 Stream s = m.Build();
1965 ASSERT_EQ(1U, s.size());
1966 EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1967 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1968 ASSERT_EQ(3U, s[0]->InputCount());
1969 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1970 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1971 EXPECT_EQ(1U, s[0]->OutputCount());
1973 // x * (2^k - 1) -> -x + (x >> k)
1974 TRACED_FORRANGE(int32_t, k, 3, 30) {
1975 StreamBuilder m(this, kMachInt32, kMachInt32);
1976 m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
1977 Stream s = m.Build();
1978 ASSERT_EQ(1U, s.size());
1979 EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1980 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1981 ASSERT_EQ(3U, s[0]->InputCount());
1982 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1983 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1984 EXPECT_EQ(1U, s[0]->OutputCount());
1989 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
1990 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
1991 Node* const p0 = m.Parameter(0);
1992 Node* const p1 = m.Parameter(1);
1993 Node* const n = m.Int32MulHigh(p0, p1);
1995 Stream s = m.Build();
1996 ASSERT_EQ(1U, s.size());
1997 EXPECT_EQ(kArmSmmul, s[0]->arch_opcode());
1998 ASSERT_EQ(2U, s[0]->InputCount());
1999 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2000 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2001 ASSERT_EQ(1U, s[0]->OutputCount());
2002 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
2006 TEST_F(InstructionSelectorTest, Uint32MulHighWithParameters) {
2007 StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
2008 Node* const p0 = m.Parameter(0);
2009 Node* const p1 = m.Parameter(1);
2010 Node* const n = m.Uint32MulHigh(p0, p1);
2012 Stream s = m.Build();
2013 ASSERT_EQ(1U, s.size());
2014 EXPECT_EQ(kArmUmull, s[0]->arch_opcode());
2015 ASSERT_EQ(2U, s[0]->InputCount());
2016 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2017 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2018 ASSERT_EQ(2U, s[0]->OutputCount());
2019 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->OutputAt(1)));
2023 TEST_F(InstructionSelectorTest, Uint32DivWithParameters) {
2024 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2025 m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
2026 Stream s = m.Build();
2027 ASSERT_EQ(4U, s.size());
2028 EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
2029 ASSERT_EQ(1U, s[0]->OutputCount());
2030 EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
2031 ASSERT_EQ(1U, s[1]->OutputCount());
2032 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
2033 ASSERT_EQ(2U, s[2]->InputCount());
2034 ASSERT_EQ(1U, s[2]->OutputCount());
2035 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
2036 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2037 EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
2038 ASSERT_EQ(1U, s[3]->InputCount());
2039 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
2043 TEST_F(InstructionSelectorTest, Uint32DivWithParametersForSUDIV) {
2044 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2045 m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
2046 Stream s = m.Build(SUDIV);
2047 ASSERT_EQ(1U, s.size());
2048 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2052 TEST_F(InstructionSelectorTest, Uint32ModWithParameters) {
2053 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2054 m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2055 Stream s = m.Build();
2056 ASSERT_EQ(6U, s.size());
2057 EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
2058 ASSERT_EQ(1U, s[0]->OutputCount());
2059 EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
2060 ASSERT_EQ(1U, s[1]->OutputCount());
2061 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
2062 ASSERT_EQ(2U, s[2]->InputCount());
2063 ASSERT_EQ(1U, s[2]->OutputCount());
2064 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
2065 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2066 EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
2067 ASSERT_EQ(1U, s[3]->InputCount());
2068 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
2069 EXPECT_EQ(kArmMul, s[4]->arch_opcode());
2070 ASSERT_EQ(1U, s[4]->OutputCount());
2071 ASSERT_EQ(2U, s[4]->InputCount());
2072 EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
2073 EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
2074 EXPECT_EQ(kArmSub, s[5]->arch_opcode());
2075 ASSERT_EQ(1U, s[5]->OutputCount());
2076 ASSERT_EQ(2U, s[5]->InputCount());
2077 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
2078 EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
2082 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIV) {
2083 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2084 m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2085 Stream s = m.Build(SUDIV);
2086 ASSERT_EQ(3U, s.size());
2087 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2088 ASSERT_EQ(1U, s[0]->OutputCount());
2089 ASSERT_EQ(2U, s[0]->InputCount());
2090 EXPECT_EQ(kArmMul, s[1]->arch_opcode());
2091 ASSERT_EQ(1U, s[1]->OutputCount());
2092 ASSERT_EQ(2U, s[1]->InputCount());
2093 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2094 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
2095 EXPECT_EQ(kArmSub, s[2]->arch_opcode());
2096 ASSERT_EQ(1U, s[2]->OutputCount());
2097 ASSERT_EQ(2U, s[2]->InputCount());
2098 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
2099 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
2103 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIVAndMLS) {
2104 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2105 m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
2106 Stream s = m.Build(MLS, SUDIV);
2107 ASSERT_EQ(2U, s.size());
2108 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
2109 ASSERT_EQ(1U, s[0]->OutputCount());
2110 ASSERT_EQ(2U, s[0]->InputCount());
2111 EXPECT_EQ(kArmMls, s[1]->arch_opcode());
2112 ASSERT_EQ(1U, s[1]->OutputCount());
2113 ASSERT_EQ(3U, s[1]->InputCount());
2114 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2115 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
2116 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
2120 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
2121 TRACED_FORRANGE(int32_t, width, 1, 32) {
2122 StreamBuilder m(this, kMachInt32, kMachInt32);
2123 m.Return(m.Word32And(m.Parameter(0),
2124 m.Int32Constant(0xffffffffu >> (32 - width))));
2125 Stream s = m.Build(ARMv7);
2126 ASSERT_EQ(1U, s.size());
2127 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2128 ASSERT_EQ(3U, s[0]->InputCount());
2129 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2130 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2132 TRACED_FORRANGE(int32_t, width, 1, 32) {
2133 StreamBuilder m(this, kMachInt32, kMachInt32);
2134 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
2136 Stream s = m.Build(ARMv7);
2137 ASSERT_EQ(1U, s.size());
2138 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2139 ASSERT_EQ(3U, s[0]->InputCount());
2140 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2141 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2146 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
2147 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2148 TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
2149 StreamBuilder m(this, kMachInt32, kMachInt32);
2150 m.Return(m.Word32And(
2152 m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
2153 Stream s = m.Build(ARMv7);
2154 ASSERT_EQ(1U, s.size());
2155 EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
2156 ASSERT_EQ(1U, s[0]->OutputCount());
2158 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
2159 ASSERT_EQ(3U, s[0]->InputCount());
2160 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2161 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2164 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2165 TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
2166 StreamBuilder m(this, kMachInt32, kMachInt32);
2168 m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
2170 Stream s = m.Build(ARMv7);
2171 ASSERT_EQ(1U, s.size());
2172 EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
2173 ASSERT_EQ(1U, s[0]->OutputCount());
2175 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
2176 ASSERT_EQ(3U, s[0]->InputCount());
2177 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2178 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2184 TEST_F(InstructionSelectorTest, Word32AndWith0xffff) {
2186 StreamBuilder m(this, kMachInt32, kMachInt32);
2187 Node* const p0 = m.Parameter(0);
2188 Node* const r = m.Word32And(p0, m.Int32Constant(0xffff));
2190 Stream s = m.Build();
2191 ASSERT_EQ(1U, s.size());
2192 EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
2193 ASSERT_EQ(2U, s[0]->InputCount());
2194 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2195 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2196 ASSERT_EQ(1U, s[0]->OutputCount());
2197 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2200 StreamBuilder m(this, kMachInt32, kMachInt32);
2201 Node* const p0 = m.Parameter(0);
2202 Node* const r = m.Word32And(m.Int32Constant(0xffff), p0);
2204 Stream s = m.Build();
2205 ASSERT_EQ(1U, s.size());
2206 EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
2207 ASSERT_EQ(2U, s[0]->InputCount());
2208 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2209 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2210 ASSERT_EQ(1U, s[0]->OutputCount());
2211 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2216 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
2218 StreamBuilder m(this, kMachInt32, kMachInt32);
2219 Node* const p0 = m.Parameter(0);
2221 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
2223 Stream s = m.Build();
2224 ASSERT_EQ(1U, s.size());
2225 EXPECT_EQ(kArmSxtb, s[0]->arch_opcode());
2226 ASSERT_EQ(2U, s[0]->InputCount());
2227 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2228 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2229 ASSERT_EQ(1U, s[0]->OutputCount());
2230 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2233 StreamBuilder m(this, kMachInt32, kMachInt32);
2234 Node* const p0 = m.Parameter(0);
2236 m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
2238 Stream s = m.Build();
2239 ASSERT_EQ(1U, s.size());
2240 EXPECT_EQ(kArmSxth, s[0]->arch_opcode());
2241 ASSERT_EQ(2U, s[0]->InputCount());
2242 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2243 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
2244 ASSERT_EQ(1U, s[0]->OutputCount());
2245 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
2250 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
2251 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2252 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2253 uint32_t max = 1 << lsb;
2254 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
2255 uint32_t jnk = rng()->NextInt(max);
2256 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2257 StreamBuilder m(this, kMachInt32, kMachInt32);
2258 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
2259 m.Int32Constant(lsb)));
2260 Stream s = m.Build(ARMv7);
2261 ASSERT_EQ(1U, s.size());
2262 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2263 ASSERT_EQ(3U, s[0]->InputCount());
2264 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2265 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2268 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2269 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2270 uint32_t max = 1 << lsb;
2271 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
2272 uint32_t jnk = rng()->NextInt(max);
2273 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2274 StreamBuilder m(this, kMachInt32, kMachInt32);
2275 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
2276 m.Int32Constant(lsb)));
2277 Stream s = m.Build(ARMv7);
2278 ASSERT_EQ(1U, s.size());
2279 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2280 ASSERT_EQ(3U, s[0]->InputCount());
2281 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2282 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2288 TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
2290 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2291 m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
2292 Stream s = m.Build();
2293 ASSERT_EQ(1U, s.size());
2294 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
2295 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2296 EXPECT_EQ(2U, s[0]->InputCount());
2297 EXPECT_EQ(1U, s[0]->OutputCount());
2300 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2301 m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
2302 Stream s = m.Build();
2303 ASSERT_EQ(1U, s.size());
2304 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
2305 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2306 EXPECT_EQ(2U, s[0]->InputCount());
2307 EXPECT_EQ(1U, s[0]->OutputCount());
2312 TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
2313 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
2314 m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
2315 Stream s = m.Build();
2316 ASSERT_EQ(1U, s.size());
2317 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2318 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2319 EXPECT_EQ(2U, s[0]->InputCount());
2320 EXPECT_EQ(1U, s[0]->OutputCount());
2321 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2322 EXPECT_EQ(kEqual, s[0]->flags_condition());
2326 TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
2327 TRACED_FOREACH(int32_t, imm, kImmediates) {
2328 if (imm == 0) continue;
2329 StreamBuilder m(this, kMachInt32, kMachInt32);
2330 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
2331 Stream s = m.Build();
2332 ASSERT_EQ(1U, s.size());
2333 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2334 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
2335 ASSERT_EQ(2U, s[0]->InputCount());
2336 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
2337 EXPECT_EQ(1U, s[0]->OutputCount());
2338 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2339 EXPECT_EQ(kEqual, s[0]->flags_condition());
2341 TRACED_FOREACH(int32_t, imm, kImmediates) {
2342 if (imm == 0) continue;
2343 StreamBuilder m(this, kMachInt32, kMachInt32);
2344 m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
2345 Stream s = m.Build();
2346 ASSERT_EQ(1U, s.size());
2347 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
2348 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
2349 ASSERT_EQ(2U, s[0]->InputCount());
2350 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
2351 EXPECT_EQ(1U, s[0]->OutputCount());
2352 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2353 EXPECT_EQ(kEqual, s[0]->flags_condition());
2358 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
2360 StreamBuilder m(this, kMachInt32, kMachInt32);
2361 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
2362 Stream s = m.Build();
2363 ASSERT_EQ(1U, s.size());
2364 EXPECT_EQ(kArmTst, s[0]->arch_opcode());
2365 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2366 ASSERT_EQ(2U, s[0]->InputCount());
2367 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2368 EXPECT_EQ(1U, s[0]->OutputCount());
2369 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2370 EXPECT_EQ(kEqual, s[0]->flags_condition());
2373 StreamBuilder m(this, kMachInt32, kMachInt32);
2374 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
2375 Stream s = m.Build();
2376 ASSERT_EQ(1U, s.size());
2377 EXPECT_EQ(kArmTst, s[0]->arch_opcode());
2378 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2379 ASSERT_EQ(2U, s[0]->InputCount());
2380 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2381 EXPECT_EQ(1U, s[0]->OutputCount());
2382 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2383 EXPECT_EQ(kEqual, s[0]->flags_condition());
2388 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
2389 StreamBuilder m(this, kMachInt32, kMachInt32);
2390 m.Return(m.Word32Not(m.Parameter(0)));
2391 Stream s = m.Build();
2392 ASSERT_EQ(1U, s.size());
2393 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
2394 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
2395 EXPECT_EQ(1U, s[0]->InputCount());
2396 EXPECT_EQ(1U, s[0]->OutputCount());
2400 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
2401 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2402 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2403 StreamBuilder m(this, kMachInt32, kMachInt32);
2404 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
2405 m.Int32Constant(0xffffffffu >> (32 - width))));
2406 Stream s = m.Build(ARMv7);
2407 ASSERT_EQ(1U, s.size());
2408 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2409 ASSERT_EQ(3U, s[0]->InputCount());
2410 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2411 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2414 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
2415 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2416 StreamBuilder m(this, kMachInt32, kMachInt32);
2417 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
2418 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
2419 Stream s = m.Build(ARMv7);
2420 ASSERT_EQ(1U, s.size());
2421 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
2422 ASSERT_EQ(3U, s[0]->InputCount());
2423 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2424 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2429 } // namespace compiler
2430 } // namespace internal