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

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

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback, rebase and "git cl format" 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
9 using namespace v8::internal;
10 using namespace v8::internal::compiler;
11
12 namespace {
13
14 typedef RawMachineAssembler::Label MLabel;
15
16 struct DPI {
17 Operator* op;
18 ArchOpcode arch_opcode;
19 ArchOpcode reverse_arch_opcode;
20 ArchOpcode test_arch_opcode;
21 };
22
23
24 // ARM data processing instructions.
25 class DPIs V8_FINAL : public std::list<DPI>, private HandleAndZoneScope {
26 public:
27 DPIs() {
28 MachineOperatorBuilder machine(main_zone());
29 DPI and_ = {machine.Word32And(), kArmAnd, kArmAnd, kArmTst};
30 push_back(and_);
31 DPI or_ = {machine.Word32Or(), kArmOrr, kArmOrr, kArmOrr};
32 push_back(or_);
33 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq};
34 push_back(xor_);
35 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn};
36 push_back(add);
37 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp};
38 push_back(sub);
39 }
40 };
41
42
43 // ARM immediates.
44 class Immediates V8_FINAL : public std::list<int32_t> {
45 public:
46 Immediates() {
47 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) {
48 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) {
49 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4));
50 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm));
51 push_back(imm);
52 }
53 }
54 }
55 };
56
57
58 struct Shift {
59 Operator* op;
60 int32_t i_low; // lowest possible immediate
61 int32_t i_high; // highest possible immediate
62 AddressingMode i_mode; // Operand2_R_<shift>_I
63 AddressingMode r_mode; // Operand2_R_<shift>_R
64 };
65
66
67 // ARM shifts.
68 class Shifts V8_FINAL : public std::list<Shift>, private HandleAndZoneScope {
69 public:
70 Shifts() {
71 MachineOperatorBuilder machine(main_zone());
72 Shift sar = {machine.Word32Sar(), 1, 32, kMode_Operand2_R_ASR_I,
73 kMode_Operand2_R_ASR_R};
74 Shift shl = {machine.Word32Shl(), 0, 31, kMode_Operand2_R_LSL_I,
75 kMode_Operand2_R_LSL_R};
76 Shift shr = {machine.Word32Shr(), 1, 32, kMode_Operand2_R_LSR_I,
77 kMode_Operand2_R_LSR_R};
78 push_back(sar);
79 push_back(shl);
80 push_back(shr);
81 }
82 };
83
84 } // namespace
85
86
87 TEST(InstructionSelectorDPIP) {
88 DPIs dpis;
89 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
90 DPI dpi = *i;
91 InstructionSelectorTester m;
92 m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)));
93 m.SelectInstructions();
94 CHECK_EQ(1, m.code.size());
95 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
96 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
97 }
98 }
99
100
101 TEST(InstructionSelectorDPIAndShiftP) {
102 DPIs dpis;
103 Shifts shifts;
104 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
105 DPI dpi = *i;
106 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
107 Shift shift = *j;
108 {
109 InstructionSelectorTester m;
110 m.Return(
111 m.NewNode(dpi.op, m.Parameter(0),
112 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))));
113 m.SelectInstructions();
114 CHECK_EQ(1, m.code.size());
115 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
116 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
117 }
118 {
119 InstructionSelectorTester m;
120 m.Return(m.NewNode(dpi.op,
121 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)),
122 m.Parameter(2)));
123 m.SelectInstructions();
124 CHECK_EQ(1, m.code.size());
125 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
126 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
127 }
128 }
129 }
130 }
131
132
133 TEST(InstructionSelectorDPIAndShiftImm) {
134 DPIs dpis;
135 Shifts shifts;
136 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
137 DPI dpi = *i;
138 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) {
139 Shift shift = *j;
140 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
141 {
142 InstructionSelectorTester m;
143 m.Return(m.NewNode(
144 dpi.op, m.Parameter(0),
145 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))));
146 m.SelectInstructions();
147 CHECK_EQ(1, m.code.size());
148 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
149 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
150 }
151 {
152 InstructionSelectorTester m;
153 m.Return(m.NewNode(
154 dpi.op, m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)),
155 m.Parameter(1)));
156 m.SelectInstructions();
157 CHECK_EQ(1, m.code.size());
158 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
159 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
160 }
161 }
162 }
163 }
164 }
165
166
167 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) {
168 {
169 InstructionSelectorTester m;
170 m.Return(m.Word32And(m.Parameter(0),
171 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1))));
172 m.SelectInstructions();
173 CHECK_EQ(1, m.code.size());
174 CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
175 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
176 }
177 {
178 InstructionSelectorTester m;
179 m.Return(m.Word32And(m.Parameter(0),
180 m.Word32Xor(m.Parameter(1), m.Int32Constant(-1))));
181 m.SelectInstructions();
182 CHECK_EQ(1, m.code.size());
183 CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
184 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
185 }
186 {
187 InstructionSelectorTester m;
188 m.Return(m.Word32And(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)),
189 m.Parameter(1)));
190 m.SelectInstructions();
191 CHECK_EQ(1, m.code.size());
192 CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
193 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
194 }
195 {
196 InstructionSelectorTester m;
197 m.Return(m.Word32And(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)),
198 m.Parameter(1)));
199 m.SelectInstructions();
200 CHECK_EQ(1, m.code.size());
201 CHECK_EQ(kArmBic, m.code[0]->arch_opcode());
202 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
203 }
204 }
205
206
207 TEST(InstructionSelectorWord32XorWithMinus1P) {
208 {
209 InstructionSelectorTester m;
210 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
211 m.SelectInstructions();
212 CHECK_EQ(1, m.code.size());
213 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
214 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
215 }
216 {
217 InstructionSelectorTester m;
218 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
219 m.SelectInstructions();
220 CHECK_EQ(1, m.code.size());
221 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode());
222 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
223 }
224 }
225
226
227 TEST(InstructionSelectorInt32MulP) {
228 InstructionSelectorTester m;
229 m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
230 m.SelectInstructions();
231 CHECK_EQ(1, m.code.size());
232 CHECK_EQ(kArmMul, m.code[0]->arch_opcode());
233 }
234
235
236 TEST(InstructionSelectorInt32MulImm) {
237 // x * (2^k + 1) -> (x >> k) + x
238 for (int k = 1; k < 31; ++k) {
239 InstructionSelectorTester m;
240 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
241 m.SelectInstructions();
242 CHECK_EQ(1, m.code.size());
243 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
244 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
245 }
246 // (2^k + 1) * x -> (x >> k) + x
247 for (int k = 1; k < 31; ++k) {
248 InstructionSelectorTester m;
249 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
250 m.SelectInstructions();
251 CHECK_EQ(1, m.code.size());
252 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode());
253 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
254 }
255 // x * (2^k - 1) -> (x >> k) - x
256 for (int k = 3; k < 31; ++k) {
257 InstructionSelectorTester m;
258 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
259 m.SelectInstructions();
260 CHECK_EQ(1, m.code.size());
261 CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
262 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
263 }
264 // (2^k - 1) * x -> (x >> k) - x
265 for (int k = 3; k < 31; ++k) {
266 InstructionSelectorTester m;
267 m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
268 m.SelectInstructions();
269 CHECK_EQ(1, m.code.size());
270 CHECK_EQ(kArmRsb, m.code[0]->arch_opcode());
271 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode());
272 }
273 }
274
275
276 // The following tests depend on the exact CPU features available, which we do
277 // only fully control in a simulator build.
278 #ifdef USE_SIMULATOR
279
280 TEST(InstructionSelectorDPIImm_ARMv7AndVFP3Disabled) {
281 i::FLAG_enable_armv7 = false;
282 i::FLAG_enable_vfp3 = false;
283 DPIs dpis;
284 Immediates immediates;
285 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
286 DPI dpi = *i;
287 for (Immediates::const_iterator j = immediates.begin();
288 j != immediates.end(); ++j) {
289 int32_t imm = *j;
290 {
291 InstructionSelectorTester m;
292 m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)));
293 m.SelectInstructions();
294 CHECK_EQ(1, m.code.size());
295 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
296 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
297 }
298 {
299 InstructionSelectorTester m;
300 m.Return(m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)));
301 m.SelectInstructions();
302 CHECK_EQ(1, m.code.size());
303 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
304 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
305 }
306 }
307 }
308 }
309
310
311 TEST(InstructionSelectorWord32AndImm_ARMv7Enabled) {
312 i::FLAG_enable_armv7 = true;
313 for (uint32_t width = 1; width <= 32; ++width) {
314 InstructionSelectorTester m;
315 m.Return(m.Word32And(m.Parameter(0),
316 m.Int32Constant(0xffffffffu >> (32 - width))));
317 m.SelectInstructions();
318 CHECK_EQ(1, m.code.size());
319 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
320 CHECK_EQ(3, m.code[0]->InputCount());
321 CHECK_EQ(0, m.ToInt32(m.code[0]->InputAt(1)));
322 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
323 }
324 for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
325 for (uint32_t width = 1; width < 32 - lsb; ++width) {
326 uint32_t msk = ~((0xffffffffu >> (32 - width)) << lsb);
327 InstructionSelectorTester m;
328 m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(msk)));
329 m.SelectInstructions();
330 CHECK_EQ(1, m.code.size());
331 CHECK_EQ(kArmBfc, m.code[0]->arch_opcode());
332 CHECK_EQ(1, m.code[0]->OutputCount());
333 CHECK(UnallocatedOperand::cast(m.code[0]->Output())
334 ->HasSameAsInputPolicy());
335 CHECK_EQ(3, m.code[0]->InputCount());
336 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
337 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
338 }
339 }
340 }
341
342
343 TEST(InstructionSelectorWord32AndAndWord32ShrImm_ARMv7Enabled) {
344 i::FLAG_enable_armv7 = true;
345 for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
346 for (uint32_t width = 1; width <= 32 - lsb; ++width) {
347 {
348 InstructionSelectorTester m;
349 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
350 m.Int32Constant(0xffffffffu >> (32 - width))));
351 m.SelectInstructions();
352 CHECK_EQ(1, m.code.size());
353 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
354 CHECK_EQ(3, m.code[0]->InputCount());
355 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
356 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
357 }
358 {
359 InstructionSelectorTester m;
360 m.Return(
361 m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
362 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
363 m.SelectInstructions();
364 CHECK_EQ(1, m.code.size());
365 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
366 CHECK_EQ(3, m.code[0]->InputCount());
367 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
368 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
369 }
370 }
371 }
372 }
373
374
375 TEST(InstructionSelectorWord32ShrAndWord32AndImm_ARMv7Enabled) {
376 i::FLAG_enable_armv7 = true;
377 for (uint32_t lsb = 0; lsb <= 31; ++lsb) {
378 for (uint32_t width = 1; width <= 32 - lsb; ++width) {
379 uint32_t max = 1 << lsb;
380 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
381 uint32_t jnk = CcTest::random_number_generator()->NextInt(max);
382 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
383 {
384 InstructionSelectorTester m;
385 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
386 m.Int32Constant(lsb)));
387 m.SelectInstructions();
388 CHECK_EQ(1, m.code.size());
389 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
390 CHECK_EQ(3, m.code[0]->InputCount());
391 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
392 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
393 }
394 {
395 InstructionSelectorTester m;
396 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
397 m.Int32Constant(lsb)));
398 m.SelectInstructions();
399 CHECK_EQ(1, m.code.size());
400 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode());
401 CHECK_EQ(3, m.code[0]->InputCount());
402 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1)));
403 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2)));
404 }
405 }
406 }
407 }
408
409
410 TEST(InstructionSelectorInt32SubAndInt32MulP_MlsEnabled) {
411 i::FLAG_enable_mls = true;
412 InstructionSelectorTester m;
413 m.Return(
414 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
415 m.SelectInstructions();
416 CHECK_EQ(1, m.code.size());
417 CHECK_EQ(kArmMls, m.code[0]->arch_opcode());
418 }
419
420
421 TEST(InstructionSelectorInt32SubAndInt32MulP_MlsDisabled) {
422 i::FLAG_enable_mls = false;
423 InstructionSelectorTester m;
424 m.Return(
425 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
426 m.SelectInstructions();
427 CHECK_EQ(2, m.code.size());
428 CHECK_EQ(kArmMul, m.code[0]->arch_opcode());
429 CHECK_EQ(1, m.code[0]->OutputCount());
430 CHECK_EQ(kArmSub, m.code[1]->arch_opcode());
431 CHECK_EQ(2, m.code[1]->InputCount());
432 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(1));
433 }
434
435
436 TEST(InstructionSelectorInt32DivP_ARMv7AndSudivEnabled) {
437 i::FLAG_enable_armv7 = true;
438 i::FLAG_enable_sudiv = true;
439 InstructionSelectorTester m;
440 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
441 m.SelectInstructions();
442 CHECK_EQ(1, m.code.size());
443 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
444 }
445
446
447 TEST(InstructionSelectorInt32DivP_SudivDisabled) {
448 i::FLAG_enable_sudiv = false;
449 InstructionSelectorTester m;
450 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
451 m.SelectInstructions();
452 CHECK_EQ(4, m.code.size());
453 CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode());
454 CHECK_EQ(1, m.code[0]->OutputCount());
455 CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode());
456 CHECK_EQ(1, m.code[1]->OutputCount());
457 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
458 CHECK_EQ(2, m.code[2]->InputCount());
459 CHECK_EQ(1, m.code[2]->OutputCount());
460 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
461 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
462 CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode());
463 CHECK_EQ(1, m.code[3]->InputCount());
464 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
465 }
466
467
468 TEST(InstructionSelectorInt32UDivP_ARMv7AndSudivEnabled) {
469 i::FLAG_enable_armv7 = true;
470 i::FLAG_enable_sudiv = true;
471 InstructionSelectorTester m;
472 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
473 m.SelectInstructions();
474 CHECK_EQ(1, m.code.size());
475 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
476 }
477
478
479 TEST(InstructionSelectorInt32UDivP_SudivDisabled) {
480 i::FLAG_enable_sudiv = false;
481 InstructionSelectorTester m;
482 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
483 m.SelectInstructions();
484 CHECK_EQ(4, m.code.size());
485 CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode());
486 CHECK_EQ(1, m.code[0]->OutputCount());
487 CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode());
488 CHECK_EQ(1, m.code[1]->OutputCount());
489 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
490 CHECK_EQ(2, m.code[2]->InputCount());
491 CHECK_EQ(1, m.code[2]->OutputCount());
492 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
493 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
494 CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode());
495 CHECK_EQ(1, m.code[3]->InputCount());
496 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
497 }
498
499
500 TEST(InstructionSelectorInt32ModP_ARMv7AndMlsAndSudivEnabled) {
501 i::FLAG_enable_armv7 = true;
502 i::FLAG_enable_mls = true;
503 i::FLAG_enable_sudiv = true;
504 InstructionSelectorTester m;
505 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
506 m.SelectInstructions();
507 CHECK_EQ(2, m.code.size());
508 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
509 CHECK_EQ(1, m.code[0]->OutputCount());
510 CHECK_EQ(2, m.code[0]->InputCount());
511 CHECK_EQ(kArmMls, m.code[1]->arch_opcode());
512 CHECK_EQ(1, m.code[1]->OutputCount());
513 CHECK_EQ(3, m.code[1]->InputCount());
514 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
515 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
516 CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2));
517 }
518
519
520 TEST(InstructionSelectorInt32ModP_ARMv7AndSudivEnabled) {
521 i::FLAG_enable_armv7 = true;
522 i::FLAG_enable_mls = false;
523 i::FLAG_enable_sudiv = true;
524 InstructionSelectorTester m;
525 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
526 m.SelectInstructions();
527 CHECK_EQ(3, m.code.size());
528 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode());
529 CHECK_EQ(1, m.code[0]->OutputCount());
530 CHECK_EQ(2, m.code[0]->InputCount());
531 CHECK_EQ(kArmMul, m.code[1]->arch_opcode());
532 CHECK_EQ(1, m.code[1]->OutputCount());
533 CHECK_EQ(2, m.code[1]->InputCount());
534 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
535 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
536 CHECK_EQ(kArmSub, m.code[2]->arch_opcode());
537 CHECK_EQ(1, m.code[2]->OutputCount());
538 CHECK_EQ(2, m.code[2]->InputCount());
539 CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0));
540 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
541 }
542
543
544 TEST(InstructionSelectorInt32ModP_ARMv7AndMlsAndSudivDisabled) {
545 i::FLAG_enable_armv7 = false;
546 i::FLAG_enable_mls = false;
547 i::FLAG_enable_sudiv = false;
548 InstructionSelectorTester m;
549 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
550 m.SelectInstructions();
551 CHECK_EQ(6, m.code.size());
552 CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode());
553 CHECK_EQ(1, m.code[0]->OutputCount());
554 CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode());
555 CHECK_EQ(1, m.code[1]->OutputCount());
556 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
557 CHECK_EQ(2, m.code[2]->InputCount());
558 CHECK_EQ(1, m.code[2]->OutputCount());
559 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
560 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
561 CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode());
562 CHECK_EQ(1, m.code[3]->InputCount());
563 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
564 CHECK_EQ(kArmMul, m.code[4]->arch_opcode());
565 CHECK_EQ(1, m.code[4]->OutputCount());
566 CHECK_EQ(2, m.code[4]->InputCount());
567 CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0));
568 CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1));
569 CHECK_EQ(kArmSub, m.code[5]->arch_opcode());
570 CHECK_EQ(1, m.code[5]->OutputCount());
571 CHECK_EQ(2, m.code[5]->InputCount());
572 CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0));
573 CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1));
574 }
575
576
577 TEST(InstructionSelectorInt32UModP_ARMv7AndMlsAndSudivEnabled) {
578 i::FLAG_enable_armv7 = true;
579 i::FLAG_enable_mls = true;
580 i::FLAG_enable_sudiv = true;
581 InstructionSelectorTester m;
582 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
583 m.SelectInstructions();
584 CHECK_EQ(2, m.code.size());
585 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
586 CHECK_EQ(1, m.code[0]->OutputCount());
587 CHECK_EQ(2, m.code[0]->InputCount());
588 CHECK_EQ(kArmMls, m.code[1]->arch_opcode());
589 CHECK_EQ(1, m.code[1]->OutputCount());
590 CHECK_EQ(3, m.code[1]->InputCount());
591 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
592 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
593 CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2));
594 }
595
596
597 TEST(InstructionSelectorInt32UModP_ARMv7AndSudivEnabled) {
598 i::FLAG_enable_armv7 = true;
599 i::FLAG_enable_mls = false;
600 i::FLAG_enable_sudiv = true;
601 InstructionSelectorTester m;
602 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
603 m.SelectInstructions();
604 CHECK_EQ(3, m.code.size());
605 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode());
606 CHECK_EQ(1, m.code[0]->OutputCount());
607 CHECK_EQ(2, m.code[0]->InputCount());
608 CHECK_EQ(kArmMul, m.code[1]->arch_opcode());
609 CHECK_EQ(1, m.code[1]->OutputCount());
610 CHECK_EQ(2, m.code[1]->InputCount());
611 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0));
612 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1));
613 CHECK_EQ(kArmSub, m.code[2]->arch_opcode());
614 CHECK_EQ(1, m.code[2]->OutputCount());
615 CHECK_EQ(2, m.code[2]->InputCount());
616 CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0));
617 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
618 }
619
620
621 TEST(InstructionSelectorInt32UModP_ARMv7AndMlsAndSudivDisabled) {
622 i::FLAG_enable_armv7 = false;
623 i::FLAG_enable_mls = false;
624 i::FLAG_enable_sudiv = false;
625 InstructionSelectorTester m;
626 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
627 m.SelectInstructions();
628 CHECK_EQ(6, m.code.size());
629 CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode());
630 CHECK_EQ(1, m.code[0]->OutputCount());
631 CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode());
632 CHECK_EQ(1, m.code[1]->OutputCount());
633 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode());
634 CHECK_EQ(2, m.code[2]->InputCount());
635 CHECK_EQ(1, m.code[2]->OutputCount());
636 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0));
637 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1));
638 CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode());
639 CHECK_EQ(1, m.code[3]->InputCount());
640 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0));
641 CHECK_EQ(kArmMul, m.code[4]->arch_opcode());
642 CHECK_EQ(1, m.code[4]->OutputCount());
643 CHECK_EQ(2, m.code[4]->InputCount());
644 CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0));
645 CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1));
646 CHECK_EQ(kArmSub, m.code[5]->arch_opcode());
647 CHECK_EQ(1, m.code[5]->OutputCount());
648 CHECK_EQ(2, m.code[5]->InputCount());
649 CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0));
650 CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1));
651 }
652
653 #endif // USE_SIMULATOR
654
655
656 TEST(InstructionSelectorWord32EqualP) {
657 InstructionSelectorTester m;
658 m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
659 m.SelectInstructions();
660 CHECK_EQ(1, m.code.size());
661 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
662 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
663 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
664 CHECK_EQ(kEqual, m.code[0]->flags_condition());
665 }
666
667
668 TEST(InstructionSelectorWord32EqualImm) {
669 Immediates immediates;
670 for (Immediates::const_iterator i = immediates.begin(); i != immediates.end();
671 ++i) {
672 int32_t imm = *i;
673 {
674 InstructionSelectorTester m;
675 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
676 m.SelectInstructions();
677 CHECK_EQ(1, m.code.size());
678 if (imm == 0) {
679 CHECK_EQ(kArmTst, m.code[0]->arch_opcode());
680 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
681 CHECK_EQ(2, m.code[0]->InputCount());
682 CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1));
683 } else {
684 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
685 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
686 }
687 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
688 CHECK_EQ(kEqual, m.code[0]->flags_condition());
689 }
690 {
691 InstructionSelectorTester m;
692 m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
693 m.SelectInstructions();
694 CHECK_EQ(1, m.code.size());
695 if (imm == 0) {
696 CHECK_EQ(kArmTst, m.code[0]->arch_opcode());
697 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
698 CHECK_EQ(2, m.code[0]->InputCount());
699 CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1));
700 } else {
701 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
702 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
703 }
704 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
705 CHECK_EQ(kEqual, m.code[0]->flags_condition());
706 }
707 }
708 }
709
710
711 TEST(InstructionSelectorWord32EqualAndDPIP) {
712 DPIs dpis;
713 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
714 DPI dpi = *i;
715 {
716 InstructionSelectorTester m;
717 m.Return(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)),
718 m.Int32Constant(0)));
719 m.SelectInstructions();
720 CHECK_EQ(1, m.code.size());
721 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
722 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
723 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
724 CHECK_EQ(kEqual, m.code[0]->flags_condition());
725 }
726 {
727 InstructionSelectorTester m;
728 m.Return(
729 m.Word32Equal(m.Int32Constant(0),
730 m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))));
731 m.SelectInstructions();
732 CHECK_EQ(1, m.code.size());
733 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
734 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
735 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
736 CHECK_EQ(kEqual, m.code[0]->flags_condition());
737 }
738 }
739 }
740
741
742 TEST(InstructionSelectorWord32EqualAndDPIImm) {
743 DPIs dpis;
744 Immediates immediates;
745 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
746 DPI dpi = *i;
747 for (Immediates::const_iterator j = immediates.begin();
748 j != immediates.end(); ++j) {
749 int32_t imm = *j;
750 {
751 InstructionSelectorTester m;
752 m.Return(m.Word32Equal(
753 m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)),
754 m.Int32Constant(0)));
755 m.SelectInstructions();
756 CHECK_EQ(1, m.code.size());
757 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
758 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
759 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
760 CHECK_EQ(kEqual, m.code[0]->flags_condition());
761 }
762 {
763 InstructionSelectorTester m;
764 m.Return(m.Word32Equal(
765 m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)),
766 m.Int32Constant(0)));
767 m.SelectInstructions();
768 CHECK_EQ(1, m.code.size());
769 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
770 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
771 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
772 CHECK_EQ(kEqual, m.code[0]->flags_condition());
773 }
774 {
775 InstructionSelectorTester m;
776 m.Return(m.Word32Equal(
777 m.Int32Constant(0),
778 m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm))));
779 m.SelectInstructions();
780 CHECK_EQ(1, m.code.size());
781 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
782 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
783 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
784 CHECK_EQ(kEqual, m.code[0]->flags_condition());
785 }
786 {
787 InstructionSelectorTester m;
788 m.Return(m.Word32Equal(
789 m.Int32Constant(0),
790 m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0))));
791 m.SelectInstructions();
792 CHECK_EQ(1, m.code.size());
793 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
794 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode());
795 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
796 CHECK_EQ(kEqual, m.code[0]->flags_condition());
797 }
798 }
799 }
800 }
801
802
803 TEST(InstructionSelectorWord32EqualAndShiftP) {
804 Shifts shifts;
805 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
806 Shift shift = *i;
807 {
808 InstructionSelectorTester m;
809 m.Return(m.Word32Equal(
810 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))));
811 m.SelectInstructions();
812 CHECK_EQ(1, m.code.size());
813 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
814 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
815 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
816 CHECK_EQ(kEqual, m.code[0]->flags_condition());
817 }
818 {
819 InstructionSelectorTester m;
820 m.Return(m.Word32Equal(
821 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
822 m.SelectInstructions();
823 CHECK_EQ(1, m.code.size());
824 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
825 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
826 CHECK_EQ(kFlags_set, m.code[0]->flags_mode());
827 CHECK_EQ(kEqual, m.code[0]->flags_condition());
828 }
829 }
830 }
831
832
833 TEST(InstructionSelectorBranchWithWord32EqualAndShiftP) {
834 Shifts shifts;
835 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
836 Shift shift = *i;
837 {
838 InstructionSelectorTester m;
839 MLabel blocka, blockb;
840 m.Branch(m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1),
841 m.Parameter(2))),
842 &blocka, &blockb);
843 m.Bind(&blocka);
844 m.Return(m.Int32Constant(1));
845 m.Bind(&blockb);
846 m.Return(m.Int32Constant(0));
847 m.SelectInstructions();
848 CHECK_EQ(1, m.code.size());
849 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
850 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
851 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
852 CHECK_EQ(kEqual, m.code[0]->flags_condition());
853 }
854 {
855 InstructionSelectorTester m;
856 MLabel blocka, blockb;
857 m.Branch(
858 m.Word32Equal(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)),
859 m.Parameter(0)),
860 &blocka, &blockb);
861 m.Bind(&blocka);
862 m.Return(m.Int32Constant(1));
863 m.Bind(&blockb);
864 m.Return(m.Int32Constant(0));
865 m.SelectInstructions();
866 CHECK_EQ(1, m.code.size());
867 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
868 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
869 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
870 CHECK_EQ(kEqual, m.code[0]->flags_condition());
871 }
872 }
873 }
874
875
876 TEST(InstructionSelectorBranchWithWord32EqualAndShiftImm) {
877 Shifts shifts;
878 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
879 Shift shift = *i;
880 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
881 {
882 InstructionSelectorTester m;
883 MLabel blocka, blockb;
884 m.Branch(
885 m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1),
886 m.Int32Constant(imm))),
887 &blocka, &blockb);
888 m.Bind(&blocka);
889 m.Return(m.Int32Constant(1));
890 m.Bind(&blockb);
891 m.Return(m.Int32Constant(0));
892 m.SelectInstructions();
893 CHECK_EQ(1, m.code.size());
894 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
895 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
896 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
897 CHECK_EQ(kEqual, m.code[0]->flags_condition());
898 }
899 {
900 InstructionSelectorTester m;
901 MLabel blocka, blockb;
902 m.Branch(m.Word32Equal(
903 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)),
904 m.Parameter(0)),
905 &blocka, &blockb);
906 m.Bind(&blocka);
907 m.Return(m.Int32Constant(1));
908 m.Bind(&blockb);
909 m.Return(m.Int32Constant(0));
910 m.SelectInstructions();
911 CHECK_EQ(1, m.code.size());
912 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
913 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
914 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
915 CHECK_EQ(kEqual, m.code[0]->flags_condition());
916 }
917 }
918 }
919 }
920
921
922 TEST(InstructionSelectorBranchWithDPIP) {
923 DPIs dpis;
924 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
925 DPI dpi = *i;
926 {
927 InstructionSelectorTester m;
928 MLabel blocka, blockb;
929 m.Branch(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)), &blocka,
930 &blockb);
931 m.Bind(&blocka);
932 m.Return(m.Int32Constant(1));
933 m.Bind(&blockb);
934 m.Return(m.Int32Constant(0));
935 m.SelectInstructions();
936 CHECK_EQ(1, m.code.size());
937 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
938 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
939 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
940 CHECK_EQ(kNotEqual, m.code[0]->flags_condition());
941 }
942 {
943 InstructionSelectorTester m;
944 MLabel blocka, blockb;
945 m.Branch(m.Word32Equal(m.Int32Constant(0),
946 m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))),
947 &blocka, &blockb);
948 m.Bind(&blocka);
949 m.Return(m.Int32Constant(1));
950 m.Bind(&blockb);
951 m.Return(m.Int32Constant(0));
952 m.SelectInstructions();
953 CHECK_EQ(1, m.code.size());
954 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
955 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
956 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
957 CHECK_EQ(kEqual, m.code[0]->flags_condition());
958 }
959 {
960 InstructionSelectorTester m;
961 MLabel blocka, blockb;
962 m.Branch(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)),
963 m.Int32Constant(0)),
964 &blocka, &blockb);
965 m.Bind(&blocka);
966 m.Return(m.Int32Constant(1));
967 m.Bind(&blockb);
968 m.Return(m.Int32Constant(0));
969 m.SelectInstructions();
970 CHECK_EQ(1, m.code.size());
971 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode());
972 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode());
973 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
974 CHECK_EQ(kEqual, m.code[0]->flags_condition());
975 }
976 }
977 }
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-instruction-selector.cc ('k') | test/cctest/compiler/test-js-constant-cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698