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.
5 #include "src/compiler/machine-operator.h"
6 #include "src/compiler/operator-properties-inl.h"
7 #include "testing/gtest-support.h"
16 class MachineOperatorTestWithParam
17 : public ::testing::TestWithParam< ::testing::tuple<MachineType, T> > {
19 MachineType type() const { return ::testing::get<0>(B::GetParam()); }
20 const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
23 typedef ::testing::TestWithParam< ::testing::tuple<MachineType, T> > B;
29 const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
32 const MachineType kMachineTypes[] = {
33 kMachFloat32, kMachFloat64, kMachInt8, kMachUint8, kMachInt16,
34 kMachUint16, kMachInt32, kMachUint32, kMachInt64, kMachUint64,
35 kMachPtr, kMachAnyTagged, kRepBit, kRepWord8, kRepWord16,
36 kRepWord32, kRepWord64, kRepFloat32, kRepFloat64, kRepTagged};
41 // -----------------------------------------------------------------------------
45 typedef MachineOperatorTestWithParam<LoadRepresentation>
46 MachineLoadOperatorTest;
49 TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
50 MachineOperatorBuilder machine1(type());
51 MachineOperatorBuilder machine2(type());
52 EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
56 TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
57 MachineOperatorBuilder machine(type());
58 const Operator* op = machine.Load(GetParam());
60 EXPECT_EQ(2, op->ValueInputCount());
61 EXPECT_EQ(1, op->EffectInputCount());
62 EXPECT_EQ(1, op->ControlInputCount());
63 EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
65 EXPECT_EQ(1, op->ValueOutputCount());
66 EXPECT_EQ(1, op->EffectOutputCount());
67 EXPECT_EQ(0, op->ControlOutputCount());
71 TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
72 MachineOperatorBuilder machine(type());
73 EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
77 TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
78 MachineOperatorBuilder machine(type());
80 OpParameter<LoadRepresentation>(machine.Load(GetParam())));
84 INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
85 ::testing::Combine(::testing::ValuesIn(kMachineReps),
86 ::testing::ValuesIn(kMachineTypes)));
89 // -----------------------------------------------------------------------------
93 class MachineStoreOperatorTest
94 : public MachineOperatorTestWithParam<
95 ::testing::tuple<MachineType, WriteBarrierKind> > {
97 StoreRepresentation GetParam() const {
98 return StoreRepresentation(
99 ::testing::get<0>(MachineOperatorTestWithParam<
100 ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
101 ::testing::get<1>(MachineOperatorTestWithParam<
102 ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
107 TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
108 MachineOperatorBuilder machine1(type());
109 MachineOperatorBuilder machine2(type());
110 EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
114 TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
115 MachineOperatorBuilder machine(type());
116 const Operator* op = machine.Store(GetParam());
118 EXPECT_EQ(3, op->ValueInputCount());
119 EXPECT_EQ(1, op->EffectInputCount());
120 EXPECT_EQ(1, op->ControlInputCount());
121 EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
123 EXPECT_EQ(0, op->ValueOutputCount());
124 EXPECT_EQ(1, op->EffectOutputCount());
125 EXPECT_EQ(0, op->ControlOutputCount());
129 TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
130 MachineOperatorBuilder machine(type());
131 EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
135 TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
136 MachineOperatorBuilder machine(type());
137 EXPECT_EQ(GetParam(),
138 OpParameter<StoreRepresentation>(machine.Store(GetParam())));
142 INSTANTIATE_TEST_CASE_P(
143 MachineOperatorTest, MachineStoreOperatorTest,
145 ::testing::ValuesIn(kMachineReps),
146 ::testing::Combine(::testing::ValuesIn(kMachineTypes),
147 ::testing::Values(kNoWriteBarrier,
148 kFullWriteBarrier))));
151 // -----------------------------------------------------------------------------
157 struct PureOperator {
158 const Operator* (MachineOperatorBuilder::*constructor)();
159 IrOpcode::Value opcode;
160 int value_input_count;
161 int control_input_count;
162 int value_output_count;
166 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
167 return os << IrOpcode::Mnemonic(pop.opcode);
171 const PureOperator kPureOperators[] = {
172 #define PURE(Name, value_input_count, control_input_count, value_output_count) \
174 &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \
175 control_input_count, value_output_count \
177 PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1),
178 PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1),
179 PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1),
180 PURE(Word32Equal, 2, 0, 1), PURE(Word64And, 2, 0, 1),
181 PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), PURE(Word64Shl, 2, 0, 1),
182 PURE(Word64Shr, 2, 0, 1), PURE(Word64Sar, 2, 0, 1),
183 PURE(Word64Ror, 2, 0, 1), PURE(Word64Equal, 2, 0, 1),
184 PURE(Int32Add, 2, 0, 1), PURE(Int32AddWithOverflow, 2, 0, 2),
185 PURE(Int32Sub, 2, 0, 1), PURE(Int32SubWithOverflow, 2, 0, 2),
186 PURE(Int32Mul, 2, 0, 1), PURE(Int32MulHigh, 2, 0, 1),
187 PURE(Int32Div, 2, 1, 1), PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1),
188 PURE(Uint32Mod, 2, 1, 1), PURE(Int32LessThan, 2, 0, 1),
189 PURE(Int32LessThanOrEqual, 2, 0, 1), PURE(Uint32LessThan, 2, 0, 1),
190 PURE(Uint32LessThanOrEqual, 2, 0, 1), PURE(Int64Add, 2, 0, 1),
191 PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), PURE(Int64Div, 2, 0, 1),
192 PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), PURE(Uint64Mod, 2, 0, 1),
193 PURE(Int64LessThan, 2, 0, 1), PURE(Int64LessThanOrEqual, 2, 0, 1),
194 PURE(Uint64LessThan, 2, 0, 1), PURE(ChangeFloat32ToFloat64, 1, 0, 1),
195 PURE(ChangeFloat64ToInt32, 1, 0, 1), PURE(ChangeFloat64ToUint32, 1, 0, 1),
196 PURE(ChangeInt32ToInt64, 1, 0, 1), PURE(ChangeUint32ToFloat64, 1, 0, 1),
197 PURE(ChangeUint32ToUint64, 1, 0, 1),
198 PURE(TruncateFloat64ToFloat32, 1, 0, 1),
199 PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1),
200 PURE(Float64Add, 2, 0, 1), PURE(Float64Sub, 2, 0, 1),
201 PURE(Float64Mul, 2, 0, 1), PURE(Float64Div, 2, 0, 1),
202 PURE(Float64Mod, 2, 0, 1), PURE(Float64Sqrt, 1, 0, 1),
203 PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1),
204 PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1),
205 PURE(Float64Floor, 1, 0, 1), PURE(Float64Ceil, 1, 0, 1),
206 PURE(Float64RoundTruncate, 1, 0, 1), PURE(Float64RoundTiesAway, 1, 0, 1)
211 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
216 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
217 const PureOperator& pop = GetParam();
218 MachineOperatorBuilder machine1(type());
219 MachineOperatorBuilder machine2(type());
220 EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
224 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
225 MachineOperatorBuilder machine(type());
226 const PureOperator& pop = GetParam();
227 const Operator* op = (machine.*pop.constructor)();
229 EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
230 EXPECT_EQ(0, op->EffectInputCount());
231 EXPECT_EQ(pop.control_input_count, op->ControlInputCount());
232 EXPECT_EQ(pop.value_input_count + pop.control_input_count,
233 OperatorProperties::GetTotalInputCount(op));
235 EXPECT_EQ(pop.value_output_count, op->ValueOutputCount());
236 EXPECT_EQ(0, op->EffectOutputCount());
237 EXPECT_EQ(0, op->ControlOutputCount());
241 TEST_P(MachinePureOperatorTest, MarkedAsPure) {
242 MachineOperatorBuilder machine(type());
243 const PureOperator& pop = GetParam();
244 const Operator* op = (machine.*pop.constructor)();
245 EXPECT_TRUE(op->HasProperty(Operator::kPure));
249 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
250 MachineOperatorBuilder machine(type());
251 const PureOperator& pop = GetParam();
252 const Operator* op = (machine.*pop.constructor)();
253 EXPECT_EQ(pop.opcode, op->opcode());
257 INSTANTIATE_TEST_CASE_P(
258 MachineOperatorTest, MachinePureOperatorTest,
259 ::testing::Combine(::testing::ValuesIn(kMachineReps),
260 ::testing::ValuesIn(kPureOperators)));
262 #endif // GTEST_HAS_COMBINE
265 // -----------------------------------------------------------------------------
269 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
270 MachineOperatorBuilder machine(kRepWord32);
271 EXPECT_EQ(machine.Word32And(), machine.WordAnd());
272 EXPECT_EQ(machine.Word32Or(), machine.WordOr());
273 EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
274 EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
275 EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
276 EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
277 EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
278 EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
279 EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
280 EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
281 EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
282 EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
283 EXPECT_EQ(machine.Uint32Div(), machine.UintDiv());
284 EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
285 EXPECT_EQ(machine.Uint32Mod(), machine.UintMod());
286 EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
287 EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
291 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
292 MachineOperatorBuilder machine(kRepWord64);
293 EXPECT_EQ(machine.Word64And(), machine.WordAnd());
294 EXPECT_EQ(machine.Word64Or(), machine.WordOr());
295 EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
296 EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
297 EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
298 EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
299 EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
300 EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
301 EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
302 EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
303 EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
304 EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
305 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv());
306 EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
307 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod());
308 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
309 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
312 } // namespace compiler
313 } // namespace internal