| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 IA32OperandGenerator g(selector); | 1209 IA32OperandGenerator g(selector); |
| 1210 if (commutative && g.CanBeBetterLeftOperand(right)) { | 1210 if (commutative && g.CanBeBetterLeftOperand(right)) { |
| 1211 std::swap(left, right); | 1211 std::swap(left, right); |
| 1212 } | 1212 } |
| 1213 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 1213 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
| 1214 } | 1214 } |
| 1215 | 1215 |
| 1216 // Tries to match the size of the given opcode to that of the operands, if | 1216 // Tries to match the size of the given opcode to that of the operands, if |
| 1217 // possible. | 1217 // possible. |
| 1218 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, | 1218 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, |
| 1219 Node* right) { | 1219 Node* right, FlagsContinuation* cont) { |
| 1220 if (opcode != kIA32Cmp && opcode != kIA32Test) { | |
| 1221 return opcode; | |
| 1222 } | |
| 1223 // Currently, if one of the two operands is not a Load, we don't know what its | 1220 // Currently, if one of the two operands is not a Load, we don't know what its |
| 1224 // machine representation is, so we bail out. | 1221 // machine representation is, so we bail out. |
| 1225 // TODO(epertoso): we can probably get some size information out of immediates | 1222 // TODO(epertoso): we can probably get some size information out of immediates |
| 1226 // and phi nodes. | 1223 // and phi nodes. |
| 1227 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { | 1224 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { |
| 1228 return opcode; | 1225 return opcode; |
| 1229 } | 1226 } |
| 1230 // If the load representations don't match, both operands will be | 1227 // If the load representations don't match, both operands will be |
| 1231 // zero/sign-extended to 32bit. | 1228 // zero/sign-extended to 32bit. |
| 1232 LoadRepresentation left_representation = LoadRepresentationOf(left->op()); | 1229 MachineType left_type = LoadRepresentationOf(left->op()); |
| 1233 if (left_representation != LoadRepresentationOf(right->op())) { | 1230 MachineType right_type = LoadRepresentationOf(right->op()); |
| 1234 return opcode; | 1231 if (left_type == right_type) { |
| 1232 switch (left_type.representation()) { |
| 1233 case MachineRepresentation::kBit: |
| 1234 case MachineRepresentation::kWord8: { |
| 1235 if (opcode == kIA32Test) return kIA32Test8; |
| 1236 if (opcode == kIA32Cmp) { |
| 1237 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1238 cont->OverwriteUnsignedIfSigned(); |
| 1239 } else { |
| 1240 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1241 } |
| 1242 return kIA32Cmp8; |
| 1243 } |
| 1244 break; |
| 1245 } |
| 1246 case MachineRepresentation::kWord16: |
| 1247 if (opcode == kIA32Test) return kIA32Test16; |
| 1248 if (opcode == kIA32Cmp) { |
| 1249 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1250 cont->OverwriteUnsignedIfSigned(); |
| 1251 } else { |
| 1252 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1253 } |
| 1254 return kIA32Cmp16; |
| 1255 } |
| 1256 break; |
| 1257 default: |
| 1258 break; |
| 1259 } |
| 1235 } | 1260 } |
| 1236 switch (left_representation.representation()) { | 1261 return opcode; |
| 1237 case MachineRepresentation::kBit: | |
| 1238 case MachineRepresentation::kWord8: | |
| 1239 return opcode == kIA32Cmp ? kIA32Cmp8 : kIA32Test8; | |
| 1240 case MachineRepresentation::kWord16: | |
| 1241 return opcode == kIA32Cmp ? kIA32Cmp16 : kIA32Test16; | |
| 1242 default: | |
| 1243 return opcode; | |
| 1244 } | |
| 1245 } | 1262 } |
| 1246 | 1263 |
| 1247 // Shared routine for multiple float32 compare operations (inputs commuted). | 1264 // Shared routine for multiple float32 compare operations (inputs commuted). |
| 1248 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1265 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1249 FlagsContinuation* cont) { | 1266 FlagsContinuation* cont) { |
| 1250 Node* const left = node->InputAt(0); | 1267 Node* const left = node->InputAt(0); |
| 1251 Node* const right = node->InputAt(1); | 1268 Node* const right = node->InputAt(1); |
| 1252 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); | 1269 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); |
| 1253 } | 1270 } |
| 1254 | 1271 |
| 1255 | 1272 |
| 1256 // Shared routine for multiple float64 compare operations (inputs commuted). | 1273 // Shared routine for multiple float64 compare operations (inputs commuted). |
| 1257 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1274 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1258 FlagsContinuation* cont) { | 1275 FlagsContinuation* cont) { |
| 1259 Node* const left = node->InputAt(0); | 1276 Node* const left = node->InputAt(0); |
| 1260 Node* const right = node->InputAt(1); | 1277 Node* const right = node->InputAt(1); |
| 1261 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); | 1278 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); |
| 1262 } | 1279 } |
| 1263 | 1280 |
| 1264 // Shared routine for multiple word compare operations. | 1281 // Shared routine for multiple word compare operations. |
| 1265 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1282 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1266 InstructionCode opcode, FlagsContinuation* cont) { | 1283 InstructionCode opcode, FlagsContinuation* cont) { |
| 1267 IA32OperandGenerator g(selector); | 1284 IA32OperandGenerator g(selector); |
| 1268 Node* left = node->InputAt(0); | 1285 Node* left = node->InputAt(0); |
| 1269 Node* right = node->InputAt(1); | 1286 Node* right = node->InputAt(1); |
| 1270 | 1287 |
| 1271 InstructionCode narrowed_opcode = TryNarrowOpcodeSize(opcode, left, right); | 1288 InstructionCode narrowed_opcode = |
| 1289 TryNarrowOpcodeSize(opcode, left, right, cont); |
| 1272 | 1290 |
| 1273 int effect_level = selector->GetEffectLevel(node); | 1291 int effect_level = selector->GetEffectLevel(node); |
| 1274 if (cont->IsBranch()) { | 1292 if (cont->IsBranch()) { |
| 1275 effect_level = selector->GetEffectLevel( | 1293 effect_level = selector->GetEffectLevel( |
| 1276 cont->true_block()->PredecessorAt(0)->control_input()); | 1294 cont->true_block()->PredecessorAt(0)->control_input()); |
| 1277 } | 1295 } |
| 1278 | 1296 |
| 1279 // If one of the two inputs is an immediate, make sure it's on the right, or | 1297 // If one of the two inputs is an immediate, make sure it's on the right, or |
| 1280 // if one of the two inputs is a memory operand, make sure it's on the left. | 1298 // if one of the two inputs is a memory operand, make sure it's on the left. |
| 1281 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || | 1299 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 // static | 1721 // static |
| 1704 MachineOperatorBuilder::AlignmentRequirements | 1722 MachineOperatorBuilder::AlignmentRequirements |
| 1705 InstructionSelector::AlignmentRequirements() { | 1723 InstructionSelector::AlignmentRequirements() { |
| 1706 return MachineOperatorBuilder::AlignmentRequirements:: | 1724 return MachineOperatorBuilder::AlignmentRequirements:: |
| 1707 FullUnalignedAccessSupport(); | 1725 FullUnalignedAccessSupport(); |
| 1708 } | 1726 } |
| 1709 | 1727 |
| 1710 } // namespace compiler | 1728 } // namespace compiler |
| 1711 } // namespace internal | 1729 } // namespace internal |
| 1712 } // namespace v8 | 1730 } // namespace v8 |
| OLD | NEW |