Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: src/compiler/arm/instruction-selector-arm-unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698