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 |