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

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

Issue 61123003: Inline integer modulo operation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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_arm.cc ('k') | runtime/vm/intermediate_language_mips.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 2288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 summary->set_out(Location::SameAsFirstInput()); 2299 summary->set_out(Location::SameAsFirstInput());
2300 } else { 2300 } else {
2301 // Both inputs must be writable because they will be untagged. 2301 // Both inputs must be writable because they will be untagged.
2302 summary->set_in(0, Location::RegisterLocation(EAX)); 2302 summary->set_in(0, Location::RegisterLocation(EAX));
2303 summary->set_in(1, Location::WritableRegister()); 2303 summary->set_in(1, Location::WritableRegister());
2304 summary->set_out(Location::SameAsFirstInput()); 2304 summary->set_out(Location::SameAsFirstInput());
2305 // Will be used for sign extension and division. 2305 // Will be used for sign extension and division.
2306 summary->set_temp(0, Location::RegisterLocation(EDX)); 2306 summary->set_temp(0, Location::RegisterLocation(EDX));
2307 } 2307 }
2308 return summary; 2308 return summary;
2309 } else if (op_kind() == Token::kMOD) {
2310 const intptr_t kNumTemps = 1;
2311 LocationSummary* summary =
2312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2313 // Both inputs must be writable because they will be untagged.
2314 summary->set_in(0, Location::RegisterLocation(EDX));
2315 summary->set_in(1, Location::WritableRegister());
2316 summary->set_out(Location::SameAsFirstInput());
2317 // Will be used for sign extension and division.
2318 summary->set_temp(0, Location::RegisterLocation(EAX));
2319 return summary;
2309 } else if (op_kind() == Token::kSHR) { 2320 } else if (op_kind() == Token::kSHR) {
2310 const intptr_t kNumTemps = 0; 2321 const intptr_t kNumTemps = 0;
2311 LocationSummary* summary = 2322 LocationSummary* summary =
2312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2323 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2313 summary->set_in(0, Location::RequiresRegister()); 2324 summary->set_in(0, Location::RequiresRegister());
2314 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); 2325 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
2315 summary->set_out(Location::SameAsFirstInput()); 2326 summary->set_out(Location::SameAsFirstInput());
2316 return summary; 2327 return summary;
2317 } else if (op_kind() == Token::kSHL) { 2328 } else if (op_kind() == Token::kSHL) {
2318 const intptr_t kNumTemps = 0; 2329 const intptr_t kNumTemps = 0;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 __ SmiUntag(right); 2555 __ SmiUntag(right);
2545 __ cdq(); // Sign extend EAX -> EDX:EAX. 2556 __ cdq(); // Sign extend EAX -> EDX:EAX.
2546 __ idivl(right); // EAX: quotient, EDX: remainder. 2557 __ idivl(right); // EAX: quotient, EDX: remainder.
2547 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2558 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2548 // case we cannot tag the result. 2559 // case we cannot tag the result.
2549 __ cmpl(result, Immediate(0x40000000)); 2560 __ cmpl(result, Immediate(0x40000000));
2550 __ j(EQUAL, deopt); 2561 __ j(EQUAL, deopt);
2551 __ SmiTag(result); 2562 __ SmiTag(result);
2552 break; 2563 break;
2553 } 2564 }
2565 case Token::kMOD: {
2566 // Handle divide by zero in runtime.
2567 __ testl(right, right);
2568 __ j(ZERO, deopt);
2569 ASSERT(left == EDX);
2570 ASSERT((right != EDX) && (right != EAX));
2571 ASSERT(locs()->temp(0).reg() == EAX);
2572 ASSERT(result == EDX);
2573 __ SmiUntag(left);
2574 __ SmiUntag(right);
2575 __ movl(EAX, EDX);
2576 __ cdq(); // Sign extend EAX -> EDX:EAX.
2577 __ idivl(right); // EAX: quotient, EDX: remainder.
2578 // res = left % right;
2579 // if (res < 0) {
2580 // if (right < 0) {
2581 // res = res - right;
2582 // } else {
2583 // res = res + right;
2584 // }
2585 // }
2586 Label subtract, done;
2587 __ cmpl(result, Immediate(0));
2588 __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
2589 // Result is negative, adjust it.
2590 __ cmpl(right, Immediate(0));
2591 __ j(LESS, &subtract, Assembler::kNearJump);
2592 __ addl(result, right);
2593 __ jmp(&done, Assembler::kNearJump);
2594 __ Bind(&subtract);
2595 __ subl(result, right);
2596 __ Bind(&done);
2597 __ SmiTag(result);
2598 break;
2599 }
2554 case Token::kSHR: { 2600 case Token::kSHR: {
2555 if (CanDeoptimize()) { 2601 if (CanDeoptimize()) {
2556 __ cmpl(right, Immediate(0)); 2602 __ cmpl(right, Immediate(0));
2557 __ j(LESS, deopt); 2603 __ j(LESS, deopt);
2558 } 2604 }
2559 __ SmiUntag(right); 2605 __ SmiUntag(right);
2560 // sarl operation masks the count to 5 bits. 2606 // sarl operation masks the count to 5 bits.
2561 const intptr_t kCountLimit = 0x1F; 2607 const intptr_t kCountLimit = 0x1F;
2562 Range* right_range = this->right()->definition()->range(); 2608 Range* right_range = this->right()->definition()->range();
2563 if ((right_range == NULL) || 2609 if ((right_range == NULL) ||
2564 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 2610 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2565 __ cmpl(right, Immediate(kCountLimit)); 2611 __ cmpl(right, Immediate(kCountLimit));
2566 Label count_ok; 2612 Label count_ok;
2567 __ j(LESS, &count_ok, Assembler::kNearJump); 2613 __ j(LESS, &count_ok, Assembler::kNearJump);
2568 __ movl(right, Immediate(kCountLimit)); 2614 __ movl(right, Immediate(kCountLimit));
2569 __ Bind(&count_ok); 2615 __ Bind(&count_ok);
2570 } 2616 }
2571 ASSERT(right == ECX); // Count must be in ECX 2617 ASSERT(right == ECX); // Count must be in ECX
2572 __ SmiUntag(left); 2618 __ SmiUntag(left);
2573 __ sarl(left, right); 2619 __ sarl(left, right);
2574 __ SmiTag(left); 2620 __ SmiTag(left);
2575 break; 2621 break;
2576 } 2622 }
2577 case Token::kDIV: { 2623 case Token::kDIV: {
2578 // Dispatches to 'Double./'. 2624 // Dispatches to 'Double./'.
2579 // TODO(srdjan): Implement as conversion to double and double division. 2625 // TODO(srdjan): Implement as conversion to double and double division.
2580 UNREACHABLE(); 2626 UNREACHABLE();
2581 break; 2627 break;
2582 } 2628 }
2583 case Token::kMOD: {
2584 // TODO(srdjan): Implement.
2585 UNREACHABLE();
2586 break;
2587 }
2588 case Token::kOR: 2629 case Token::kOR:
2589 case Token::kAND: { 2630 case Token::kAND: {
2590 // Flow graph builder has dissected this operation to guarantee correct 2631 // Flow graph builder has dissected this operation to guarantee correct
2591 // behavior (short-circuit evaluation). 2632 // behavior (short-circuit evaluation).
2592 UNREACHABLE(); 2633 UNREACHABLE();
2593 break; 2634 break;
2594 } 2635 }
2595 default: 2636 default:
2596 UNREACHABLE(); 2637 UNREACHABLE();
2597 break; 2638 break;
(...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after
4952 PcDescriptors::kOther, 4993 PcDescriptors::kOther,
4953 locs()); 4994 locs());
4954 __ Drop(2); // Discard type arguments and receiver. 4995 __ Drop(2); // Discard type arguments and receiver.
4955 } 4996 }
4956 4997
4957 } // namespace dart 4998 } // namespace dart
4958 4999
4959 #undef __ 5000 #undef __
4960 5001
4961 #endif // defined TARGET_ARCH_IA32 5002 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698