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

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 if (TargetCPUFeatures::arm_version() == ARMv7) {
6135 __ smull(out_lo, out_hi, left_lo, right_lo);
6136 if (can_overflow()) {
6137 __ TestImmediate(out_hi, 0xC0000000);
6138 __ b(deopt, NE);
6139 }
6140 } else {
6141 __ b(deopt);
6142 }
6143 break;
6144 }
6133 default: 6145 default:
6134 UNREACHABLE(); 6146 UNREACHABLE();
6135 break;
6136 } 6147 }
6137 if (FLAG_throw_on_javascript_int_overflow) { 6148 if (FLAG_throw_on_javascript_int_overflow) {
6138 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6149 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6139 } 6150 }
6140 } 6151 }
6141 6152
6142 6153
6143 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 6154 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
6144 bool opt) const { 6155 bool opt) const {
6145 const intptr_t kNumInputs = 2; 6156 const intptr_t kNumInputs = 2;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
6220 __ Asr(temp, temp, shift); 6231 __ Asr(temp, temp, shift);
6221 // Compare with high word from input. 6232 // Compare with high word from input.
6222 __ cmp(temp, Operand(left_hi)); 6233 __ cmp(temp, Operand(left_hi));
6223 // Overflow if they aren't equal. 6234 // Overflow if they aren't equal.
6224 __ b(deopt, NE); 6235 __ b(deopt, NE);
6225 } 6236 }
6226 break; 6237 break;
6227 } 6238 }
6228 default: 6239 default:
6229 UNREACHABLE(); 6240 UNREACHABLE();
6230 break;
6231 } 6241 }
6232 6242
6233 if (FLAG_throw_on_javascript_int_overflow) { 6243 if (FLAG_throw_on_javascript_int_overflow) {
6234 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6244 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6235 } 6245 }
6236 } 6246 }
6237 6247
6238 6248
6239 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 6249 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
6240 bool opt) const { 6250 bool opt) const {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6312 6322
6313 6323
6314 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6324 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6315 Register left = locs()->in(0).reg(); 6325 Register left = locs()->in(0).reg();
6316 Register right = locs()->in(1).reg(); 6326 Register right = locs()->in(1).reg();
6317 Register out = locs()->out(0).reg(); 6327 Register out = locs()->out(0).reg();
6318 ASSERT(out != left); 6328 ASSERT(out != left);
6319 switch (op_kind()) { 6329 switch (op_kind()) {
6320 case Token::kBIT_AND: 6330 case Token::kBIT_AND:
6321 __ and_(out, left, Operand(right)); 6331 __ and_(out, left, Operand(right));
6322 break; 6332 break;
6323 case Token::kBIT_OR: 6333 case Token::kBIT_OR:
6324 __ orr(out, left, Operand(right)); 6334 __ orr(out, left, Operand(right));
6325 break; 6335 break;
6326 case Token::kBIT_XOR: 6336 case Token::kBIT_XOR:
6327 __ eor(out, left, Operand(right)); 6337 __ eor(out, left, Operand(right));
6328 break; 6338 break;
6329 case Token::kADD: 6339 case Token::kADD:
6330 __ add(out, left, Operand(right)); 6340 __ add(out, left, Operand(right));
6331 break; 6341 break;
6332 case Token::kSUB: 6342 case Token::kSUB:
6333 __ sub(out, left, Operand(right)); 6343 __ sub(out, left, Operand(right));
6334 break; 6344 break;
6345 case Token::kMUL:
6346 __ mul(out, left, right);
6347 break;
6335 default: 6348 default:
6336 UNREACHABLE(); 6349 UNREACHABLE();
6337 } 6350 }
6338 } 6351 }
6339 6352
6340 6353
6341 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6354 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6342 bool opt) const { 6355 bool opt) const {
6343 const intptr_t kNumInputs = 2; 6356 const intptr_t kNumInputs = 2;
6344 const intptr_t kNumTemps = 1; 6357 const intptr_t kNumTemps = 1;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6378 // Invalid shift value. 6391 // Invalid shift value.
6379 __ b(deopt); 6392 __ b(deopt);
6380 } else if (shift_value > kShifterLimit) { 6393 } else if (shift_value > kShifterLimit) {
6381 // Result is 0. 6394 // Result is 0.
6382 __ eor(out, out, Operand(out)); 6395 __ eor(out, out, Operand(out));
6383 } else { 6396 } else {
6384 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). 6397 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6385 switch (op_kind()) { 6398 switch (op_kind()) {
6386 case Token::kSHR: 6399 case Token::kSHR:
6387 __ Lsr(out, left, shift_value); 6400 __ Lsr(out, left, shift_value);
6388 break; 6401 break;
6389 case Token::kSHL: 6402 case Token::kSHL:
6390 __ Lsl(out, left, shift_value); 6403 __ Lsl(out, left, shift_value);
6391 break; 6404 break;
6392 default: 6405 default:
6393 UNREACHABLE(); 6406 UNREACHABLE();
6394 } 6407 }
6395 } 6408 }
6396 return; 6409 return;
6397 } 6410 }
6398 6411
6399 // Non constant shift value. 6412 // Non constant shift value.
6400 6413
6401 Register shifter = locs()->in(1).reg(); 6414 Register shifter = locs()->in(1).reg();
6402 6415
6403 __ mov(temp, Operand(shifter)); 6416 __ mov(temp, Operand(shifter));
6404 __ SmiUntag(temp); 6417 __ SmiUntag(temp);
6405 __ CompareImmediate(temp, 0); 6418 __ CompareImmediate(temp, 0);
6406 // If shift value is < 0, deoptimize. 6419 // If shift value is < 0, deoptimize.
6407 __ b(deopt, LT); 6420 __ b(deopt, LT);
6408 __ CompareImmediate(temp, kShifterLimit); 6421 __ CompareImmediate(temp, kShifterLimit);
6409 // > kShifterLimit, result is 0. 6422 // > kShifterLimit, result is 0.
6410 __ eor(out, out, Operand(out), HI); 6423 __ eor(out, out, Operand(out), HI);
6411 // Do the shift. 6424 // Do the shift.
6412 switch (op_kind()) { 6425 switch (op_kind()) {
6413 case Token::kSHR: 6426 case Token::kSHR:
6414 __ Lsr(out, left, temp, LS); 6427 __ Lsr(out, left, temp, LS);
6415 break; 6428 break;
6416 case Token::kSHL: 6429 case Token::kSHL:
6417 __ Lsl(out, left, temp, LS); 6430 __ Lsl(out, left, temp, LS);
6418 break; 6431 break;
6419 default: 6432 default:
6420 UNREACHABLE(); 6433 UNREACHABLE();
6421 } 6434 }
6422 } 6435 }
6423 6436
6424 6437
6425 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6438 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6426 bool opt) const { 6439 bool opt) const {
6427 const intptr_t kNumInputs = 1; 6440 const intptr_t kNumInputs = 1;
6428 const intptr_t kNumTemps = 0; 6441 const intptr_t kNumTemps = 0;
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
6816 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6829 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6817 #if defined(DEBUG) 6830 #if defined(DEBUG)
6818 __ LoadImmediate(R4, kInvalidObjectPointer); 6831 __ LoadImmediate(R4, kInvalidObjectPointer);
6819 __ LoadImmediate(R5, kInvalidObjectPointer); 6832 __ LoadImmediate(R5, kInvalidObjectPointer);
6820 #endif 6833 #endif
6821 } 6834 }
6822 6835
6823 } // namespace dart 6836 } // namespace dart
6824 6837
6825 #endif // defined TARGET_ARCH_ARM 6838 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698