Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 2101123005: [turbofan] Introduce integer multiplication with overflow. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compile error. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698