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

Side by Side Diff: src/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: minor cleanups Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file
4
5 #include "src/compiler/instruction-selector-unittest.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10
11 namespace {
12
13 template <typename T>
14 struct MachInst {
15 T constructor;
16 const char* constructor_name;
17 ArchOpcode arch_opcode;
18 MachineType machine_type;
19 };
20
Benedikt Meurer 2014/09/25 05:37:11 You should add std::ostream& operator<<(std::ostre
paul.l... 2014/09/25 17:18:39 Done.
21 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
22 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
23
24 // To avoid duplicated code IntCmp helper structure
25 // is created. It contains MachInst2 with two nodes and expected_size
26 // because different cmp instructions have different size.
27 struct IntCmp {
28 MachInst2 mi;
29 uint32_t expected_size;
30 };
31
32 struct FPCmp {
33 MachInst2 mi;
34 FlagsCondition cond;
35 };
36
37 static const FPCmp kFPCmpInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
38 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMipsFloat64Cmp,
39 kMachFloat64},
40 kUnorderedEqual},
41 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsFloat64Cmp,
42 kMachFloat64},
43 kUnorderedLessThan},
44 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
45 kMipsFloat64Cmp, kMachFloat64},
46 kUnorderedLessThanOrEqual},
47 {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan",
48 kMipsFloat64Cmp, kMachFloat64},
49 kUnorderedLessThan},
50 {{&RawMachineAssembler::Float64GreaterThanOrEqual,
51 "Float64GreaterThanOrEqual", kMipsFloat64Cmp, kMachFloat64},
52 kUnorderedLessThanOrEqual}};
53
54 struct Conversion {
55 // The machine_type field in MachInst1 represents the destination type.
56 MachInst1 mi;
57 MachineType src_machine_type;
58 };
59
60
61 // ----------------------------------------------------------------------------
62 // Logical instructions.
63 // ----------------------------------------------------------------------------
64
65
66 static const MachInst2 kLogicalInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:40 Done.
67 {&RawMachineAssembler::WordAnd, "WordAnd", kMipsAnd, kMachInt16},
68 {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, kMachInt16},
69 {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, kMachInt16},
70 {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, kMachInt32},
71 {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, kMachInt32},
72 {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, kMachInt32}};
73
74
75 // ----------------------------------------------------------------------------
76 // Shift instructions.
77 // ----------------------------------------------------------------------------
78
79
80 static const MachInst2 kShiftInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
81 {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, kMachInt16},
82 {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, kMachInt16},
83 {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, kMachInt16},
84 {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, kMachInt16},
85 {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, kMachInt32},
86 {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, kMachInt32},
87 {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, kMachInt32},
88 {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, kMachInt32}};
89
90
91 // ----------------------------------------------------------------------------
92 // MUL/DIV instructions.
93 // ----------------------------------------------------------------------------
94
95
96 static const MachInst2 kMulDivInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
97 {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, kMachInt32},
98 {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, kMachInt32},
99 {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kMipsDivU, kMachUint32},
100 {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsFloat64Mul,
101 kMachFloat64},
102 {&RawMachineAssembler::Float64Div, "Float64Div", kMipsFloat64Div,
103 kMachFloat64}};
104
105
106 // ----------------------------------------------------------------------------
107 // MOD instructions.
108 // ----------------------------------------------------------------------------
109
110
111 static const MachInst2 kModInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
112 {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, kMachInt32},
113 {&RawMachineAssembler::Int32UMod, "Int32UMod", kMipsModU, kMachInt32},
114 {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsFloat64Mod,
115 kMachFloat64}};
116
117
118 // ----------------------------------------------------------------------------
119 // Arithmetic FPU instructions.
120 // ----------------------------------------------------------------------------
121
122
123 static const MachInst2 kFPArithInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
124 {&RawMachineAssembler::Float64Add, "Float64Add", kMipsFloat64Add,
125 kMachFloat64},
126 {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsFloat64Sub,
127 kMachFloat64}};
128
129
130 // ----------------------------------------------------------------------------
131 // IntArithTest instructions, two nodes.
132 // ----------------------------------------------------------------------------
133
134
135 static const MachInst2 kAddSubInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
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 static const MachInst1 kAddSubOneInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
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 static const IntCmp kCmpInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:39 Done.
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 static const Conversion kConversionInstructions[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: no need to use static, it's in an anonymous n
paul.l... 2014/09/25 17:18:40 Done.
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 kMipsInt32ToFloat64, kMachFloat64},
204 kMachInt32},
205
206 // mips instruction: cvt_d_uw
207 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
208 kMipsUint32ToFloat64, kMachFloat64},
209 kMachInt32},
210
211 // mips instruction: trunc_w_d
212 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
213 kMipsFloat64ToInt32, kMachFloat64},
214 kMachInt32},
215
216 // mips instruction: trunc_uw_d
217 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
218 kMipsFloat64ToUint32, 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
Benedikt Meurer 2014/09/25 05:37:11 You should add std::ostream& operator<<(std::ostr
paul.l... 2014/09/25 17:18:39 Done.
513
514 struct MemoryAccessImm1 {
515 MachineType type;
516 ArchOpcode load_opcode;
517 ArchOpcode store_opcode;
518 bool (InstructionSelectorTest::Stream::*val_predicate)(
519 const InstructionOperand*) const;
520 const int32_t immediates[5];
521 };
522
Benedikt Meurer 2014/09/25 05:37:11 Stream operator, see above.
paul.l... 2014/09/25 17:18:39 Done.
523
524 // ----------------------------------------------------------------------------
525 // Loads and stores immediate values.
526 // ----------------------------------------------------------------------------
527
528
529 static const MemoryAccessImm kMemoryAccessesImm[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: static, see above.
paul.l... 2014/09/25 17:18:40 Done.
530 {kMachInt8,
531 kMipsLb,
532 kMipsSb,
533 &InstructionSelectorTest::Stream::IsInteger,
534 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
535 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
536 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
537 {kMachUint8,
538 kMipsLbu,
539 kMipsSb,
540 &InstructionSelectorTest::Stream::IsInteger,
541 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
542 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
543 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
544 {kMachInt16,
545 kMipsLh,
546 kMipsSh,
547 &InstructionSelectorTest::Stream::IsInteger,
548 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
549 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
550 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
551 {kMachUint16,
552 kMipsLhu,
553 kMipsSh,
554 &InstructionSelectorTest::Stream::IsInteger,
555 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
556 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
557 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
558 {kMachInt32,
559 kMipsLw,
560 kMipsSw,
561 &InstructionSelectorTest::Stream::IsInteger,
562 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
563 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
564 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
565 {kMachFloat32,
566 kMipsLwc1,
567 kMipsSwc1,
568 &InstructionSelectorTest::Stream::IsDouble,
569 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
570 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
571 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
572 {kMachFloat64,
573 kMipsLdc1,
574 kMipsSdc1,
575 &InstructionSelectorTest::Stream::IsDouble,
576 {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
577 -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
578 115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}};
579
580
581 static const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = {
Benedikt Meurer 2014/09/25 05:37:11 Nit: static, see above.
paul.l... 2014/09/25 17:18:39 Done.
582 {kMachInt8,
583 kMipsLb,
584 kMipsSb,
585 &InstructionSelectorTest::Stream::IsInteger,
586 {-65000, -55000, 32777, 55000, 65000}},
587 {kMachInt8,
588 kMipsLbu,
589 kMipsSb,
590 &InstructionSelectorTest::Stream::IsInteger,
591 {-65000, -55000, 32777, 55000, 65000}},
592 {kMachInt16,
593 kMipsLh,
594 kMipsSh,
595 &InstructionSelectorTest::Stream::IsInteger,
596 {-65000, -55000, 32777, 55000, 65000}},
597 {kMachInt16,
598 kMipsLhu,
599 kMipsSh,
600 &InstructionSelectorTest::Stream::IsInteger,
601 {-65000, -55000, 32777, 55000, 65000}},
602 {kMachInt32,
603 kMipsLw,
604 kMipsSw,
605 &InstructionSelectorTest::Stream::IsInteger,
606 {-65000, -55000, 32777, 55000, 65000}},
607 {kMachFloat32,
608 kMipsLwc1,
609 kMipsSwc1,
610 &InstructionSelectorTest::Stream::IsDouble,
611 {-65000, -55000, 32777, 55000, 65000}},
612 {kMachFloat64,
613 kMipsLdc1,
614 kMipsSdc1,
615 &InstructionSelectorTest::Stream::IsDouble,
616 {-65000, -55000, 32777, 55000, 65000}}};
617
618 } // namespace
619
620
621 typedef InstructionSelectorTestWithParam<MemoryAccess>
622 InstructionSelectorMemoryAccessTest;
623
624
625 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
626 const MemoryAccess memacc = GetParam();
627 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
628 m.Return(m.Load(memacc.type, m.Parameter(0)));
629 Stream s = m.Build();
630 ASSERT_EQ(1U, s.size());
631 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
632 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
633 }
634
635
636 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
637 const MemoryAccess memacc = GetParam();
638 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
639 m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
640 m.Return(m.Int32Constant(0));
641 Stream s = m.Build();
642 ASSERT_EQ(1U, s.size());
643 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
644 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
645 }
646
647
648 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
649 InstructionSelectorMemoryAccessTest,
650 ::testing::ValuesIn(kMemoryAccesses));
651
652
653 // ----------------------------------------------------------------------------
654 // Load immediate.
655 // ----------------------------------------------------------------------------
656
657
658 typedef InstructionSelectorTestWithParam<MemoryAccessImm>
659 InstructionSelectorMemoryAccessImmTest;
660
661
662 TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) {
663 const MemoryAccessImm memacc = GetParam();
664 TRACED_FOREACH(int32_t, index, memacc.immediates) {
665 StreamBuilder m(this, memacc.type, kMachPtr);
666 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
667 Stream s = m.Build();
668 ASSERT_EQ(1U, s.size());
669 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
670 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
671 ASSERT_EQ(2U, s[0]->InputCount());
672 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
673 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
674 ASSERT_EQ(1U, s[0]->OutputCount());
675 EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
676 }
677 }
678
679
680 // ----------------------------------------------------------------------------
681 // Store immediate.
682 // ----------------------------------------------------------------------------
683
684
685 TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
686 const MemoryAccessImm memacc = GetParam();
687 TRACED_FOREACH(int32_t, index, memacc.immediates) {
688 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
689 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
690 m.Parameter(1));
691 m.Return(m.Int32Constant(0));
692 Stream s = m.Build();
693 ASSERT_EQ(1U, s.size());
694 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
695 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
696 ASSERT_EQ(3U, s[0]->InputCount());
697 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
698 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
699 EXPECT_EQ(0U, s[0]->OutputCount());
700 }
701 }
702
703
704 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
705 InstructionSelectorMemoryAccessImmTest,
706 ::testing::ValuesIn(kMemoryAccessesImm));
707
708
709 // ----------------------------------------------------------------------------
710 // Load/store offsets more than 16 bits.
711 // ----------------------------------------------------------------------------
712
713
714 typedef InstructionSelectorTestWithParam<MemoryAccessImm1>
715 InstructionSelectorMemoryAccessImmMoreThan16bitTest;
716
717
718 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
719 LoadWithImmediateIndex) {
720 const MemoryAccessImm1 memacc = GetParam();
721 TRACED_FOREACH(int32_t, index, memacc.immediates) {
722 StreamBuilder m(this, memacc.type, kMachPtr);
723 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
724 Stream s = m.Build();
725 ASSERT_EQ(2U, s.size());
726 // kMipsAdd is expected opcode.
727 // size more than 16 bits wide.
728 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
729 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
730 EXPECT_EQ(2U, s[0]->InputCount());
731 EXPECT_EQ(1U, s[0]->OutputCount());
732 }
733 }
734
735
736 TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
737 StoreWithImmediateIndex) {
738 const MemoryAccessImm1 memacc = GetParam();
739 TRACED_FOREACH(int32_t, index, memacc.immediates) {
740 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
741 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
742 m.Parameter(1));
743 m.Return(m.Int32Constant(0));
744 Stream s = m.Build();
745 ASSERT_EQ(2U, s.size());
746 // kMipsAdd is expected opcode
747 // size more than 16 bits wide
748 EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
749 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
750 EXPECT_EQ(2U, s[0]->InputCount());
751 EXPECT_EQ(1U, s[0]->OutputCount());
752 }
753 }
754
755
756 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
757 InstructionSelectorMemoryAccessImmMoreThan16bitTest,
758 ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit));
759
760
761 // ----------------------------------------------------------------------------
762 // kMipsTst testing.
763 // ----------------------------------------------------------------------------
764
765
766 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
767 {
768 StreamBuilder m(this, kMachInt32, kMachInt32);
769 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
770 Stream s = m.Build();
771 ASSERT_EQ(1U, s.size());
772 EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
773 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
774 ASSERT_EQ(2U, s[0]->InputCount());
775 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
776 EXPECT_EQ(1U, s[0]->OutputCount());
777 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
778 EXPECT_EQ(kEqual, s[0]->flags_condition());
779 }
780 {
781 StreamBuilder m(this, kMachInt32, kMachInt32);
782 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
783 Stream s = m.Build();
784 ASSERT_EQ(1U, s.size());
785 EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
786 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
787 ASSERT_EQ(2U, s[0]->InputCount());
788 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
789 EXPECT_EQ(1U, s[0]->OutputCount());
790 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
791 EXPECT_EQ(kEqual, s[0]->flags_condition());
792 }
793 }
794
795
Benedikt Meurer 2014/09/25 05:37:11 Nit: extra new line :-)
paul.l... 2014/09/25 17:18:39 Done.
796 } // namespace compiler
797 } // namespace internal
798 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698