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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 396733006: Optimize the multiplication of two 32-bit unsigned integers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 6084 matching lines...) Expand 10 before | Expand all | Expand 10 after
6095 Register out_hi = out_pair->At(1).reg(); 6095 Register out_hi = out_pair->At(1).reg();
6096 6096
6097 Label* deopt = NULL; 6097 Label* deopt = NULL;
6098 if (CanDeoptimize()) { 6098 if (CanDeoptimize()) {
6099 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); 6099 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
6100 } 6100 }
6101 switch (op_kind()) { 6101 switch (op_kind()) {
6102 case Token::kBIT_AND: { 6102 case Token::kBIT_AND: {
6103 __ and_(out_lo, left_lo, Operand(right_lo)); 6103 __ and_(out_lo, left_lo, Operand(right_lo));
6104 __ and_(out_hi, left_hi, Operand(right_hi)); 6104 __ and_(out_hi, left_hi, Operand(right_hi));
6105 break;
6105 } 6106 }
6106 break;
6107 case Token::kBIT_OR: { 6107 case Token::kBIT_OR: {
6108 __ orr(out_lo, left_lo, Operand(right_lo)); 6108 __ orr(out_lo, left_lo, Operand(right_lo));
6109 __ orr(out_hi, left_hi, Operand(right_hi)); 6109 __ orr(out_hi, left_hi, Operand(right_hi));
6110 break;
6110 } 6111 }
6111 break;
6112 case Token::kBIT_XOR: { 6112 case Token::kBIT_XOR: {
6113 __ eor(out_lo, left_lo, Operand(right_lo)); 6113 __ eor(out_lo, left_lo, Operand(right_lo));
6114 __ eor(out_hi, left_hi, Operand(right_hi)); 6114 __ eor(out_hi, left_hi, Operand(right_hi));
6115 break;
6115 } 6116 }
6116 break;
6117 case Token::kADD: 6117 case Token::kADD:
6118 case Token::kSUB: { 6118 case Token::kSUB: {
6119 if (op_kind() == Token::kADD) { 6119 if (op_kind() == Token::kADD) {
6120 __ adds(out_lo, left_lo, Operand(right_lo)); 6120 __ adds(out_lo, left_lo, Operand(right_lo));
6121 __ adcs(out_hi, left_hi, Operand(right_hi)); 6121 __ adcs(out_hi, left_hi, Operand(right_hi));
6122 } else { 6122 } else {
6123 ASSERT(op_kind() == Token::kSUB); 6123 ASSERT(op_kind() == Token::kSUB);
6124 __ subs(out_lo, left_lo, Operand(right_lo)); 6124 __ subs(out_lo, left_lo, Operand(right_lo));
6125 __ sbcs(out_hi, left_hi, Operand(right_hi)); 6125 __ sbcs(out_hi, left_hi, Operand(right_hi));
6126 } 6126 }
6127 if (can_overflow()) { 6127 if (can_overflow()) {
6128 // Deopt on overflow. 6128 // Deopt on overflow.
6129 __ b(deopt, VS); 6129 __ b(deopt, VS);
6130 } 6130 }
6131 break; 6131 break;
6132 } 6132 }
6133 case Token::kMUL: {
6134 // The product of two signed 32-bit integers fits in a signed 64-bit
6135 // result without causing overflow.
6136 // We deopt on larger inputs.
6137 if (TargetCPUFeatures::arm_version() == ARMv7) {
6138 __ cmp(left_hi, Operand(left_lo, ASR, 31));
6139 __ cmp(right_hi, Operand(right_lo, ASR, 31), EQ);
6140 __ b(deopt, NE);
6141 __ smull(out_lo, out_hi, left_lo, right_lo);
6142 } else {
6143 __ b(deopt);
6144 }
6145 break;
6146 }
6133 default: 6147 default:
6134 UNREACHABLE(); 6148 UNREACHABLE();
6135 break;
6136 } 6149 }
6137 if (FLAG_throw_on_javascript_int_overflow) { 6150 if (FLAG_throw_on_javascript_int_overflow) {
6138 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6151 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6139 } 6152 }
6140 } 6153 }
6141 6154
6142 6155
6143 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 6156 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
6144 bool opt) const { 6157 bool opt) const {
6145 const intptr_t kNumInputs = 2; 6158 const intptr_t kNumInputs = 2;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
6368 6381
6369 6382
6370 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6383 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6371 Register left = locs()->in(0).reg(); 6384 Register left = locs()->in(0).reg();
6372 Register right = locs()->in(1).reg(); 6385 Register right = locs()->in(1).reg();
6373 Register out = locs()->out(0).reg(); 6386 Register out = locs()->out(0).reg();
6374 ASSERT(out != left); 6387 ASSERT(out != left);
6375 switch (op_kind()) { 6388 switch (op_kind()) {
6376 case Token::kBIT_AND: 6389 case Token::kBIT_AND:
6377 __ and_(out, left, Operand(right)); 6390 __ and_(out, left, Operand(right));
6378 break; 6391 break;
6379 case Token::kBIT_OR: 6392 case Token::kBIT_OR:
6380 __ orr(out, left, Operand(right)); 6393 __ orr(out, left, Operand(right));
6381 break; 6394 break;
6382 case Token::kBIT_XOR: 6395 case Token::kBIT_XOR:
6383 __ eor(out, left, Operand(right)); 6396 __ eor(out, left, Operand(right));
6384 break; 6397 break;
6385 case Token::kADD: 6398 case Token::kADD:
6386 __ add(out, left, Operand(right)); 6399 __ add(out, left, Operand(right));
6387 break; 6400 break;
6388 case Token::kSUB: 6401 case Token::kSUB:
6389 __ sub(out, left, Operand(right)); 6402 __ sub(out, left, Operand(right));
6390 break; 6403 break;
6404 case Token::kMUL:
6405 __ mul(out, left, right);
6406 break;
6391 default: 6407 default:
6392 UNREACHABLE(); 6408 UNREACHABLE();
6393 } 6409 }
6394 } 6410 }
6395 6411
6396 6412
6397 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6413 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6398 bool opt) const { 6414 bool opt) const {
6399 const intptr_t kNumInputs = 2; 6415 const intptr_t kNumInputs = 2;
6400 const intptr_t kNumTemps = 1; 6416 const intptr_t kNumTemps = 1;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6434 // Invalid shift value. 6450 // Invalid shift value.
6435 __ b(deopt); 6451 __ b(deopt);
6436 } else if (shift_value > kShifterLimit) { 6452 } else if (shift_value > kShifterLimit) {
6437 // Result is 0. 6453 // Result is 0.
6438 __ eor(out, out, Operand(out)); 6454 __ eor(out, out, Operand(out));
6439 } else { 6455 } else {
6440 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). 6456 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6441 switch (op_kind()) { 6457 switch (op_kind()) {
6442 case Token::kSHR: 6458 case Token::kSHR:
6443 __ Lsr(out, left, shift_value); 6459 __ Lsr(out, left, shift_value);
6444 break; 6460 break;
6445 case Token::kSHL: 6461 case Token::kSHL:
6446 __ Lsl(out, left, shift_value); 6462 __ Lsl(out, left, shift_value);
6447 break; 6463 break;
6448 default: 6464 default:
6449 UNREACHABLE(); 6465 UNREACHABLE();
6450 } 6466 }
6451 } 6467 }
6452 return; 6468 return;
6453 } 6469 }
6454 6470
6455 // Non constant shift value. 6471 // Non constant shift value.
6456 6472
6457 Register shifter = locs()->in(1).reg(); 6473 Register shifter = locs()->in(1).reg();
6458 6474
6459 __ mov(temp, Operand(shifter)); 6475 __ mov(temp, Operand(shifter));
6460 __ SmiUntag(temp); 6476 __ SmiUntag(temp);
6461 __ CompareImmediate(temp, 0); 6477 __ CompareImmediate(temp, 0);
6462 // If shift value is < 0, deoptimize. 6478 // If shift value is < 0, deoptimize.
6463 __ b(deopt, LT); 6479 __ b(deopt, LT);
6464 __ CompareImmediate(temp, kShifterLimit); 6480 __ CompareImmediate(temp, kShifterLimit);
6465 // > kShifterLimit, result is 0. 6481 // > kShifterLimit, result is 0.
6466 __ eor(out, out, Operand(out), HI); 6482 __ eor(out, out, Operand(out), HI);
6467 // Do the shift. 6483 // Do the shift.
6468 switch (op_kind()) { 6484 switch (op_kind()) {
6469 case Token::kSHR: 6485 case Token::kSHR:
6470 __ Lsr(out, left, temp, LS); 6486 __ Lsr(out, left, temp, LS);
6471 break; 6487 break;
6472 case Token::kSHL: 6488 case Token::kSHL:
6473 __ Lsl(out, left, temp, LS); 6489 __ Lsl(out, left, temp, LS);
6474 break; 6490 break;
6475 default: 6491 default:
6476 UNREACHABLE(); 6492 UNREACHABLE();
6477 } 6493 }
6478 } 6494 }
6479 6495
6480 6496
6481 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6497 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6482 bool opt) const { 6498 bool opt) const {
6483 const intptr_t kNumInputs = 1; 6499 const intptr_t kNumInputs = 1;
6484 const intptr_t kNumTemps = 0; 6500 const intptr_t kNumTemps = 0;
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
6872 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6888 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6873 #if defined(DEBUG) 6889 #if defined(DEBUG)
6874 __ LoadImmediate(R4, kInvalidObjectPointer); 6890 __ LoadImmediate(R4, kInvalidObjectPointer);
6875 __ LoadImmediate(R5, kInvalidObjectPointer); 6891 __ LoadImmediate(R5, kInvalidObjectPointer);
6876 #endif 6892 #endif
6877 } 6893 }
6878 6894
6879 } // namespace dart 6895 } // namespace dart
6880 6896
6881 #endif // defined TARGET_ARCH_ARM 6897 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698