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