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

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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(regis): Range analysis may eliminate the deopt check.
6138 if (TargetCPUFeatures::arm_version() == ARMv7) {
6139 __ cmp(left_hi, Operand(left_lo, ASR, 31));
6140 __ cmp(right_hi, Operand(right_lo, ASR, 31), EQ);
6141 __ b(deopt, NE);
6142 __ smull(out_lo, out_hi, left_lo, right_lo);
6143 } else {
6144 __ b(deopt);
6145 }
6146 break;
6147 }
6133 default: 6148 default:
6134 UNREACHABLE(); 6149 UNREACHABLE();
6135 break;
6136 } 6150 }
6137 if (FLAG_throw_on_javascript_int_overflow) { 6151 if (FLAG_throw_on_javascript_int_overflow) {
6138 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6152 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6139 } 6153 }
6140 } 6154 }
6141 6155
6142 6156
6143 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 6157 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
6144 bool opt) const { 6158 bool opt) const {
6145 const intptr_t kNumInputs = 2; 6159 const intptr_t kNumInputs = 2;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
6368 6382
6369 6383
6370 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6384 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6371 Register left = locs()->in(0).reg(); 6385 Register left = locs()->in(0).reg();
6372 Register right = locs()->in(1).reg(); 6386 Register right = locs()->in(1).reg();
6373 Register out = locs()->out(0).reg(); 6387 Register out = locs()->out(0).reg();
6374 ASSERT(out != left); 6388 ASSERT(out != left);
6375 switch (op_kind()) { 6389 switch (op_kind()) {
6376 case Token::kBIT_AND: 6390 case Token::kBIT_AND:
6377 __ and_(out, left, Operand(right)); 6391 __ and_(out, left, Operand(right));
6378 break; 6392 break;
6379 case Token::kBIT_OR: 6393 case Token::kBIT_OR:
6380 __ orr(out, left, Operand(right)); 6394 __ orr(out, left, Operand(right));
6381 break; 6395 break;
6382 case Token::kBIT_XOR: 6396 case Token::kBIT_XOR:
6383 __ eor(out, left, Operand(right)); 6397 __ eor(out, left, Operand(right));
6384 break; 6398 break;
6385 case Token::kADD: 6399 case Token::kADD:
6386 __ add(out, left, Operand(right)); 6400 __ add(out, left, Operand(right));
6387 break; 6401 break;
6388 case Token::kSUB: 6402 case Token::kSUB:
6389 __ sub(out, left, Operand(right)); 6403 __ sub(out, left, Operand(right));
6390 break; 6404 break;
6405 case Token::kMUL:
6406 __ mul(out, left, right);
6407 break;
6391 default: 6408 default:
6392 UNREACHABLE(); 6409 UNREACHABLE();
6393 } 6410 }
6394 } 6411 }
6395 6412
6396 6413
6397 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6414 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6398 bool opt) const { 6415 bool opt) const {
6399 const intptr_t kNumInputs = 2; 6416 const intptr_t kNumInputs = 2;
6400 const intptr_t kNumTemps = 1; 6417 const intptr_t kNumTemps = 1;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6434 // Invalid shift value. 6451 // Invalid shift value.
6435 __ b(deopt); 6452 __ b(deopt);
6436 } else if (shift_value > kShifterLimit) { 6453 } else if (shift_value > kShifterLimit) {
6437 // Result is 0. 6454 // Result is 0.
6438 __ eor(out, out, Operand(out)); 6455 __ eor(out, out, Operand(out));
6439 } else { 6456 } else {
6440 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). 6457 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6441 switch (op_kind()) { 6458 switch (op_kind()) {
6442 case Token::kSHR: 6459 case Token::kSHR:
6443 __ Lsr(out, left, shift_value); 6460 __ Lsr(out, left, shift_value);
6444 break; 6461 break;
6445 case Token::kSHL: 6462 case Token::kSHL:
6446 __ Lsl(out, left, shift_value); 6463 __ Lsl(out, left, shift_value);
6447 break; 6464 break;
6448 default: 6465 default:
6449 UNREACHABLE(); 6466 UNREACHABLE();
6450 } 6467 }
6451 } 6468 }
6452 return; 6469 return;
6453 } 6470 }
6454 6471
6455 // Non constant shift value. 6472 // Non constant shift value.
6456 6473
6457 Register shifter = locs()->in(1).reg(); 6474 Register shifter = locs()->in(1).reg();
6458 6475
6459 __ mov(temp, Operand(shifter)); 6476 __ mov(temp, Operand(shifter));
6460 __ SmiUntag(temp); 6477 __ SmiUntag(temp);
6461 __ CompareImmediate(temp, 0); 6478 __ CompareImmediate(temp, 0);
6462 // If shift value is < 0, deoptimize. 6479 // If shift value is < 0, deoptimize.
6463 __ b(deopt, LT); 6480 __ b(deopt, LT);
6464 __ CompareImmediate(temp, kShifterLimit); 6481 __ CompareImmediate(temp, kShifterLimit);
6465 // > kShifterLimit, result is 0. 6482 // > kShifterLimit, result is 0.
6466 __ eor(out, out, Operand(out), HI); 6483 __ eor(out, out, Operand(out), HI);
6467 // Do the shift. 6484 // Do the shift.
6468 switch (op_kind()) { 6485 switch (op_kind()) {
6469 case Token::kSHR: 6486 case Token::kSHR:
6470 __ Lsr(out, left, temp, LS); 6487 __ Lsr(out, left, temp, LS);
6471 break; 6488 break;
6472 case Token::kSHL: 6489 case Token::kSHL:
6473 __ Lsl(out, left, temp, LS); 6490 __ Lsl(out, left, temp, LS);
6474 break; 6491 break;
6475 default: 6492 default:
6476 UNREACHABLE(); 6493 UNREACHABLE();
6477 } 6494 }
6478 } 6495 }
6479 6496
6480 6497
6481 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6498 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6482 bool opt) const { 6499 bool opt) const {
6483 const intptr_t kNumInputs = 1; 6500 const intptr_t kNumInputs = 1;
6484 const intptr_t kNumTemps = 0; 6501 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()); 6889 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6873 #if defined(DEBUG) 6890 #if defined(DEBUG)
6874 __ LoadImmediate(R4, kInvalidObjectPointer); 6891 __ LoadImmediate(R4, kInvalidObjectPointer);
6875 __ LoadImmediate(R5, kInvalidObjectPointer); 6892 __ LoadImmediate(R5, kInvalidObjectPointer);
6876 #endif 6893 #endif
6877 } 6894 }
6878 6895
6879 } // namespace dart 6896 } // namespace dart
6880 6897
6881 #endif // defined TARGET_ARCH_ARM 6898 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698