deps: update v8 to 4.3.61.21
[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(Word32Clz, 1, 0, 1),
184     PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1),
185     PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1),
186     PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1),
187     PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1),
188     PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1),
189     PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1),
190     PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1),
191     PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1),
192     PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1),
193     PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1),
194     PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1),
195     PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1),
196     PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1),
197     PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1),
198     PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1),
199     PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1),
200     PURE(ChangeUint32ToFloat64, 1, 0, 1), 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(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1),
209     PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1),
210     PURE(Float64ExtractHighWord32, 1, 0, 1),
211     PURE(Float64InsertLowWord32, 2, 0, 1),
212     PURE(Float64InsertHighWord32, 2, 0, 1), PURE(Float64Max, 2, 0, 1),
213     PURE(Float64Min, 2, 0, 1)
214 #undef PURE
215 };
216
217
218 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
219
220 }  // namespace
221
222
223 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
224   const PureOperator& pop = GetParam();
225   MachineOperatorBuilder machine1(zone(), type());
226   MachineOperatorBuilder machine2(zone(), type());
227   EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
228 }
229
230
231 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
232   MachineOperatorBuilder machine(zone(), type());
233   const PureOperator& pop = GetParam();
234   const Operator* op = (machine.*pop.constructor)();
235
236   EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
237   EXPECT_EQ(0, op->EffectInputCount());
238   EXPECT_EQ(pop.control_input_count, op->ControlInputCount());
239   EXPECT_EQ(pop.value_input_count + pop.control_input_count,
240             OperatorProperties::GetTotalInputCount(op));
241
242   EXPECT_EQ(pop.value_output_count, op->ValueOutputCount());
243   EXPECT_EQ(0, op->EffectOutputCount());
244   EXPECT_EQ(0, op->ControlOutputCount());
245 }
246
247
248 TEST_P(MachinePureOperatorTest, MarkedAsPure) {
249   MachineOperatorBuilder machine(zone(), type());
250   const PureOperator& pop = GetParam();
251   const Operator* op = (machine.*pop.constructor)();
252   EXPECT_TRUE(op->HasProperty(Operator::kPure));
253 }
254
255
256 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
257   MachineOperatorBuilder machine(zone(), type());
258   const PureOperator& pop = GetParam();
259   const Operator* op = (machine.*pop.constructor)();
260   EXPECT_EQ(pop.opcode, op->opcode());
261 }
262
263
264 INSTANTIATE_TEST_CASE_P(
265     MachineOperatorTest, MachinePureOperatorTest,
266     ::testing::Combine(::testing::ValuesIn(kMachineReps),
267                        ::testing::ValuesIn(kPureOperators)));
268
269 #endif  // GTEST_HAS_COMBINE
270
271
272 // -----------------------------------------------------------------------------
273 // Pseudo operators.
274
275
276 namespace {
277
278 typedef TestWithZone MachineOperatorTest;
279
280 }  // namespace
281
282
283 TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
284   MachineOperatorBuilder machine(zone(), kRepWord32);
285   EXPECT_EQ(machine.Word32And(), machine.WordAnd());
286   EXPECT_EQ(machine.Word32Or(), machine.WordOr());
287   EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
288   EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
289   EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
290   EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
291   EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
292   EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
293   EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
294   EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
295   EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
296   EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
297   EXPECT_EQ(machine.Uint32Div(), machine.UintDiv());
298   EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
299   EXPECT_EQ(machine.Uint32Mod(), machine.UintMod());
300   EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
301   EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
302 }
303
304
305 TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
306   MachineOperatorBuilder machine(zone(), kRepWord64);
307   EXPECT_EQ(machine.Word64And(), machine.WordAnd());
308   EXPECT_EQ(machine.Word64Or(), machine.WordOr());
309   EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
310   EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
311   EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
312   EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
313   EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
314   EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
315   EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
316   EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
317   EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
318   EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
319   EXPECT_EQ(machine.Uint64Div(), machine.UintDiv());
320   EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
321   EXPECT_EQ(machine.Uint64Mod(), machine.UintMod());
322   EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
323   EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
324 }
325
326 }  // namespace compiler
327 }  // namespace internal
328 }  // namespace v8