Chromium Code Reviews| 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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1263 g.UseRegister(mright.left().node()), | 1263 g.UseRegister(mright.left().node()), |
| 1264 g.UseRegister(mright.right().node()), | 1264 g.UseRegister(mright.right().node()), |
| 1265 g.UseRegister(m.left().node())); | 1265 g.UseRegister(m.left().node())); |
| 1266 return; | 1266 return; |
| 1267 } | 1267 } |
| 1268 } | 1268 } |
| 1269 | 1269 |
| 1270 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add); | 1270 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add); |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 void VisitInt32MulWithOverflowImpl(InstructionSelector* selector, Node* node, | |
|
Benedikt Meurer
2016/07/12 04:09:28
Put this into an anonymous namespace and remove th
mvstanton
2016/07/12 08:52:49
Done.
| |
| 1274 FlagsContinuation* cont) { | |
| 1275 Arm64OperandGenerator g(selector); | |
| 1276 Int32BinopMatcher m(node); | |
| 1277 InstructionOperand result = g.DefineAsRegister(node); | |
| 1278 InstructionOperand left = g.UseRegister(m.left().node()); | |
| 1279 InstructionOperand right = g.UseRegister(m.right().node()); | |
| 1280 selector->Emit(kArm64Smull, result, left, right); | |
| 1281 | |
| 1282 InstructionCode opcode = cont->Encode(kArm64Cmp) | | |
| 1283 AddressingModeField::encode(kMode_Operand2_R_SXTW); | |
| 1284 if (cont->IsBranch()) { | |
| 1285 selector->Emit(opcode, g.NoOutput(), result, result, | |
| 1286 g.Label(cont->true_block()), g.Label(cont->false_block())); | |
| 1287 } else if (cont->IsDeoptimize()) { | |
| 1288 InstructionOperand in[] = {result, result}; | |
| 1289 selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->frame_state()); | |
| 1290 } else { | |
| 1291 DCHECK(cont->IsSet()); | |
| 1292 selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); | |
| 1293 } | |
| 1294 } | |
| 1273 | 1295 |
| 1274 void InstructionSelector::VisitInt32Mul(Node* node) { | 1296 void InstructionSelector::VisitInt32Mul(Node* node) { |
| 1275 Arm64OperandGenerator g(this); | 1297 Arm64OperandGenerator g(this); |
| 1276 Int32BinopMatcher m(node); | 1298 Int32BinopMatcher m(node); |
| 1277 | 1299 |
| 1278 // First, try to reduce the multiplication to addition with left shift. | 1300 // First, try to reduce the multiplication to addition with left shift. |
| 1279 // x * (2^k + 1) -> x + (x << k) | 1301 // x * (2^k + 1) -> x + (x << k) |
| 1280 int32_t shift = LeftShiftForReducedMultiply(&m); | 1302 int32_t shift = LeftShiftForReducedMultiply(&m); |
| 1281 if (shift > 0) { | 1303 if (shift > 0) { |
| 1282 Emit(kArm64Add32 | AddressingModeField::encode(kMode_Operand2_R_LSL_I), | 1304 Emit(kArm64Add32 | AddressingModeField::encode(kMode_Operand2_R_LSL_I), |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 if (mright.left().Is(0)) { | 1368 if (mright.left().Is(0)) { |
| 1347 Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 1369 Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
| 1348 g.UseRegister(mright.right().node())); | 1370 g.UseRegister(mright.right().node())); |
| 1349 return; | 1371 return; |
| 1350 } | 1372 } |
| 1351 } | 1373 } |
| 1352 | 1374 |
| 1353 VisitRRR(this, kArm64Mul, node); | 1375 VisitRRR(this, kArm64Mul, node); |
| 1354 } | 1376 } |
| 1355 | 1377 |
| 1356 | |
| 1357 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 1378 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
| 1358 Arm64OperandGenerator g(this); | 1379 Arm64OperandGenerator g(this); |
| 1359 InstructionOperand const smull_operand = g.TempRegister(); | 1380 InstructionOperand const smull_operand = g.TempRegister(); |
| 1360 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), | 1381 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), |
| 1361 g.UseRegister(node->InputAt(1))); | 1382 g.UseRegister(node->InputAt(1))); |
| 1362 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); | 1383 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); |
| 1363 } | 1384 } |
| 1364 | 1385 |
| 1365 | 1386 |
| 1366 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 1387 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2241 if (result == nullptr || selector->IsDefined(result)) { | 2262 if (result == nullptr || selector->IsDefined(result)) { |
| 2242 switch (node->opcode()) { | 2263 switch (node->opcode()) { |
| 2243 case IrOpcode::kInt32AddWithOverflow: | 2264 case IrOpcode::kInt32AddWithOverflow: |
| 2244 cont->OverwriteAndNegateIfEqual(kOverflow); | 2265 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 2245 return VisitBinop<Int32BinopMatcher>( | 2266 return VisitBinop<Int32BinopMatcher>( |
| 2246 selector, node, kArm64Add32, kArithmeticImm, cont); | 2267 selector, node, kArm64Add32, kArithmeticImm, cont); |
| 2247 case IrOpcode::kInt32SubWithOverflow: | 2268 case IrOpcode::kInt32SubWithOverflow: |
| 2248 cont->OverwriteAndNegateIfEqual(kOverflow); | 2269 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 2249 return VisitBinop<Int32BinopMatcher>( | 2270 return VisitBinop<Int32BinopMatcher>( |
| 2250 selector, node, kArm64Sub32, kArithmeticImm, cont); | 2271 selector, node, kArm64Sub32, kArithmeticImm, cont); |
| 2272 case IrOpcode::kInt32MulWithOverflow: | |
| 2273 // ARM64 doesn't set the overflow flag for multiplication, so we | |
| 2274 // need to test on kNotEqual. Here is the code sequence used: | |
| 2275 // smull result, left, right | |
| 2276 // cmp result.X(), Operand(result, SXTW) | |
| 2277 cont->OverwriteAndNegateIfEqual(kNotEqual); | |
| 2278 return VisitInt32MulWithOverflowImpl(selector, node, cont); | |
| 2251 case IrOpcode::kInt64AddWithOverflow: | 2279 case IrOpcode::kInt64AddWithOverflow: |
| 2252 cont->OverwriteAndNegateIfEqual(kOverflow); | 2280 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 2253 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Add, | 2281 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Add, |
| 2254 kArithmeticImm, cont); | 2282 kArithmeticImm, cont); |
| 2255 case IrOpcode::kInt64SubWithOverflow: | 2283 case IrOpcode::kInt64SubWithOverflow: |
| 2256 cont->OverwriteAndNegateIfEqual(kOverflow); | 2284 cont->OverwriteAndNegateIfEqual(kOverflow); |
| 2257 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Sub, | 2285 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Sub, |
| 2258 kArithmeticImm, cont); | 2286 kArithmeticImm, cont); |
| 2259 default: | 2287 default: |
| 2260 break; | 2288 break; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2448 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 2476 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| 2449 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 2477 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 2450 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 2478 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 2451 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, | 2479 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, |
| 2452 kArithmeticImm, &cont); | 2480 kArithmeticImm, &cont); |
| 2453 } | 2481 } |
| 2454 FlagsContinuation cont; | 2482 FlagsContinuation cont; |
| 2455 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont); | 2483 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont); |
| 2456 } | 2484 } |
| 2457 | 2485 |
| 2486 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) { | |
| 2487 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | |
| 2488 // ARM64 doesn't set the overflow flag for multiplication, so we need to | |
| 2489 // test on kNotEqual. Here is the code sequence used: | |
| 2490 // smull result, left, right | |
| 2491 // cmp result.X(), Operand(result, SXTW) | |
| 2492 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); | |
| 2493 return VisitInt32MulWithOverflowImpl(this, node, &cont); | |
| 2494 } | |
| 2495 FlagsContinuation cont; | |
| 2496 VisitInt32MulWithOverflowImpl(this, node, &cont); | |
| 2497 } | |
| 2458 | 2498 |
| 2459 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { | 2499 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { |
| 2460 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 2500 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 2461 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 2501 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 2462 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, | 2502 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, |
| 2463 &cont); | 2503 &cont); |
| 2464 } | 2504 } |
| 2465 FlagsContinuation cont; | 2505 FlagsContinuation cont; |
| 2466 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont); | 2506 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont); |
| 2467 } | 2507 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2678 // static | 2718 // static |
| 2679 MachineOperatorBuilder::AlignmentRequirements | 2719 MachineOperatorBuilder::AlignmentRequirements |
| 2680 InstructionSelector::AlignmentRequirements() { | 2720 InstructionSelector::AlignmentRequirements() { |
| 2681 return MachineOperatorBuilder::AlignmentRequirements:: | 2721 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2682 FullUnalignedAccessSupport(); | 2722 FullUnalignedAccessSupport(); |
| 2683 } | 2723 } |
| 2684 | 2724 |
| 2685 } // namespace compiler | 2725 } // namespace compiler |
| 2686 } // namespace internal | 2726 } // namespace internal |
| 2687 } // namespace v8 | 2727 } // namespace v8 |
| OLD | NEW |