Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / machine-operator-unittest.cc
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/machine-operator.h"
6 #include "src/compiler/operator-properties-inl.h"
7 #include "testing/gtest-support.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12
13 #if GTEST_HAS_COMBINE
14
15 // TODO(bmeurer): Find a new home for these.
16 inline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
17   OStringStream ost;
18   ost << type;
19   return os << ost.c_str();
20 }
21 inline std::ostream& operator<<(std::ostream& os,
22                          const WriteBarrierKind& write_barrier_kind) {
23   OStringStream ost;
24   ost << write_barrier_kind;
25   return os << ost.c_str();
26 }
27
28
29 template <typename T>
30 class MachineOperatorTestWithParam
31     : public ::testing::TestWithParam< ::testing::tuple<MachineType, T> > {
32  protected:
33   MachineType type() const { return ::testing::get<0>(B::GetParam()); }
34   const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
35
36  private:
37   typedef ::testing::TestWithParam< ::testing::tuple<MachineType, T> > B;
38 };
39
40
41 namespace {
42
43 const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
44
45
46 const MachineType kMachineTypes[] = {
47     kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
48     kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
49     kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
50     kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
51
52 }  // namespace
53
54
55 // -----------------------------------------------------------------------------
56 // Load operator.
57
58
59 typedef MachineOperatorTestWithParam<LoadRepresentation>
60     MachineLoadOperatorTest;
61
62
63 TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
64   MachineOperatorBuilder machine1(type());
65   MachineOperatorBuilder machine2(type());
66   EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
67 }
68
69
70 TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
71   MachineOperatorBuilder machine(type());
72   const Operator* op = machine.Load(GetParam());
73
74   EXPECT_EQ(2, OperatorProperties::GetValueInputCount(op));
75   EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
76   EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
77   EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
78
79   EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
80   EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
81   EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
82 }
83
84
85 TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
86   MachineOperatorBuilder machine(type());
87   EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
88 }
89
90
91 TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
92   MachineOperatorBuilder machine(type());
93   EXPECT_EQ(GetParam(),
94             OpParameter<LoadRepresentation>(machine.Load(GetParam())));
95 }
96
97
98 INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
99                         ::testing::Combine(::testing::ValuesIn(kMachineReps),
100                                            ::testing::ValuesIn(kMachineTypes)));
101
102
103 // -----------------------------------------------------------------------------
104 // Store operator.
105
106
107 class MachineStoreOperatorTest
108     : public MachineOperatorTestWithParam<
109           ::testing::tuple<MachineType, WriteBarrierKind> > {
110  protected:
111   StoreRepresentation GetParam() const {
112     return StoreRepresentation(
113         ::testing::get<0>(MachineOperatorTestWithParam<
114             ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
115         ::testing::get<1>(MachineOperatorTestWithParam<
116             ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
117   }
118 };
119
120
121 TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
122   MachineOperatorBuilder machine1(type());
123   MachineOperatorBuilder machine2(type());
124   EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
125 }
126
127
128 TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
129   MachineOperatorBuilder machine(type());
130   const Operator* op = machine.Store(GetParam());
131
132   EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
133   EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
134   EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
135   EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
136
137   EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
138   EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
139   EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
140 }
141
142
143 TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
144   MachineOperatorBuilder machine(type());
145   EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
146 }
147
148
149 TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
150   MachineOperatorBuilder machine(type());
151   EXPECT_EQ(GetParam(),
152             OpParameter<StoreRepresentation>(machine.Store(GetParam())));
153 }
154
155
156 INSTANTIATE_TEST_CASE_P(
157     MachineOperatorTest, MachineStoreOperatorTest,
158     ::testing::Combine(
159         ::testing::ValuesIn(kMachineReps),
160         ::testing::Combine(::testing::ValuesIn(kMachineTypes),
161                            ::testing::Values(kNoWriteBarrier,
162                                              kFullWriteBarrier))));
163
164
165 // -----------------------------------------------------------------------------
166 // Pure operators.
167
168
169 namespace {
170
171 struct PureOperator {
172   const Operator* (MachineOperatorBuilder::*constructor)();
173   IrOpcode::Value opcode;
174   int value_input_count;
175   int value_output_count;
176 };
177
178
179 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
180   return os << IrOpcode::Mnemonic(pop.opcode);
181 }
182
183
184 const PureOperator kPureOperators[] = {
185 #define PURE(Name, input_count, output_count)                      \
186   {                                                                \
187     &MachineOperatorBuilder::Name, IrOpcode::k##Name, input_count, \
188         output_count                                               \
189   }
190     PURE(Word32And, 2, 1),                PURE(Word32Or, 2, 1),
191     PURE(Word32Xor, 2, 1),                PURE(Word32Shl, 2, 1),
192     PURE(Word32Shr, 2, 1),                PURE(Word32Sar, 2, 1),
193     PURE(Word32Ror, 2, 1),                PURE(Word32Equal, 2, 1),
194     PURE(Word64And, 2, 1),                PURE(Word64Or, 2, 1),
195     PURE(Word64Xor, 2, 1),                PURE(Word64Shl, 2, 1),
196     PURE(Word64Shr, 2, 1),                PURE(Word64Sar, 2, 1),
197     PURE(Word64Ror, 2, 1),                PURE(Word64Equal, 2, 1),
198     PURE(Int32Add, 2, 1),                 PURE(Int32AddWithOverflow, 2, 2),
199     PURE(Int32Sub, 2, 1),                 PURE(Int32SubWithOverflow, 2, 2),
200     PURE(Int32Mul, 2, 1),                 PURE(Int32Div, 2, 1),
201     PURE(Int32UDiv, 2, 1),                PURE(Int32Mod, 2, 1),
202     PURE(Int32UMod, 2, 1),                PURE(Int32LessThan, 2, 1),
203     PURE(Int32LessThanOrEqual, 2, 1),     PURE(Uint32LessThan, 2, 1),
204     PURE(Uint32LessThanOrEqual, 2, 1),    PURE(Int64Add, 2, 1),
205     PURE(Int64Sub, 2, 1),                 PURE(Int64Mul, 2, 1),
206     PURE(Int64Div, 2, 1),                 PURE(Int64UDiv, 2, 1),
207     PURE(Int64Mod, 2, 1),                 PURE(Int64UMod, 2, 1),
208     PURE(Int64LessThan, 2, 1),            PURE(Int64LessThanOrEqual, 2, 1),
209     PURE(ChangeFloat32ToFloat64, 1, 1),   PURE(ChangeFloat64ToInt32, 1, 1),
210     PURE(ChangeFloat64ToUint32, 1, 1),    PURE(ChangeInt32ToInt64, 1, 1),
211     PURE(ChangeUint32ToFloat64, 1, 1),    PURE(ChangeUint32ToUint64, 1, 1),
212     PURE(TruncateFloat64ToFloat32, 1, 1), PURE(TruncateFloat64ToInt32, 1, 1),
213     PURE(TruncateInt64ToInt32, 1, 1),     PURE(Float64Add, 2, 1),
214     PURE(Float64Sub, 2, 1),               PURE(Float64Mul, 2, 1),
215     PURE(Float64Div, 2, 1),               PURE(Float64Mod, 2, 1),
216     PURE(Float64Sqrt, 1, 1),              PURE(Float64Equal, 2, 1),
217     PURE(Float64LessThan, 2, 1),          PURE(Float64LessThanOrEqual, 2, 1)
218 #undef PURE
219 };
220
221
222 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
223
224 }  // namespace
225
226
227 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
228   const PureOperator& pop = GetParam();
229   MachineOperatorBuilder machine1(type());
230   MachineOperatorBuilder machine2(type());
231   EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
232 }
233
234
235 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
236   MachineOperatorBuilder machine(type());
237   const PureOperator& pop = GetParam();
238   const Operator* op = (machine.*pop.constructor)();
239
240   EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
241   EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
242   EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
243   EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
244
245   EXPECT_EQ(pop.value_output_count,
246             OperatorProperties::GetValueOutputCount(op));
247   EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
248   EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
249 }
250
251
252 TEST_P(MachinePureOperatorTest, MarkedAsPure) {
253   MachineOperatorBuilder machine(type());
254   const PureOperator& pop = GetParam();
255   const Operator* op = (machine.*pop.constructor)();
256   EXPECT_TRUE(op->HasProperty(Operator::kPure));
257 }
258
259
260 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
261   MachineOperatorBuilder machine(type());
262   const PureOperator& pop = GetParam();
263   const Operator* op = (machine.*pop.constructor)();
264   EXPECT_EQ(pop.opcode, op->opcode());
265 }
266
267
268 INSTANTIATE_TEST_CASE_P(
269     MachineOperatorTest, MachinePureOperatorTest,
270     ::testing::Combine(::testing::ValuesIn(kMachineReps),
271                        ::testing::ValuesIn(kPureOperators)));
272
273 #endif  // GTEST_HAS_COMBINE
274
275
276 // -----------------------------------------------------------------------------
277 // Pseudo operators.
278
279
280 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
281   MachineOperatorBuilder machine(kRepWord32);
282   EXPECT_EQ(machine.Word32And(), machine.WordAnd());
283   EXPECT_EQ(machine.Word32Or(), machine.WordOr());
284   EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
285   EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
286   EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
287   EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
288   EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
289   EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
290   EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
291   EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
292   EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
293   EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
294   EXPECT_EQ(machine.Int32UDiv(), machine.IntUDiv());
295   EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
296   EXPECT_EQ(machine.Int32UMod(), machine.IntUMod());
297   EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
298   EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
299 }
300
301
302 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
303   MachineOperatorBuilder machine(kRepWord64);
304   EXPECT_EQ(machine.Word64And(), machine.WordAnd());
305   EXPECT_EQ(machine.Word64Or(), machine.WordOr());
306   EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
307   EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
308   EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
309   EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
310   EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
311   EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
312   EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
313   EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
314   EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
315   EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
316   EXPECT_EQ(machine.Int64UDiv(), machine.IntUDiv());
317   EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
318   EXPECT_EQ(machine.Int64UMod(), machine.IntUMod());
319   EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
320   EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
321 }
322
323 }  // namespace compiler
324 }  // namespace internal
325 }  // namespace v8