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

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

Powered by Google App Engine
This is Rietveld 408576698