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