| 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 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 X87OperandGenerator g(selector); | 1204 X87OperandGenerator g(selector); |
| 1205 if (commutative && g.CanBeBetterLeftOperand(right)) { | 1205 if (commutative && g.CanBeBetterLeftOperand(right)) { |
| 1206 std::swap(left, right); | 1206 std::swap(left, right); |
| 1207 } | 1207 } |
| 1208 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 1208 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 // Tries to match the size of the given opcode to that of the operands, if | 1211 // Tries to match the size of the given opcode to that of the operands, if |
| 1212 // possible. | 1212 // possible. |
| 1213 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, | 1213 InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, |
| 1214 Node* right) { | 1214 Node* right, FlagsContinuation* cont) { |
| 1215 if (opcode != kX87Cmp && opcode != kX87Test) { | |
| 1216 return opcode; | |
| 1217 } | |
| 1218 // Currently, if one of the two operands is not a Load, we don't know what its | 1215 // Currently, if one of the two operands is not a Load, we don't know what its |
| 1219 // machine representation is, so we bail out. | 1216 // machine representation is, so we bail out. |
| 1220 // TODO(epertoso): we can probably get some size information out of immediates | 1217 // TODO(epertoso): we can probably get some size information out of immediates |
| 1221 // and phi nodes. | 1218 // and phi nodes. |
| 1222 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { | 1219 if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { |
| 1223 return opcode; | 1220 return opcode; |
| 1224 } | 1221 } |
| 1225 // If the load representations don't match, both operands will be | 1222 // If the load representations don't match, both operands will be |
| 1226 // zero/sign-extended to 32bit. | 1223 // zero/sign-extended to 32bit. |
| 1227 LoadRepresentation left_representation = LoadRepresentationOf(left->op()); | 1224 MachineType left_type = LoadRepresentationOf(left->op()); |
| 1228 if (left_representation != LoadRepresentationOf(right->op())) { | 1225 MachineType right_type = LoadRepresentationOf(right->op()); |
| 1229 return opcode; | 1226 if (left_type == right_type) { |
| 1227 switch (left_type.representation()) { |
| 1228 case MachineRepresentation::kBit: |
| 1229 case MachineRepresentation::kWord8: { |
| 1230 if (opcode == kX87Test) return kX87Test8; |
| 1231 if (opcode == kX87Cmp) { |
| 1232 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1233 cont->OverwriteUnsignedIfSigned(); |
| 1234 } else { |
| 1235 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1236 } |
| 1237 return kX87Cmp8; |
| 1238 } |
| 1239 break; |
| 1240 } |
| 1241 case MachineRepresentation::kWord16: |
| 1242 if (opcode == kX87Test) return kX87Test16; |
| 1243 if (opcode == kX87Cmp) { |
| 1244 if (left_type.semantic() == MachineSemantic::kUint32) { |
| 1245 cont->OverwriteUnsignedIfSigned(); |
| 1246 } else { |
| 1247 CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); |
| 1248 } |
| 1249 return kX87Cmp16; |
| 1250 } |
| 1251 break; |
| 1252 default: |
| 1253 break; |
| 1254 } |
| 1230 } | 1255 } |
| 1231 switch (left_representation.representation()) { | 1256 return opcode; |
| 1232 case MachineRepresentation::kBit: | |
| 1233 case MachineRepresentation::kWord8: | |
| 1234 return opcode == kX87Cmp ? kX87Cmp8 : kX87Test8; | |
| 1235 case MachineRepresentation::kWord16: | |
| 1236 return opcode == kX87Cmp ? kX87Cmp16 : kX87Test16; | |
| 1237 default: | |
| 1238 return opcode; | |
| 1239 } | |
| 1240 } | 1257 } |
| 1241 | 1258 |
| 1242 // Shared routine for multiple float32 compare operations (inputs commuted). | 1259 // Shared routine for multiple float32 compare operations (inputs commuted). |
| 1243 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1260 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1244 FlagsContinuation* cont) { | 1261 FlagsContinuation* cont) { |
| 1245 X87OperandGenerator g(selector); | 1262 X87OperandGenerator g(selector); |
| 1246 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); | 1263 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| 1247 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); | 1264 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| 1248 if (cont->IsBranch()) { | 1265 if (cont->IsBranch()) { |
| 1249 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), | 1266 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1280 } | 1297 } |
| 1281 } | 1298 } |
| 1282 | 1299 |
| 1283 // Shared routine for multiple word compare operations. | 1300 // Shared routine for multiple word compare operations. |
| 1284 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1301 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1285 InstructionCode opcode, FlagsContinuation* cont) { | 1302 InstructionCode opcode, FlagsContinuation* cont) { |
| 1286 X87OperandGenerator g(selector); | 1303 X87OperandGenerator g(selector); |
| 1287 Node* left = node->InputAt(0); | 1304 Node* left = node->InputAt(0); |
| 1288 Node* right = node->InputAt(1); | 1305 Node* right = node->InputAt(1); |
| 1289 | 1306 |
| 1290 InstructionCode narrowed_opcode = TryNarrowOpcodeSize(opcode, left, right); | 1307 InstructionCode narrowed_opcode = |
| 1308 TryNarrowOpcodeSize(opcode, left, right, cont); |
| 1291 | 1309 |
| 1292 int effect_level = selector->GetEffectLevel(node); | 1310 int effect_level = selector->GetEffectLevel(node); |
| 1293 if (cont->IsBranch()) { | 1311 if (cont->IsBranch()) { |
| 1294 effect_level = selector->GetEffectLevel( | 1312 effect_level = selector->GetEffectLevel( |
| 1295 cont->true_block()->PredecessorAt(0)->control_input()); | 1313 cont->true_block()->PredecessorAt(0)->control_input()); |
| 1296 } | 1314 } |
| 1297 | 1315 |
| 1298 // If one of the two inputs is an immediate, make sure it's on the right, or | 1316 // If one of the two inputs is an immediate, make sure it's on the right, or |
| 1299 // if one of the two inputs is a memory operand, make sure it's on the left. | 1317 // if one of the two inputs is a memory operand, make sure it's on the left. |
| 1300 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || | 1318 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 // static | 1734 // static |
| 1717 MachineOperatorBuilder::AlignmentRequirements | 1735 MachineOperatorBuilder::AlignmentRequirements |
| 1718 InstructionSelector::AlignmentRequirements() { | 1736 InstructionSelector::AlignmentRequirements() { |
| 1719 return MachineOperatorBuilder::AlignmentRequirements:: | 1737 return MachineOperatorBuilder::AlignmentRequirements:: |
| 1720 FullUnalignedAccessSupport(); | 1738 FullUnalignedAccessSupport(); |
| 1721 } | 1739 } |
| 1722 | 1740 |
| 1723 } // namespace compiler | 1741 } // namespace compiler |
| 1724 } // namespace internal | 1742 } // namespace internal |
| 1725 } // namespace v8 | 1743 } // namespace v8 |
| OLD | NEW |