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

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

Issue 469743002: [turbofan] Refactor the InstructionSelector tests. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ARM64 Created 6 years, 4 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
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "test/compiler-unittests/instruction-selector-unittest.h" 5 #include "test/compiler-unittests/instruction-selector-unittest.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace compiler { 9 namespace compiler {
10 10
11 class InstructionSelectorARMTest : public InstructionSelectorTest {}; 11 namespace {
12 12
13 13 typedef RawMachineAssembler::Label MLabel;
14 TARGET_TEST_F(InstructionSelectorARMTest, Int32AddP) { 14 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
15 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32); 15
16 m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1))); 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, kMachineWord32, kMachineWord32, kMachineWord32);
127 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
17 Stream s = m.Build(); 128 Stream s = m.Build();
18 ASSERT_EQ(1U, s.size()); 129 ASSERT_EQ(1U, s.size());
19 EXPECT_EQ(kArmAdd, s[0]->arch_opcode()); 130 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
20 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); 131 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
21 EXPECT_EQ(2U, s[0]->InputCount()); 132 EXPECT_EQ(2U, s[0]->InputCount());
22 EXPECT_EQ(1U, s[0]->OutputCount()); 133 EXPECT_EQ(1U, s[0]->OutputCount());
23 } 134 }
24 135
136
137 TEST_P(InstructionSelectorDPITest, Immediate) {
138 const DPI dpi = GetParam();
139 TRACED_FOREACH(int32_t, imm, kImmediates) {
140 StreamBuilder m(this, kMachineWord32, kMachineWord32);
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, kMachineWord32, kMachineWord32);
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, kMachineWord32, kMachineWord32, kMachineWord32,
168 kMachineWord32);
169 m.Return((m.*dpi.constructor)(
170 m.Parameter(0),
171 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
172 Stream s = m.Build();
173 ASSERT_EQ(1U, s.size());
174 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
175 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
176 EXPECT_EQ(3U, s[0]->InputCount());
177 EXPECT_EQ(1U, s[0]->OutputCount());
178 }
179 TRACED_FOREACH(Shift, shift, kShifts) {
180 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
181 kMachineWord32);
182 m.Return((m.*dpi.constructor)(
183 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
184 m.Parameter(2)));
185 Stream s = m.Build();
186 ASSERT_EQ(1U, s.size());
187 EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
188 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
189 EXPECT_EQ(3U, s[0]->InputCount());
190 EXPECT_EQ(1U, s[0]->OutputCount());
191 }
192 }
193
194
195 TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
196 const DPI dpi = GetParam();
197 TRACED_FOREACH(Shift, shift, kShifts) {
198 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
199 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
200 m.Return((m.*dpi.constructor)(
201 m.Parameter(0),
202 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
203 Stream s = m.Build();
204 ASSERT_EQ(1U, s.size());
205 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
206 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
207 ASSERT_EQ(3U, s[0]->InputCount());
208 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
209 EXPECT_EQ(1U, s[0]->OutputCount());
210 }
211 }
212 TRACED_FOREACH(Shift, shift, kShifts) {
213 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
214 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
215 m.Return((m.*dpi.constructor)(
216 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
217 m.Parameter(1)));
218 Stream s = m.Build();
219 ASSERT_EQ(1U, s.size());
220 EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
221 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
222 ASSERT_EQ(3U, s[0]->InputCount());
223 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
224 EXPECT_EQ(1U, s[0]->OutputCount());
225 }
226 }
227 }
228
229
230 TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
231 const DPI dpi = GetParam();
232 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
233 MLabel a, b;
234 m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
235 m.Bind(&a);
236 m.Return(m.Int32Constant(1));
237 m.Bind(&b);
238 m.Return(m.Int32Constant(0));
239 Stream s = m.Build();
240 ASSERT_EQ(1U, s.size());
241 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
242 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
243 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
244 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
245 }
246
247
248 TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
249 const DPI dpi = GetParam();
250 TRACED_FOREACH(int32_t, imm, kImmediates) {
251 StreamBuilder m(this, kMachineWord32, kMachineWord32);
252 MLabel a, b;
253 m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
254 &b);
255 m.Bind(&a);
256 m.Return(m.Int32Constant(1));
257 m.Bind(&b);
258 m.Return(m.Int32Constant(0));
259 Stream s = m.Build();
260 ASSERT_EQ(1U, s.size());
261 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
262 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
263 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
264 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
265 }
266 TRACED_FOREACH(int32_t, imm, kImmediates) {
267 StreamBuilder m(this, kMachineWord32, kMachineWord32);
268 MLabel a, b;
269 m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
270 &b);
271 m.Bind(&a);
272 m.Return(m.Int32Constant(1));
273 m.Bind(&b);
274 m.Return(m.Int32Constant(0));
275 Stream s = m.Build();
276 ASSERT_EQ(1U, s.size());
277 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
278 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
279 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
280 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
281 }
282 }
283
284
285 TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
286 const DPI dpi = GetParam();
287 TRACED_FOREACH(Shift, shift, kShifts) {
288 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
289 kMachineWord32);
290 MLabel a, b;
291 m.Branch((m.*dpi.constructor)(
292 m.Parameter(0),
293 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
294 &a, &b);
295 m.Bind(&a);
296 m.Return(m.Int32Constant(1));
297 m.Bind(&b);
298 m.Return(m.Int32Constant(0));
299 Stream s = m.Build();
300 ASSERT_EQ(1U, s.size());
301 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
302 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
303 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
304 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
305 }
306 TRACED_FOREACH(Shift, shift, kShifts) {
307 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
308 kMachineWord32);
309 MLabel a, b;
310 m.Branch((m.*dpi.constructor)(
311 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
312 m.Parameter(2)),
313 &a, &b);
314 m.Bind(&a);
315 m.Return(m.Int32Constant(1));
316 m.Bind(&b);
317 m.Return(m.Int32Constant(0));
318 Stream s = m.Build();
319 ASSERT_EQ(1U, s.size());
320 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
321 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
322 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
323 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
324 }
325 }
326
327
328 TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
329 const DPI dpi = GetParam();
330 TRACED_FOREACH(Shift, shift, kShifts) {
331 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
332 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
333 MLabel a, b;
334 m.Branch((m.*dpi.constructor)(m.Parameter(0),
335 (m.*shift.constructor)(
336 m.Parameter(1), m.Int32Constant(imm))),
337 &a, &b);
338 m.Bind(&a);
339 m.Return(m.Int32Constant(1));
340 m.Bind(&b);
341 m.Return(m.Int32Constant(0));
342 Stream s = m.Build();
343 ASSERT_EQ(1U, s.size());
344 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
345 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
346 ASSERT_EQ(5U, s[0]->InputCount());
347 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
348 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
349 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
350 }
351 }
352 TRACED_FOREACH(Shift, shift, kShifts) {
353 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
354 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
355 MLabel a, b;
356 m.Branch((m.*dpi.constructor)(
357 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
358 m.Parameter(1)),
359 &a, &b);
360 m.Bind(&a);
361 m.Return(m.Int32Constant(1));
362 m.Bind(&b);
363 m.Return(m.Int32Constant(0));
364 Stream s = m.Build();
365 ASSERT_EQ(1U, s.size());
366 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
367 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
368 ASSERT_EQ(5U, s[0]->InputCount());
369 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
370 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
371 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
372 }
373 }
374 }
375
376
377 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
378 const DPI dpi = GetParam();
379 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
380 MLabel a, b;
381 m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
382 m.Int32Constant(0)),
383 &a, &b);
384 m.Bind(&a);
385 m.Return(m.Int32Constant(1));
386 m.Bind(&b);
387 m.Return(m.Int32Constant(0));
388 Stream s = m.Build();
389 ASSERT_EQ(1U, s.size());
390 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
391 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
392 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
393 EXPECT_EQ(kEqual, s[0]->flags_condition());
394 }
395
396
397 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
398 const DPI dpi = GetParam();
399 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
400 MLabel a, b;
401 m.Branch(
402 m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
403 m.Int32Constant(0)),
404 &a, &b);
405 m.Bind(&a);
406 m.Return(m.Int32Constant(1));
407 m.Bind(&b);
408 m.Return(m.Int32Constant(0));
409 Stream s = m.Build();
410 ASSERT_EQ(1U, s.size());
411 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
412 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
413 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
414 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
415 }
416
417
418 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
419 const DPI dpi = GetParam();
420 TRACED_FOREACH(int32_t, imm, kImmediates) {
421 StreamBuilder m(this, kMachineWord32, kMachineWord32);
422 MLabel a, b;
423 m.Branch(m.Word32Equal(
424 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
425 m.Int32Constant(0)),
426 &a, &b);
427 m.Bind(&a);
428 m.Return(m.Int32Constant(1));
429 m.Bind(&b);
430 m.Return(m.Int32Constant(0));
431 Stream s = m.Build();
432 ASSERT_EQ(1U, s.size());
433 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
434 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
435 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
436 EXPECT_EQ(kEqual, s[0]->flags_condition());
437 }
438 TRACED_FOREACH(int32_t, imm, kImmediates) {
439 StreamBuilder m(this, kMachineWord32, kMachineWord32);
440 MLabel a, b;
441 m.Branch(m.Word32Equal(
442 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
443 m.Int32Constant(0)),
444 &a, &b);
445 m.Bind(&a);
446 m.Return(m.Int32Constant(1));
447 m.Bind(&b);
448 m.Return(m.Int32Constant(0));
449 Stream s = m.Build();
450 ASSERT_EQ(1U, s.size());
451 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
452 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
453 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
454 EXPECT_EQ(kEqual, s[0]->flags_condition());
455 }
456 }
457
458
459 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
460 const DPI dpi = GetParam();
461 TRACED_FOREACH(int32_t, imm, kImmediates) {
462 StreamBuilder m(this, kMachineWord32, kMachineWord32);
463 MLabel a, b;
464 m.Branch(m.Word32NotEqual(
465 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
466 m.Int32Constant(0)),
467 &a, &b);
468 m.Bind(&a);
469 m.Return(m.Int32Constant(1));
470 m.Bind(&b);
471 m.Return(m.Int32Constant(0));
472 Stream s = m.Build();
473 ASSERT_EQ(1U, s.size());
474 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
475 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
476 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
477 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
478 }
479 TRACED_FOREACH(int32_t, imm, kImmediates) {
480 StreamBuilder m(this, kMachineWord32, kMachineWord32);
481 MLabel a, b;
482 m.Branch(m.Word32NotEqual(
483 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
484 m.Int32Constant(0)),
485 &a, &b);
486 m.Bind(&a);
487 m.Return(m.Int32Constant(1));
488 m.Bind(&b);
489 m.Return(m.Int32Constant(0));
490 Stream s = m.Build();
491 ASSERT_EQ(1U, s.size());
492 EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
493 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
494 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
495 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
496 }
497 }
498
499
500 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
501 ::testing::ValuesIn(kDPIs));
502
503
504 // -----------------------------------------------------------------------------
505 // Data processing instructions with overflow.
506
507
508 typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
509
510
511 TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
512 const ODPI odpi = GetParam();
513 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
514 m.Return(
515 m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
516 Stream s = m.Build();
517 ASSERT_EQ(1U, s.size());
518 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
519 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
520 EXPECT_EQ(2U, s[0]->InputCount());
521 EXPECT_LE(1U, s[0]->OutputCount());
522 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
523 EXPECT_EQ(kOverflow, s[0]->flags_condition());
524 }
525
526
527 TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
528 const ODPI odpi = GetParam();
529 TRACED_FOREACH(int32_t, imm, kImmediates) {
530 StreamBuilder m(this, kMachineWord32, kMachineWord32);
531 m.Return(m.Projection(
532 1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
533 Stream s = m.Build();
534 ASSERT_EQ(1U, s.size());
535 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
536 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
537 ASSERT_EQ(2U, s[0]->InputCount());
538 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
539 EXPECT_LE(1U, s[0]->OutputCount());
540 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
541 EXPECT_EQ(kOverflow, s[0]->flags_condition());
542 }
543 TRACED_FOREACH(int32_t, imm, kImmediates) {
544 StreamBuilder m(this, kMachineWord32, kMachineWord32);
545 m.Return(m.Projection(
546 1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
547 Stream s = m.Build();
548 ASSERT_EQ(1U, s.size());
549 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
550 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
551 ASSERT_EQ(2U, s[0]->InputCount());
552 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
553 EXPECT_LE(1U, s[0]->OutputCount());
554 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
555 EXPECT_EQ(kOverflow, s[0]->flags_condition());
556 }
557 }
558
559
560 TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
561 const ODPI odpi = GetParam();
562 TRACED_FOREACH(Shift, shift, kShifts) {
563 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
564 kMachineWord32);
565 m.Return(m.Projection(
566 1, (m.*odpi.constructor)(
567 m.Parameter(0),
568 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
569 Stream s = m.Build();
570 ASSERT_EQ(1U, s.size());
571 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
572 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
573 EXPECT_EQ(3U, s[0]->InputCount());
574 EXPECT_LE(1U, s[0]->OutputCount());
575 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
576 EXPECT_EQ(kOverflow, s[0]->flags_condition());
577 }
578 TRACED_FOREACH(Shift, shift, kShifts) {
579 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
580 kMachineWord32);
581 m.Return(m.Projection(
582 1, (m.*odpi.constructor)(
583 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
584 m.Parameter(0))));
585 Stream s = m.Build();
586 ASSERT_EQ(1U, s.size());
587 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
588 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
589 EXPECT_EQ(3U, s[0]->InputCount());
590 EXPECT_LE(1U, s[0]->OutputCount());
591 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
592 EXPECT_EQ(kOverflow, s[0]->flags_condition());
593 }
594 }
595
596
597 TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
598 const ODPI odpi = GetParam();
599 TRACED_FOREACH(Shift, shift, kShifts) {
600 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
601 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
602 m.Return(m.Projection(
603 1, (m.*odpi.constructor)(m.Parameter(0),
604 (m.*shift.constructor)(
605 m.Parameter(1), m.Int32Constant(imm)))));
606 Stream s = m.Build();
607 ASSERT_EQ(1U, s.size());
608 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
609 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
610 ASSERT_EQ(3U, s[0]->InputCount());
611 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
612 EXPECT_LE(1U, s[0]->OutputCount());
613 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
614 EXPECT_EQ(kOverflow, s[0]->flags_condition());
615 }
616 }
617 TRACED_FOREACH(Shift, shift, kShifts) {
618 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
619 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
620 m.Return(m.Projection(
621 1, (m.*odpi.constructor)(
622 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
623 m.Parameter(0))));
624 Stream s = m.Build();
625 ASSERT_EQ(1U, s.size());
626 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
627 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
628 ASSERT_EQ(3U, s[0]->InputCount());
629 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
630 EXPECT_LE(1U, s[0]->OutputCount());
631 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
632 EXPECT_EQ(kOverflow, s[0]->flags_condition());
633 }
634 }
635 }
636
637
638 TEST_P(InstructionSelectorODPITest, ValWithParameters) {
639 const ODPI odpi = GetParam();
640 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
641 m.Return(
642 m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
643 Stream s = m.Build();
644 ASSERT_EQ(1U, s.size());
645 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
646 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
647 EXPECT_EQ(2U, s[0]->InputCount());
648 EXPECT_LE(1U, s[0]->OutputCount());
649 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
650 }
651
652
653 TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
654 const ODPI odpi = GetParam();
655 TRACED_FOREACH(int32_t, imm, kImmediates) {
656 StreamBuilder m(this, kMachineWord32, kMachineWord32);
657 m.Return(m.Projection(
658 0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
659 Stream s = m.Build();
660 ASSERT_EQ(1U, s.size());
661 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
662 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
663 ASSERT_EQ(2U, s[0]->InputCount());
664 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
665 EXPECT_LE(1U, s[0]->OutputCount());
666 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
667 }
668 TRACED_FOREACH(int32_t, imm, kImmediates) {
669 StreamBuilder m(this, kMachineWord32, kMachineWord32);
670 m.Return(m.Projection(
671 0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
672 Stream s = m.Build();
673 ASSERT_EQ(1U, s.size());
674 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
675 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
676 ASSERT_EQ(2U, s[0]->InputCount());
677 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
678 EXPECT_LE(1U, s[0]->OutputCount());
679 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
680 }
681 }
682
683
684 TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
685 const ODPI odpi = GetParam();
686 TRACED_FOREACH(Shift, shift, kShifts) {
687 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
688 kMachineWord32);
689 m.Return(m.Projection(
690 0, (m.*odpi.constructor)(
691 m.Parameter(0),
692 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
693 Stream s = m.Build();
694 ASSERT_EQ(1U, s.size());
695 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
696 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
697 EXPECT_EQ(3U, s[0]->InputCount());
698 EXPECT_LE(1U, s[0]->OutputCount());
699 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
700 }
701 TRACED_FOREACH(Shift, shift, kShifts) {
702 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
703 kMachineWord32);
704 m.Return(m.Projection(
705 0, (m.*odpi.constructor)(
706 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
707 m.Parameter(0))));
708 Stream s = m.Build();
709 ASSERT_EQ(1U, s.size());
710 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
711 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
712 EXPECT_EQ(3U, s[0]->InputCount());
713 EXPECT_LE(1U, s[0]->OutputCount());
714 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
715 }
716 }
717
718
719 TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
720 const ODPI odpi = GetParam();
721 TRACED_FOREACH(Shift, shift, kShifts) {
722 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
723 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
724 m.Return(m.Projection(
725 0, (m.*odpi.constructor)(m.Parameter(0),
726 (m.*shift.constructor)(
727 m.Parameter(1), m.Int32Constant(imm)))));
728 Stream s = m.Build();
729 ASSERT_EQ(1U, s.size());
730 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
731 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
732 ASSERT_EQ(3U, s[0]->InputCount());
733 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
734 EXPECT_LE(1U, s[0]->OutputCount());
735 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
736 }
737 }
738 TRACED_FOREACH(Shift, shift, kShifts) {
739 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
740 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
741 m.Return(m.Projection(
742 0, (m.*odpi.constructor)(
743 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
744 m.Parameter(0))));
745 Stream s = m.Build();
746 ASSERT_EQ(1U, s.size());
747 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
748 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
749 ASSERT_EQ(3U, s[0]->InputCount());
750 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
751 EXPECT_LE(1U, s[0]->OutputCount());
752 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
753 }
754 }
755 }
756
757
758 TEST_P(InstructionSelectorODPITest, BothWithParameters) {
759 const ODPI odpi = GetParam();
760 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
761 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
762 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
763 Stream s = m.Build();
764 ASSERT_LE(1U, s.size());
765 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
766 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
767 EXPECT_EQ(2U, s[0]->InputCount());
768 EXPECT_EQ(2U, s[0]->OutputCount());
769 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
770 EXPECT_EQ(kOverflow, s[0]->flags_condition());
771 }
772
773
774 TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
775 const ODPI odpi = GetParam();
776 TRACED_FOREACH(int32_t, imm, kImmediates) {
777 StreamBuilder m(this, kMachineWord32, kMachineWord32);
778 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
779 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
780 Stream s = m.Build();
781 ASSERT_LE(1U, s.size());
782 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
783 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
784 ASSERT_EQ(2U, s[0]->InputCount());
785 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
786 EXPECT_EQ(2U, s[0]->OutputCount());
787 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
788 EXPECT_EQ(kOverflow, s[0]->flags_condition());
789 }
790 TRACED_FOREACH(int32_t, imm, kImmediates) {
791 StreamBuilder m(this, kMachineWord32, kMachineWord32);
792 Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
793 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
794 Stream s = m.Build();
795 ASSERT_LE(1U, s.size());
796 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
797 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
798 ASSERT_EQ(2U, s[0]->InputCount());
799 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
800 EXPECT_EQ(2U, s[0]->OutputCount());
801 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
802 EXPECT_EQ(kOverflow, s[0]->flags_condition());
803 }
804 }
805
806
807 TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
808 const ODPI odpi = GetParam();
809 TRACED_FOREACH(Shift, shift, kShifts) {
810 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
811 kMachineWord32);
812 Node* n = (m.*odpi.constructor)(
813 m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
814 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
815 Stream s = m.Build();
816 ASSERT_LE(1U, s.size());
817 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
818 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
819 EXPECT_EQ(3U, s[0]->InputCount());
820 EXPECT_EQ(2U, s[0]->OutputCount());
821 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
822 EXPECT_EQ(kOverflow, s[0]->flags_condition());
823 }
824 TRACED_FOREACH(Shift, shift, kShifts) {
825 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
826 kMachineWord32);
827 Node* n = (m.*odpi.constructor)(
828 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
829 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
830 Stream s = m.Build();
831 ASSERT_LE(1U, s.size());
832 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
833 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
834 EXPECT_EQ(3U, s[0]->InputCount());
835 EXPECT_EQ(2U, s[0]->OutputCount());
836 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
837 EXPECT_EQ(kOverflow, s[0]->flags_condition());
838 }
839 }
840
841
842 TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
843 const ODPI odpi = GetParam();
844 TRACED_FOREACH(Shift, shift, kShifts) {
845 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
846 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
847 Node* n = (m.*odpi.constructor)(
848 m.Parameter(0),
849 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
850 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
851 Stream s = m.Build();
852 ASSERT_LE(1U, s.size());
853 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
854 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
855 ASSERT_EQ(3U, s[0]->InputCount());
856 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
857 EXPECT_EQ(2U, s[0]->OutputCount());
858 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
859 EXPECT_EQ(kOverflow, s[0]->flags_condition());
860 }
861 }
862 TRACED_FOREACH(Shift, shift, kShifts) {
863 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
864 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
865 Node* n = (m.*odpi.constructor)(
866 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
867 m.Parameter(1));
868 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
869 Stream s = m.Build();
870 ASSERT_LE(1U, s.size());
871 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
872 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
873 ASSERT_EQ(3U, s[0]->InputCount());
874 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
875 EXPECT_EQ(2U, s[0]->OutputCount());
876 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
877 EXPECT_EQ(kOverflow, s[0]->flags_condition());
878 }
879 }
880 }
881
882
883 TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
884 const ODPI odpi = GetParam();
885 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
886 MLabel a, b;
887 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
888 m.Branch(m.Projection(1, n), &a, &b);
889 m.Bind(&a);
890 m.Return(m.Int32Constant(0));
891 m.Bind(&b);
892 m.Return(m.Projection(0, n));
893 Stream s = m.Build();
894 ASSERT_EQ(1U, s.size());
895 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
896 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
897 EXPECT_EQ(4U, s[0]->InputCount());
898 EXPECT_EQ(1U, s[0]->OutputCount());
899 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
900 EXPECT_EQ(kOverflow, s[0]->flags_condition());
901 }
902
903
904 TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
905 const ODPI odpi = GetParam();
906 TRACED_FOREACH(int32_t, imm, kImmediates) {
907 StreamBuilder m(this, kMachineWord32, kMachineWord32);
908 MLabel a, b;
909 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
910 m.Branch(m.Projection(1, n), &a, &b);
911 m.Bind(&a);
912 m.Return(m.Int32Constant(0));
913 m.Bind(&b);
914 m.Return(m.Projection(0, n));
915 Stream s = m.Build();
916 ASSERT_EQ(1U, s.size());
917 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
918 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
919 ASSERT_EQ(4U, s[0]->InputCount());
920 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
921 EXPECT_EQ(1U, s[0]->OutputCount());
922 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
923 EXPECT_EQ(kOverflow, s[0]->flags_condition());
924 }
925 TRACED_FOREACH(int32_t, imm, kImmediates) {
926 StreamBuilder m(this, kMachineWord32, kMachineWord32);
927 MLabel a, b;
928 Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
929 m.Branch(m.Projection(1, n), &a, &b);
930 m.Bind(&a);
931 m.Return(m.Int32Constant(0));
932 m.Bind(&b);
933 m.Return(m.Projection(0, n));
934 Stream s = m.Build();
935 ASSERT_EQ(1U, s.size());
936 EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
937 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
938 ASSERT_EQ(4U, s[0]->InputCount());
939 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
940 EXPECT_EQ(1U, s[0]->OutputCount());
941 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
942 EXPECT_EQ(kOverflow, s[0]->flags_condition());
943 }
944 }
945
946
947 TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
948 const ODPI odpi = GetParam();
949 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
950 MLabel a, b;
951 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
952 m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
953 m.Bind(&a);
954 m.Return(m.Projection(0, n));
955 m.Bind(&b);
956 m.Return(m.Int32Constant(0));
957 Stream s = m.Build();
958 ASSERT_EQ(1U, s.size());
959 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
960 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
961 EXPECT_EQ(4U, s[0]->InputCount());
962 EXPECT_EQ(1U, s[0]->OutputCount());
963 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
964 EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
965 }
966
967
968 TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
969 const ODPI odpi = GetParam();
970 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
971 MLabel a, b;
972 Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
973 m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
974 m.Bind(&a);
975 m.Return(m.Projection(0, n));
976 m.Bind(&b);
977 m.Return(m.Int32Constant(0));
978 Stream s = m.Build();
979 ASSERT_EQ(1U, s.size());
980 EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
981 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
982 EXPECT_EQ(4U, s[0]->InputCount());
983 EXPECT_EQ(1U, s[0]->OutputCount());
984 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
985 EXPECT_EQ(kOverflow, s[0]->flags_condition());
986 }
987
988
989 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
990 ::testing::ValuesIn(kODPIs));
991
992
993 // -----------------------------------------------------------------------------
994 // Shifts.
995
996
997 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
998
999
1000 TEST_P(InstructionSelectorShiftTest, Parameters) {
1001 const Shift shift = GetParam();
1002 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1003 m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
1004 Stream s = m.Build();
1005 ASSERT_EQ(1U, s.size());
1006 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1007 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1008 EXPECT_EQ(2U, s[0]->InputCount());
1009 EXPECT_EQ(1U, s[0]->OutputCount());
1010 }
1011
1012
1013 TEST_P(InstructionSelectorShiftTest, Immediates) {
1014 const Shift shift = GetParam();
1015 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1016 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1017 m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
1018 Stream s = m.Build();
1019 ASSERT_EQ(1U, s.size());
1020 EXPECT_EQ(kArmMov, s[0]->arch_opcode());
1021 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1022 ASSERT_EQ(2U, s[0]->InputCount());
1023 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1024 EXPECT_EQ(1U, s[0]->OutputCount());
1025 }
1026 }
1027
1028
1029 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
1030 const Shift shift = GetParam();
1031 {
1032 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1033 kMachineWord32);
1034 m.Return(
1035 m.Word32Equal(m.Parameter(0),
1036 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
1037 Stream s = m.Build();
1038 ASSERT_EQ(1U, s.size());
1039 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1040 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1041 EXPECT_EQ(3U, s[0]->InputCount());
1042 EXPECT_EQ(1U, s[0]->OutputCount());
1043 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1044 EXPECT_EQ(kEqual, s[0]->flags_condition());
1045 }
1046 {
1047 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1048 kMachineWord32);
1049 m.Return(
1050 m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
1051 m.Parameter(0)));
1052 Stream s = m.Build();
1053 ASSERT_EQ(1U, s.size());
1054 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1055 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1056 EXPECT_EQ(3U, s[0]->InputCount());
1057 EXPECT_EQ(1U, s[0]->OutputCount());
1058 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1059 EXPECT_EQ(kEqual, s[0]->flags_condition());
1060 }
1061 }
1062
1063
1064 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
1065 const Shift shift = GetParam();
1066 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1067 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1068 m.Return(m.Word32Equal(
1069 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
1070 m.Parameter(0)));
1071 Stream s = m.Build();
1072 ASSERT_EQ(1U, s.size());
1073 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1074 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1075 ASSERT_EQ(3U, s[0]->InputCount());
1076 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1077 EXPECT_EQ(1U, s[0]->OutputCount());
1078 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1079 EXPECT_EQ(kEqual, s[0]->flags_condition());
1080 }
1081 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1082 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1083 m.Return(m.Word32Equal(
1084 m.Parameter(0),
1085 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
1086 Stream s = m.Build();
1087 ASSERT_EQ(1U, s.size());
1088 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1089 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1090 ASSERT_EQ(3U, s[0]->InputCount());
1091 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1092 EXPECT_EQ(1U, s[0]->OutputCount());
1093 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1094 EXPECT_EQ(kEqual, s[0]->flags_condition());
1095 }
1096 }
1097
1098
1099 TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
1100 const Shift shift = GetParam();
1101 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1102 m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
1103 Stream s = m.Build();
1104 ASSERT_EQ(1U, s.size());
1105 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1106 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1107 EXPECT_EQ(2U, s[0]->InputCount());
1108 EXPECT_EQ(1U, s[0]->OutputCount());
1109 }
1110
1111
1112 TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
1113 const Shift shift = GetParam();
1114 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1115 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1116 m.Return(m.Word32Not(
1117 (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
1118 Stream s = m.Build();
1119 ASSERT_EQ(1U, s.size());
1120 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1121 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1122 ASSERT_EQ(2U, s[0]->InputCount());
1123 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1124 EXPECT_EQ(1U, s[0]->OutputCount());
1125 }
1126 }
1127
1128
1129 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
1130 const Shift shift = GetParam();
1131 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1132 kMachineWord32);
1133 m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
1134 m.Parameter(1), m.Parameter(2)))));
1135 Stream s = m.Build();
1136 ASSERT_EQ(1U, s.size());
1137 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1138 EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
1139 EXPECT_EQ(3U, s[0]->InputCount());
1140 EXPECT_EQ(1U, s[0]->OutputCount());
1141 }
1142
1143
1144 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
1145 const Shift shift = GetParam();
1146 TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
1147 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1148 m.Return(m.Word32And(m.Parameter(0),
1149 m.Word32Not((m.*shift.constructor)(
1150 m.Parameter(1), m.Int32Constant(imm)))));
1151 Stream s = m.Build();
1152 ASSERT_EQ(1U, s.size());
1153 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1154 EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
1155 ASSERT_EQ(3U, s[0]->InputCount());
1156 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
1157 EXPECT_EQ(1U, s[0]->OutputCount());
1158 }
1159 }
1160
1161
1162 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
1163 ::testing::ValuesIn(kShifts));
1164
1165
1166 // -----------------------------------------------------------------------------
1167 // Miscellaneous.
1168
1169
1170 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
1171 {
1172 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1173 kMachineWord32);
1174 m.Return(
1175 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1176 Stream s = m.Build();
1177 ASSERT_EQ(1U, s.size());
1178 EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1179 EXPECT_EQ(3U, s[0]->InputCount());
1180 EXPECT_EQ(1U, s[0]->OutputCount());
1181 }
1182 {
1183 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1184 kMachineWord32);
1185 m.Return(
1186 m.Int32Add(m.Int32Mul(m.Parameter(1), m.Parameter(2)), m.Parameter(0)));
1187 Stream s = m.Build();
1188 ASSERT_EQ(1U, s.size());
1189 EXPECT_EQ(kArmMla, s[0]->arch_opcode());
1190 EXPECT_EQ(3U, s[0]->InputCount());
1191 EXPECT_EQ(1U, s[0]->OutputCount());
1192 }
1193 }
1194
1195
1196 TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
1197 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1198 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1199 Stream s = m.Build();
1200 ASSERT_EQ(4U, s.size());
1201 EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1202 ASSERT_EQ(1U, s[0]->OutputCount());
1203 EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1204 ASSERT_EQ(1U, s[1]->OutputCount());
1205 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1206 ASSERT_EQ(2U, s[2]->InputCount());
1207 ASSERT_EQ(1U, s[2]->OutputCount());
1208 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1209 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1210 EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1211 ASSERT_EQ(1U, s[3]->InputCount());
1212 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1213 }
1214
1215
1216 TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
1217 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1218 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
1219 Stream s = m.Build(SUDIV);
1220 ASSERT_EQ(1U, s.size());
1221 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1222 }
1223
1224
1225 TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
1226 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1227 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1228 Stream s = m.Build();
1229 ASSERT_EQ(6U, s.size());
1230 EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
1231 ASSERT_EQ(1U, s[0]->OutputCount());
1232 EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
1233 ASSERT_EQ(1U, s[1]->OutputCount());
1234 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1235 ASSERT_EQ(2U, s[2]->InputCount());
1236 ASSERT_EQ(1U, s[2]->OutputCount());
1237 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1238 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1239 EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
1240 ASSERT_EQ(1U, s[3]->InputCount());
1241 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1242 EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1243 ASSERT_EQ(1U, s[4]->OutputCount());
1244 ASSERT_EQ(2U, s[4]->InputCount());
1245 EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1246 EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1247 EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1248 ASSERT_EQ(1U, s[5]->OutputCount());
1249 ASSERT_EQ(2U, s[5]->InputCount());
1250 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1251 EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1252 }
1253
1254
1255 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
1256 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1257 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1258 Stream s = m.Build(SUDIV);
1259 ASSERT_EQ(3U, s.size());
1260 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1261 ASSERT_EQ(1U, s[0]->OutputCount());
1262 ASSERT_EQ(2U, s[0]->InputCount());
1263 EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1264 ASSERT_EQ(1U, s[1]->OutputCount());
1265 ASSERT_EQ(2U, s[1]->InputCount());
1266 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1267 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1268 EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1269 ASSERT_EQ(1U, s[2]->OutputCount());
1270 ASSERT_EQ(2U, s[2]->InputCount());
1271 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1272 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1273 }
1274
1275
1276 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
1277 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1278 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
1279 Stream s = m.Build(MLS, SUDIV);
1280 ASSERT_EQ(2U, s.size());
1281 EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
1282 ASSERT_EQ(1U, s[0]->OutputCount());
1283 ASSERT_EQ(2U, s[0]->InputCount());
1284 EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1285 ASSERT_EQ(1U, s[1]->OutputCount());
1286 ASSERT_EQ(3U, s[1]->InputCount());
1287 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1288 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1289 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1290 }
1291
1292
1293 TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
1294 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1295 m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
1296 Stream s = m.Build();
1297 ASSERT_EQ(1U, s.size());
1298 EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1299 EXPECT_EQ(2U, s[0]->InputCount());
1300 EXPECT_EQ(1U, s[0]->OutputCount());
1301 }
1302
1303
1304 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
1305 // x * (2^k + 1) -> x + (x >> k)
1306 TRACED_FORRANGE(int32_t, k, 1, 30) {
1307 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1308 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
1309 Stream s = m.Build();
1310 ASSERT_EQ(1U, s.size());
1311 EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1312 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1313 ASSERT_EQ(3U, s[0]->InputCount());
1314 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1315 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1316 EXPECT_EQ(1U, s[0]->OutputCount());
1317 }
1318 // x * (2^k - 1) -> -x + (x >> k)
1319 TRACED_FORRANGE(int32_t, k, 3, 30) {
1320 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1321 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
1322 Stream s = m.Build();
1323 ASSERT_EQ(1U, s.size());
1324 EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1325 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1326 ASSERT_EQ(3U, s[0]->InputCount());
1327 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1328 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1329 EXPECT_EQ(1U, s[0]->OutputCount());
1330 }
1331 // (2^k + 1) * x -> x + (x >> k)
1332 TRACED_FORRANGE(int32_t, k, 1, 30) {
1333 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1334 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
1335 Stream s = m.Build();
1336 ASSERT_EQ(1U, s.size());
1337 EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
1338 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1339 ASSERT_EQ(3U, s[0]->InputCount());
1340 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1341 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1342 EXPECT_EQ(1U, s[0]->OutputCount());
1343 }
1344 // x * (2^k - 1) -> -x + (x >> k)
1345 TRACED_FORRANGE(int32_t, k, 3, 30) {
1346 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1347 m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
1348 Stream s = m.Build();
1349 ASSERT_EQ(1U, s.size());
1350 EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
1351 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1352 ASSERT_EQ(3U, s[0]->InputCount());
1353 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1354 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1355 EXPECT_EQ(1U, s[0]->OutputCount());
1356 }
1357 }
1358
1359
1360 TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
1361 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1362 kMachineWord32);
1363 m.Return(
1364 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1365 Stream s = m.Build();
1366 ASSERT_EQ(2U, s.size());
1367 EXPECT_EQ(kArmMul, s[0]->arch_opcode());
1368 ASSERT_EQ(1U, s[0]->OutputCount());
1369 EXPECT_EQ(kArmSub, s[1]->arch_opcode());
1370 ASSERT_EQ(2U, s[1]->InputCount());
1371 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
1372 }
1373
1374
1375 TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
1376 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32,
1377 kMachineWord32);
1378 m.Return(
1379 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
1380 Stream s = m.Build(MLS);
1381 ASSERT_EQ(1U, s.size());
1382 EXPECT_EQ(kArmMls, s[0]->arch_opcode());
1383 EXPECT_EQ(1U, s[0]->OutputCount());
1384 EXPECT_EQ(3U, s[0]->InputCount());
1385 }
1386
1387
1388 TEST_F(InstructionSelectorTest, Int32UDivWithParameters) {
1389 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1390 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
1391 Stream s = m.Build();
1392 ASSERT_EQ(4U, s.size());
1393 EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
1394 ASSERT_EQ(1U, s[0]->OutputCount());
1395 EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
1396 ASSERT_EQ(1U, s[1]->OutputCount());
1397 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1398 ASSERT_EQ(2U, s[2]->InputCount());
1399 ASSERT_EQ(1U, s[2]->OutputCount());
1400 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1401 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1402 EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
1403 ASSERT_EQ(1U, s[3]->InputCount());
1404 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1405 }
1406
1407
1408 TEST_F(InstructionSelectorTest, Int32UDivWithParametersForSUDIV) {
1409 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1410 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
1411 Stream s = m.Build(SUDIV);
1412 ASSERT_EQ(1U, s.size());
1413 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1414 }
1415
1416
1417 TEST_F(InstructionSelectorTest, Int32UModWithParameters) {
1418 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1419 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1420 Stream s = m.Build();
1421 ASSERT_EQ(6U, s.size());
1422 EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
1423 ASSERT_EQ(1U, s[0]->OutputCount());
1424 EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
1425 ASSERT_EQ(1U, s[1]->OutputCount());
1426 EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
1427 ASSERT_EQ(2U, s[2]->InputCount());
1428 ASSERT_EQ(1U, s[2]->OutputCount());
1429 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
1430 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1431 EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
1432 ASSERT_EQ(1U, s[3]->InputCount());
1433 EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
1434 EXPECT_EQ(kArmMul, s[4]->arch_opcode());
1435 ASSERT_EQ(1U, s[4]->OutputCount());
1436 ASSERT_EQ(2U, s[4]->InputCount());
1437 EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
1438 EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
1439 EXPECT_EQ(kArmSub, s[5]->arch_opcode());
1440 ASSERT_EQ(1U, s[5]->OutputCount());
1441 ASSERT_EQ(2U, s[5]->InputCount());
1442 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
1443 EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
1444 }
1445
1446
1447 TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIV) {
1448 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1449 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1450 Stream s = m.Build(SUDIV);
1451 ASSERT_EQ(3U, s.size());
1452 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1453 ASSERT_EQ(1U, s[0]->OutputCount());
1454 ASSERT_EQ(2U, s[0]->InputCount());
1455 EXPECT_EQ(kArmMul, s[1]->arch_opcode());
1456 ASSERT_EQ(1U, s[1]->OutputCount());
1457 ASSERT_EQ(2U, s[1]->InputCount());
1458 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1459 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1460 EXPECT_EQ(kArmSub, s[2]->arch_opcode());
1461 ASSERT_EQ(1U, s[2]->OutputCount());
1462 ASSERT_EQ(2U, s[2]->InputCount());
1463 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
1464 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
1465 }
1466
1467
1468 TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIVAndMLS) {
1469 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1470 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
1471 Stream s = m.Build(MLS, SUDIV);
1472 ASSERT_EQ(2U, s.size());
1473 EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
1474 ASSERT_EQ(1U, s[0]->OutputCount());
1475 ASSERT_EQ(2U, s[0]->InputCount());
1476 EXPECT_EQ(kArmMls, s[1]->arch_opcode());
1477 ASSERT_EQ(1U, s[1]->OutputCount());
1478 ASSERT_EQ(3U, s[1]->InputCount());
1479 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
1480 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
1481 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
1482 }
1483
1484
1485 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
1486 TRACED_FORRANGE(int32_t, width, 1, 32) {
1487 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1488 m.Return(m.Word32And(m.Parameter(0),
1489 m.Int32Constant(0xffffffffu >> (32 - width))));
1490 Stream s = m.Build(ARMv7);
1491 ASSERT_EQ(1U, s.size());
1492 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1493 ASSERT_EQ(3U, s[0]->InputCount());
1494 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
1495 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1496 }
1497 TRACED_FORRANGE(int32_t, width, 1, 32) {
1498 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1499 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
1500 m.Parameter(0)));
1501 Stream s = m.Build(ARMv7);
1502 ASSERT_EQ(1U, s.size());
1503 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1504 ASSERT_EQ(3U, s[0]->InputCount());
1505 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
1506 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1507 }
1508 }
1509
1510
1511 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
1512 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1513 TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
1514 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1515 m.Return(m.Word32And(
1516 m.Parameter(0),
1517 m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
1518 Stream s = m.Build(ARMv7);
1519 ASSERT_EQ(1U, s.size());
1520 EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
1521 ASSERT_EQ(1U, s[0]->OutputCount());
1522 EXPECT_TRUE(
1523 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
1524 ASSERT_EQ(3U, s[0]->InputCount());
1525 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1526 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1527 }
1528 }
1529 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1530 TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
1531 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1532 m.Return(
1533 m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
1534 m.Parameter(0)));
1535 Stream s = m.Build(ARMv7);
1536 ASSERT_EQ(1U, s.size());
1537 EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
1538 ASSERT_EQ(1U, s[0]->OutputCount());
1539 EXPECT_TRUE(
1540 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
1541 ASSERT_EQ(3U, s[0]->InputCount());
1542 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1543 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1544 }
1545 }
1546 }
1547
1548
1549 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
1550 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1551 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1552 uint32_t max = 1 << lsb;
1553 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
1554 uint32_t jnk = rng()->NextInt(max);
1555 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
1556 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1557 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
1558 m.Int32Constant(lsb)));
1559 Stream s = m.Build(ARMv7);
1560 ASSERT_EQ(1U, s.size());
1561 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1562 ASSERT_EQ(3U, s[0]->InputCount());
1563 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1564 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1565 }
1566 }
1567 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1568 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1569 uint32_t max = 1 << lsb;
1570 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
1571 uint32_t jnk = rng()->NextInt(max);
1572 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
1573 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1574 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
1575 m.Int32Constant(lsb)));
1576 Stream s = m.Build(ARMv7);
1577 ASSERT_EQ(1U, s.size());
1578 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1579 ASSERT_EQ(3U, s[0]->InputCount());
1580 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1581 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1582 }
1583 }
1584 }
1585
1586
1587 TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
1588 {
1589 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1590 m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
1591 Stream s = m.Build();
1592 ASSERT_EQ(1U, s.size());
1593 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1594 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1595 EXPECT_EQ(2U, s[0]->InputCount());
1596 EXPECT_EQ(1U, s[0]->OutputCount());
1597 }
1598 {
1599 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1600 m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
1601 Stream s = m.Build();
1602 ASSERT_EQ(1U, s.size());
1603 EXPECT_EQ(kArmBic, s[0]->arch_opcode());
1604 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1605 EXPECT_EQ(2U, s[0]->InputCount());
1606 EXPECT_EQ(1U, s[0]->OutputCount());
1607 }
1608 }
1609
1610
1611 TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
1612 StreamBuilder m(this, kMachineWord32, kMachineWord32, kMachineWord32);
1613 m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
1614 Stream s = m.Build();
1615 ASSERT_EQ(1U, s.size());
1616 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1617 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1618 EXPECT_EQ(2U, s[0]->InputCount());
1619 EXPECT_EQ(1U, s[0]->OutputCount());
1620 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1621 EXPECT_EQ(kEqual, s[0]->flags_condition());
1622 }
1623
1624
1625 TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
1626 TRACED_FOREACH(int32_t, imm, kImmediates) {
1627 if (imm == 0) continue;
1628 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1629 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
1630 Stream s = m.Build();
1631 ASSERT_EQ(1U, s.size());
1632 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1633 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
1634 ASSERT_EQ(2U, s[0]->InputCount());
1635 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1636 EXPECT_EQ(1U, s[0]->OutputCount());
1637 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1638 EXPECT_EQ(kEqual, s[0]->flags_condition());
1639 }
1640 TRACED_FOREACH(int32_t, imm, kImmediates) {
1641 if (imm == 0) continue;
1642 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1643 m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
1644 Stream s = m.Build();
1645 ASSERT_EQ(1U, s.size());
1646 EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
1647 EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
1648 ASSERT_EQ(2U, s[0]->InputCount());
1649 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1650 EXPECT_EQ(1U, s[0]->OutputCount());
1651 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1652 EXPECT_EQ(kEqual, s[0]->flags_condition());
1653 }
1654 }
1655
1656
1657 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
1658 {
1659 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1660 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
1661 Stream s = m.Build();
1662 ASSERT_EQ(1U, s.size());
1663 EXPECT_EQ(kArmTst, s[0]->arch_opcode());
1664 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1665 ASSERT_EQ(2U, s[0]->InputCount());
1666 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1667 EXPECT_EQ(1U, s[0]->OutputCount());
1668 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1669 EXPECT_EQ(kEqual, s[0]->flags_condition());
1670 }
1671 {
1672 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1673 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
1674 Stream s = m.Build();
1675 ASSERT_EQ(1U, s.size());
1676 EXPECT_EQ(kArmTst, s[0]->arch_opcode());
1677 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1678 ASSERT_EQ(2U, s[0]->InputCount());
1679 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1680 EXPECT_EQ(1U, s[0]->OutputCount());
1681 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1682 EXPECT_EQ(kEqual, s[0]->flags_condition());
1683 }
1684 }
1685
1686
1687 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
1688 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1689 m.Return(m.Word32Not(m.Parameter(0)));
1690 Stream s = m.Build();
1691 ASSERT_EQ(1U, s.size());
1692 EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
1693 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
1694 EXPECT_EQ(1U, s[0]->InputCount());
1695 EXPECT_EQ(1U, s[0]->OutputCount());
1696 }
1697
1698
1699 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
1700 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1701 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1702 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1703 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
1704 m.Int32Constant(0xffffffffu >> (32 - width))));
1705 Stream s = m.Build(ARMv7);
1706 ASSERT_EQ(1U, s.size());
1707 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1708 ASSERT_EQ(3U, s[0]->InputCount());
1709 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1710 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1711 }
1712 }
1713 TRACED_FORRANGE(int32_t, lsb, 0, 31) {
1714 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
1715 StreamBuilder m(this, kMachineWord32, kMachineWord32);
1716 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
1717 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
1718 Stream s = m.Build(ARMv7);
1719 ASSERT_EQ(1U, s.size());
1720 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
1721 ASSERT_EQ(3U, s[0]->InputCount());
1722 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
1723 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
1724 }
1725 }
1726 }
1727
25 } // namespace compiler 1728 } // namespace compiler
26 } // namespace internal 1729 } // namespace internal
27 } // namespace v8 1730 } // namespace v8
OLDNEW
« no previous file with comments | « test/compiler-unittests/DEPS ('k') | test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698