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

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

Issue 601723002: MIPS: Add turbofan support for mips32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased 1-Oct, port r24319, r24350, r24356, r24367. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/compiler/call-tester.h ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "test/unittests/compiler/instruction-selector-unittest.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10
11 namespace {
12
13 template <typename T>
14 struct MachInst {
15 T constructor;
16 const char* constructor_name;
17 ArchOpcode arch_opcode;
18 MachineType machine_type;
19 };
20
21 template <typename T>
22 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
23 return os << mi.constructor_name;
24 }
25
26 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
27 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
28
29 // To avoid duplicated code IntCmp helper structure
30 // is created. It contains MachInst2 with two nodes and expected_size
31 // because different cmp instructions have different size.
32 struct IntCmp {
33 MachInst2 mi;
34 uint32_t expected_size;
35 };
36
37 struct FPCmp {
38 MachInst2 mi;
39 FlagsCondition cond;
40 };
41
42 const FPCmp kFPCmpInstructions[] = {
43 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMipsCmpD,
44 kMachFloat64},
45 kUnorderedEqual},
46 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsCmpD,
47 kMachFloat64},
48 kUnorderedLessThan},
49 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
50 kMipsCmpD, kMachFloat64},
51 kUnorderedLessThanOrEqual},
52 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", kMipsCmpD,
53 kMachFloat64},
54 kUnorderedLessThan},
55 {{&RawMachineAssembler::Float64GreaterThanOrEqual,
56 "Float64GreaterThanOrEqual", kMipsCmpD, kMachFloat64},
57 kUnorderedLessThanOrEqual}};
58
59 struct Conversion {
60 // The machine_type field in MachInst1 represents the destination type.
61 MachInst1 mi;
62 MachineType src_machine_type;
63 };
64
65
66 // ----------------------------------------------------------------------------
67 // Logical instructions.
68 // ----------------------------------------------------------------------------
69
70
71 const MachInst2 kLogicalInstructions[] = {
72 {&RawMachineAssembler::WordAnd, "WordAnd", kMipsAnd, kMachInt16},
73 {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, kMachInt16},
74 {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, kMachInt16},
75 {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, kMachInt32},
76 {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, kMachInt32},
77 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, kMachInt32}};
78
79
80 // ----------------------------------------------------------------------------
81 // Shift instructions.
82 // ----------------------------------------------------------------------------
83
84
85 const MachInst2 kShiftInstructions[] = {
86 {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, kMachInt16},
87 {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, kMachInt16},
88 {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, kMachInt16},
89 {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, kMachInt16},
90 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, kMachInt32},
91 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, kMachInt32},
92 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, kMachInt32},
93 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, kMachInt32}};
94
95
96 // ----------------------------------------------------------------------------
97 // MUL/DIV instructions.
98 // ----------------------------------------------------------------------------
99
100
101 const MachInst2 kMulDivInstructions[] = {
102 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, kMachInt32},
103 {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, kMachInt32},
104 {&RawMachineAssembler::Uint32Div, "Uint32Div", kMipsDivU, kMachUint32},
105 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsMulD, kMachFloat64},
106 {&RawMachineAssembler::Float64Div, "Float64Div", kMipsDivD, kMachFloat64}};
107
108
109 // ----------------------------------------------------------------------------
110 // MOD instructions.
111 // ----------------------------------------------------------------------------
112
113
114 const MachInst2 kModInstructions[] = {
115 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, kMachInt32},
116 {&RawMachineAssembler::Uint32Mod, "Int32UMod", kMipsModU, kMachInt32},
117 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsModD, kMachFloat64}};
118
119
120 // ----------------------------------------------------------------------------
121 // Arithmetic FPU instructions.
122 // ----------------------------------------------------------------------------
123
124
125 const MachInst2 kFPArithInstructions[] = {
126 {&RawMachineAssembler::Float64Add, "Float64Add", kMipsAddD, kMachFloat64},
127 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsSubD, kMachFloat64}};
128
129
130 // ----------------------------------------------------------------------------
131 // IntArithTest instructions, two nodes.
132 // ----------------------------------------------------------------------------
133
134
135 const MachInst2 kAddSubInstructions[] = {
136 {&RawMachineAssembler::Int32Add, "Int32Add", kMipsAdd, kMachInt32},
137 {&RawMachineAssembler::Int32Sub, "Int32Sub", kMipsSub, kMachInt32},
138 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
139 kMipsAddOvf, kMachInt32},
140 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
141 kMipsSubOvf, kMachInt32}};
142
143
144 // ----------------------------------------------------------------------------
145 // IntArithTest instructions, one node.
146 // ----------------------------------------------------------------------------
147
148
149 const MachInst1 kAddSubOneInstructions[] = {
150 {&RawMachineAssembler::Int32Neg, "Int32Neg", kMipsSub, kMachInt32},
151 // TODO(dusmil): check this ...
152 // {&RawMachineAssembler::WordEqual , "WordEqual" , kMipsTst, kMachInt32}
153 };
154
155
156 // ----------------------------------------------------------------------------
157 // Arithmetic compare instructions.
158 // ----------------------------------------------------------------------------
159
160
161 const IntCmp kCmpInstructions[] = {
162 {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, kMachInt16}, 1U},
163 {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, kMachInt16},
164 2U},
165 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, kMachInt32},
166 1U},
167 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp,
168 kMachInt32},
169 2U},
170 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp,
171 kMachInt32},
172 1U},
173 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
174 kMipsCmp, kMachInt32},
175 1U},
176 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMipsCmp,
177 kMachInt32},
178 1U},
179 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual",
180 kMipsCmp, kMachInt32},
181 1U},
182 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMipsCmp,
183 kMachUint32},
184 1U},
185 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
186 kMipsCmp, kMachUint32},
187 1U}};
188
189
190 // ----------------------------------------------------------------------------
191 // Conversion instructions.
192 // ----------------------------------------------------------------------------
193
194 const Conversion kConversionInstructions[] = {
195 // Conversion instructions are related to machine_operator.h:
196 // FPU conversions:
197 // Convert representation of integers between float64 and int32/uint32.
198 // The precise rounding mode and handling of out of range inputs are *not*
199 // defined for these operators, since they are intended only for use with
200 // integers.
201 // mips instruction: cvt_d_w
202 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
203 kMipsCvtDW, kMachFloat64},
204 kMachInt32},
205
206 // mips instruction: cvt_d_uw
207 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
208 kMipsCvtDUw, kMachFloat64},
209 kMachInt32},
210
211 // mips instruction: trunc_w_d
212 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
213 kMipsTruncWD, kMachFloat64},
214 kMachInt32},
215
216 // mips instruction: trunc_uw_d
217 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
218 kMipsTruncUwD, kMachFloat64},
219 kMachInt32}};
220
221 } // namespace
222
223
224 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
225
226
227 TEST_P(InstructionSelectorFPCmpTest, Parameter) {
228 const FPCmp cmp = GetParam();
229 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
230 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
231 Stream s = m.Build();
232 ASSERT_EQ(1U, s.size());
233 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
234 EXPECT_EQ(2U, s[0]->InputCount());
235 EXPECT_EQ(1U, s[0]->OutputCount());
236 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
237 EXPECT_EQ(cmp.cond, s[0]->flags_condition());
238 }
239
240 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
241 ::testing::ValuesIn(kFPCmpInstructions));
242
243
244 // ----------------------------------------------------------------------------
245 // Arithmetic compare instructions integers.
246 // ----------------------------------------------------------------------------
247
248
249 typedef InstructionSelectorTestWithParam<IntCmp> InstructionSelectorCmpTest;
250
251
252 TEST_P(InstructionSelectorCmpTest, Parameter) {
253 const IntCmp cmp = GetParam();
254 const MachineType type = cmp.mi.machine_type;
255 StreamBuilder m(this, type, type, type);
256 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
257 Stream s = m.Build();
258 ASSERT_EQ(cmp.expected_size, s.size());
259 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
260 EXPECT_EQ(2U, s[0]->InputCount());
261 EXPECT_EQ(1U, s[0]->OutputCount());
262 }
263
264
265 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorCmpTest,
266 ::testing::ValuesIn(kCmpInstructions));
267
268
269 // ----------------------------------------------------------------------------
270 // Shift instructions.
271 // ----------------------------------------------------------------------------
272
273
274 typedef InstructionSelectorTestWithParam<MachInst2>
275 InstructionSelectorShiftTest;
276
277
278 TEST_P(InstructionSelectorShiftTest, Immediate) {
279 const MachInst2 dpi = GetParam();
280 const MachineType type = dpi.machine_type;
281 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
282 StreamBuilder m(this, type, type);
283 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
284 Stream s = m.Build();
285 ASSERT_EQ(1U, s.size());
286 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
287 EXPECT_EQ(2U, s[0]->InputCount());
288 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
289 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
290 EXPECT_EQ(1U, s[0]->OutputCount());
291 }
292 }
293
294
295 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
296 ::testing::ValuesIn(kShiftInstructions));
297
298
299 // ----------------------------------------------------------------------------
300 // Logical instructions.
301 // ----------------------------------------------------------------------------
302
303
304 typedef InstructionSelectorTestWithParam<MachInst2>
305 InstructionSelectorLogicalTest;
306
307
308 TEST_P(InstructionSelectorLogicalTest, Parameter) {
309 const MachInst2 dpi = GetParam();
310 const MachineType type = dpi.machine_type;
311 StreamBuilder m(this, type, type, type);
312 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
313 Stream s = m.Build();
314 ASSERT_EQ(1U, s.size());
315 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
316 EXPECT_EQ(2U, s[0]->InputCount());
317 EXPECT_EQ(1U, s[0]->OutputCount());
318 }
319
320
321 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
322 ::testing::ValuesIn(kLogicalInstructions));
323
324
325 // ----------------------------------------------------------------------------
326 // MUL/DIV instructions.
327 // ----------------------------------------------------------------------------
328
329
330 typedef InstructionSelectorTestWithParam<MachInst2>
331 InstructionSelectorMulDivTest;
332
333
334 TEST_P(InstructionSelectorMulDivTest, Parameter) {
335 const MachInst2 dpi = GetParam();
336 const MachineType type = dpi.machine_type;
337 StreamBuilder m(this, type, type, type);
338 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
339 Stream s = m.Build();
340 ASSERT_EQ(1U, s.size());
341 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
342 EXPECT_EQ(2U, s[0]->InputCount());
343 EXPECT_EQ(1U, s[0]->OutputCount());
344 }
345
346
347 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
348 ::testing::ValuesIn(kMulDivInstructions));
349
350
351 // ----------------------------------------------------------------------------
352 // MOD instructions.
353 // ----------------------------------------------------------------------------
354
355
356 typedef InstructionSelectorTestWithParam<MachInst2> InstructionSelectorModTest;
357
358
359 TEST_P(InstructionSelectorModTest, Parameter) {
360 const MachInst2 dpi = GetParam();
361 const MachineType type = dpi.machine_type;
362 StreamBuilder m(this, type, type, type);
363 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
364 Stream s = m.Build();
365 ASSERT_EQ(1U, s.size());
366 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
367 EXPECT_EQ(2U, s[0]->InputCount());
368 EXPECT_EQ(1U, s[0]->OutputCount());
369 }
370
371
372 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorModTest,
373 ::testing::ValuesIn(kModInstructions));
374
375
376 // ----------------------------------------------------------------------------
377 // Floating point instructions.
378 // ----------------------------------------------------------------------------
379
380
381 typedef InstructionSelectorTestWithParam<MachInst2>
382 InstructionSelectorFPArithTest;
383
384
385 TEST_P(InstructionSelectorFPArithTest, Parameter) {
386 const MachInst2 fpa = GetParam();
387 StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
388 m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
389 Stream s = m.Build();
390 ASSERT_EQ(1U, s.size());
391 EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
392 EXPECT_EQ(2U, s[0]->InputCount());
393 EXPECT_EQ(1U, s[0]->OutputCount());
394 }
395
396
397 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
398 ::testing::ValuesIn(kFPArithInstructions));
399
400
401 // ----------------------------------------------------------------------------
402 // Integer arithmetic.
403 // ----------------------------------------------------------------------------
404
405
406 typedef InstructionSelectorTestWithParam<MachInst2>
407 InstructionSelectorIntArithTwoTest;
408
409
410 TEST_P(InstructionSelectorIntArithTwoTest, Parameter) {
411 const MachInst2 intpa = GetParam();
412 StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
413 intpa.machine_type);
414 m.Return((m.*intpa.constructor)(m.Parameter(0), m.Parameter(1)));
415 Stream s = m.Build();
416 ASSERT_EQ(1U, s.size());
417 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
418 EXPECT_EQ(2U, s[0]->InputCount());
419 EXPECT_EQ(1U, s[0]->OutputCount());
420 }
421
422
423 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
424 InstructionSelectorIntArithTwoTest,
425 ::testing::ValuesIn(kAddSubInstructions));
426
427
428 // ----------------------------------------------------------------------------
429 // One node.
430 // ----------------------------------------------------------------------------
431
432
433 typedef InstructionSelectorTestWithParam<MachInst1>
434 InstructionSelectorIntArithOneTest;
435
436
437 TEST_P(InstructionSelectorIntArithOneTest, Parameter) {
438 const MachInst1 intpa = GetParam();
439 StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
440 intpa.machine_type);
441 m.Return((m.*intpa.constructor)(m.Parameter(0)));
442 Stream s = m.Build();
443 ASSERT_EQ(1U, s.size());
444 EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
445 EXPECT_EQ(2U, s[0]->InputCount());
446 EXPECT_EQ(1U, s[0]->OutputCount());
447 }
448
449
450 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
451 InstructionSelectorIntArithOneTest,
452 ::testing::ValuesIn(kAddSubOneInstructions));
453
454
455 // ----------------------------------------------------------------------------
456 // Conversions.
457 // ----------------------------------------------------------------------------
458
459
460 typedef InstructionSelectorTestWithParam<Conversion>
461 InstructionSelectorConversionTest;
462
463
464 TEST_P(InstructionSelectorConversionTest, Parameter) {
465 const Conversion conv = GetParam();
466 StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
467 m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
468 Stream s = m.Build();
469 ASSERT_EQ(1U, s.size());
470 EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
471 EXPECT_EQ(1U, s[0]->InputCount());
472 EXPECT_EQ(1U, s[0]->OutputCount());
473 }
474
475
476 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
477 InstructionSelectorConversionTest,
478 ::testing::ValuesIn(kConversionInstructions));
479
480
481 // ----------------------------------------------------------------------------
482 // Loads and stores.
483 // ----------------------------------------------------------------------------
484
485 namespace {
486
487 struct MemoryAccess {
488 MachineType type;
489 ArchOpcode load_opcode;
490 ArchOpcode store_opcode;
491 };
492
493
494 static const MemoryAccess kMemoryAccesses[] = {
495 {kMachInt8, kMipsLb, kMipsSb},
496 {kMachUint8, kMipsLbu, kMipsSb},
497 {kMachInt16, kMipsLh, kMipsSh},
498 {kMachUint16, kMipsLhu, kMipsSh},
499 {kMachInt32, kMipsLw, kMipsSw},
500 {kRepFloat32, kMipsLwc1, kMipsSwc1},
501 {kRepFloat64, kMipsLdc1, kMipsSdc1}};
502
503
504 struct MemoryAccessImm {
505 MachineType type;
506 ArchOpcode load_opcode;
507 ArchOpcode store_opcode;
508 bool (InstructionSelectorTest::Stream::*val_predicate)(
509 const InstructionOperand*) const;
510 const int32_t immediates[40];
511 };
512
513
514 std::ostream& operator<<(std::ostream& os, const MemoryAccessImm& acc) {
515 return os << acc.type;
516 }
517
518
519 struct MemoryAccessImm1 {
520 MachineType type;
521 ArchOpcode load_opcode;
522 ArchOpcode store_opcode;
523 bool (InstructionSelectorTest::Stream::*val_predicate)(
524 const InstructionOperand*) const;
525 const int32_t immediates[5];
526 };
527
528
529 std::ostream& operator<<(std::ostream& os, const MemoryAccessImm1& acc) {
530 return os << acc.type;
531 }
532
533
534 // ----------------------------------------------------------------------------
535 // Loads and stores immediate values.
536 // ----------------------------------------------------------------------------
537
538
539 const MemoryAccessImm kMemoryAccessesImm[] = {
540 {kMachInt8,
541 kMipsLb,
542 kMipsSb,
543 &InstructionSelectorTest::Stream::IsInteger,
544 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
545 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
546 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
547 {kMachUint8,
548 kMipsLbu,
549 kMipsSb,
550 &InstructionSelectorTest::Stream::IsInteger,
551 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
552 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
553 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
554 {kMachInt16,
555 kMipsLh,
556 kMipsSh,
557 &InstructionSelectorTest::Stream::IsInteger,
558 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
559 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
560 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
561 {kMachUint16,
562 kMipsLhu,
563 kMipsSh,
564 &InstructionSelectorTest::Stream::IsInteger,
565 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
566 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
567 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
568 {kMachInt32,
569 kMipsLw,
570 kMipsSw,
571 &InstructionSelectorTest::Stream::IsInteger,
572 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
573 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
574 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
575 {kMachFloat32,
576 kMipsLwc1,
577 kMipsSwc1,
578 &InstructionSelectorTest::Stream::IsDouble,
579 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
580 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
581 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
582 {kMachFloat64,
583 kMipsLdc1,
584 kMipsSdc1,
585 &InstructionSelectorTest::Stream::IsDouble,
586 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
587 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
588 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}};
589
590
591 const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = {
592 {kMachInt8,
593 kMipsLb,
594 kMipsSb,
595 &InstructionSelectorTest::Stream::IsInteger,
596 {-65000, -55000, 32777, 55000, 65000}},
597 {kMachInt8,
598 kMipsLbu,
599 kMipsSb,
600 &InstructionSelectorTest::Stream::IsInteger,
601 {-65000, -55000, 32777, 55000, 65000}},
602 {kMachInt16,
603 kMipsLh,
604 kMipsSh,
605 &InstructionSelectorTest::Stream::IsInteger,
606 {-65000, -55000, 32777, 55000, 65000}},
607 {kMachInt16,
608 kMipsLhu,
609 kMipsSh,
610 &InstructionSelectorTest::Stream::IsInteger,
611 {-65000, -55000, 32777, 55000, 65000}},
612 {kMachInt32,
613 kMipsLw,
614 kMipsSw,
615 &InstructionSelectorTest::Stream::IsInteger,
616 {-65000, -55000, 32777, 55000, 65000}},
617 {kMachFloat32,
618 kMipsLwc1,
619 kMipsSwc1,
620 &InstructionSelectorTest::Stream::IsDouble,
621 {-65000, -55000, 32777, 55000, 65000}},
622 {kMachFloat64,
623 kMipsLdc1,
624 kMipsSdc1,
625 &InstructionSelectorTest::Stream::IsDouble,
626 {-65000, -55000, 32777, 55000, 65000}}};
627
628 } // namespace
629
630
631 typedef InstructionSelectorTestWithParam<MemoryAccess>
632 InstructionSelectorMemoryAccessTest;
633
634
635 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
636 const MemoryAccess memacc = GetParam();
637 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
638 m.Return(m.Load(memacc.type, m.Parameter(0)));
639 Stream s = m.Build();
640 ASSERT_EQ(1U, s.size());
641 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
642 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
643 }
644
645
646 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
647 const MemoryAccess memacc = GetParam();
648 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
649 m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
650 m.Return(m.Int32Constant(0));
651 Stream s = m.Build();
652 ASSERT_EQ(1U, s.size());
653 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
654 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
655 }
656
657
658 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
659 InstructionSelectorMemoryAccessTest,
660 ::testing::ValuesIn(kMemoryAccesses));
661
662
663 // ----------------------------------------------------------------------------
664 // Load immediate.
665 // ----------------------------------------------------------------------------
666
667
668 typedef InstructionSelectorTestWithParam<MemoryAccessImm>
669 InstructionSelectorMemoryAccessImmTest;
670
671
672 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) {
673 const MemoryAccessImm memacc = GetParam();
674 TRACED_FOREACH(int32_t, index, memacc.immediates) {
675 StreamBuilder m(this, memacc.type, kMachPtr);
676 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
677 Stream s = m.Build();
678 ASSERT_EQ(1U, s.size());
679 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
680 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
681 ASSERT_EQ(2U, s[0]->InputCount());
682 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
683 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
684 ASSERT_EQ(1U, s[0]->OutputCount());
685 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
686 }
687 }
688
689
690 // ----------------------------------------------------------------------------
691 // Store immediate.
692 // ----------------------------------------------------------------------------
693
694
695 TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
696 const MemoryAccessImm memacc = GetParam();
697 TRACED_FOREACH(int32_t, index, memacc.immediates) {
698 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
699 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
700 m.Parameter(1));
701 m.Return(m.Int32Constant(0));
702 Stream s = m.Build();
703 ASSERT_EQ(1U, s.size());
704 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
705 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
706 ASSERT_EQ(3U, s[0]->InputCount());
707 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
708 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
709 EXPECT_EQ(0U, s[0]->OutputCount());
710 }
711 }
712
713
714 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
715 InstructionSelectorMemoryAccessImmTest,
716 ::testing::ValuesIn(kMemoryAccessesImm));
717
718
719 // ----------------------------------------------------------------------------
720 // Load/store offsets more than 16 bits.
721 // ----------------------------------------------------------------------------
722
723
724 typedef InstructionSelectorTestWithParam<MemoryAccessImm1>
725 InstructionSelectorMemoryAccessImmMoreThan16bitTest;
726
727
728 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
729 LoadWithImmediateIndex) {
730 const MemoryAccessImm1 memacc = GetParam();
731 TRACED_FOREACH(int32_t, index, memacc.immediates) {
732 StreamBuilder m(this, memacc.type, kMachPtr);
733 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
734 Stream s = m.Build();
735 ASSERT_EQ(2U, s.size());
736 // kMipsAdd is expected opcode.
737 // size more than 16 bits wide.
738 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
739 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
740 EXPECT_EQ(2U, s[0]->InputCount());
741 EXPECT_EQ(1U, s[0]->OutputCount());
742 }
743 }
744
745
746 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
747 StoreWithImmediateIndex) {
748 const MemoryAccessImm1 memacc = GetParam();
749 TRACED_FOREACH(int32_t, index, memacc.immediates) {
750 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
751 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
752 m.Parameter(1));
753 m.Return(m.Int32Constant(0));
754 Stream s = m.Build();
755 ASSERT_EQ(2U, s.size());
756 // kMipsAdd is expected opcode
757 // size more than 16 bits wide
758 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
759 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
760 EXPECT_EQ(2U, s[0]->InputCount());
761 EXPECT_EQ(1U, s[0]->OutputCount());
762 }
763 }
764
765
766 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
767 InstructionSelectorMemoryAccessImmMoreThan16bitTest,
768 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit));
769
770
771 // ----------------------------------------------------------------------------
772 // kMipsTst testing.
773 // ----------------------------------------------------------------------------
774
775
776 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
777 {
778 StreamBuilder m(this, kMachInt32, kMachInt32);
779 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
780 Stream s = m.Build();
781 ASSERT_EQ(1U, s.size());
782 EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
783 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
784 ASSERT_EQ(2U, s[0]->InputCount());
785 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
786 EXPECT_EQ(1U, s[0]->OutputCount());
787 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
788 EXPECT_EQ(kEqual, s[0]->flags_condition());
789 }
790 {
791 StreamBuilder m(this, kMachInt32, kMachInt32);
792 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
793 Stream s = m.Build();
794 ASSERT_EQ(1U, s.size());
795 EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
796 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
797 ASSERT_EQ(2U, s[0]->InputCount());
798 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
799 EXPECT_EQ(1U, s[0]->OutputCount());
800 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
801 EXPECT_EQ(kEqual, s[0]->flags_condition());
802 }
803 }
804
805 } // namespace compiler
806 } // namespace internal
807 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/compiler/call-tester.h ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698