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

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

Issue 12545067: On x64 use 32bit idiv when possible instead of 64bit one. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix optimized pattern for kTRUNCDIV as well Created 7 years, 8 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 2310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2321 // No overflow check. 2321 // No overflow check.
2322 __ orq(left, right); 2322 __ orq(left, right);
2323 break; 2323 break;
2324 } 2324 }
2325 case Token::kBIT_XOR: { 2325 case Token::kBIT_XOR: {
2326 // No overflow check. 2326 // No overflow check.
2327 __ xorq(left, right); 2327 __ xorq(left, right);
2328 break; 2328 break;
2329 } 2329 }
2330 case Token::kTRUNCDIV: { 2330 case Token::kTRUNCDIV: {
2331 Label not_32bit, done;
2332
2333 Register temp = locs()->temp(0).reg();
2334 ASSERT(left == RAX);
2335 ASSERT((right != RDX) && (right != RAX));
2336 ASSERT(temp == RDX);
2337 ASSERT(result == RAX);
2338
2331 // Handle divide by zero in runtime. 2339 // Handle divide by zero in runtime.
2332 __ testq(right, right); 2340 __ testq(right, right);
2333 __ j(ZERO, deopt); 2341 __ j(ZERO, deopt);
2334 ASSERT(left == RAX); 2342
2335 ASSERT((right != RDX) && (right != RAX)); 2343 // Check if both operands fit into 32bits as idiv with 64bit operands
2336 ASSERT(locs()->temp(0).reg() == RDX); 2344 // requires twice as many cycles and has much higher latency.
2337 ASSERT(result == RAX); 2345 // We are checking this before untagging them to avoid corner case
2346 // dividing INT_MAX by -1 that raises exception because quotient is
2347 // too large for 32bit register.
2348 __ movsxl(temp, left);
2349 __ cmpq(temp, left);
2350 __ j(NOT_EQUAL, &not_32bit);
2351 __ movsxl(temp, right);
2352 __ cmpq(temp, right);
2353 __ j(NOT_EQUAL, &not_32bit);
2354
2355 // Both operands are 31bit smis. Divide using 32bit idiv.
2356 __ SmiUntag(left);
2357 __ SmiUntag(right);
2358 __ cdq();
2359 __ idivl(right);
2360 __ movsxl(result, result);
2361 __ jmp(&done);
2362
2363 // Divide using 64bit idiv.
2364 __ Bind(&not_32bit);
2338 __ SmiUntag(left); 2365 __ SmiUntag(left);
2339 __ SmiUntag(right); 2366 __ SmiUntag(right);
2340 __ cqo(); // Sign extend RAX -> RDX:RAX. 2367 __ cqo(); // Sign extend RAX -> RDX:RAX.
2341 __ idivq(right); // RAX: quotient, RDX: remainder. 2368 __ idivq(right); // RAX: quotient, RDX: remainder.
2342 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2369 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2343 // case we cannot tag the result. 2370 // case we cannot tag the result.
2344 __ cmpq(result, Immediate(0x4000000000000000)); 2371 __ cmpq(result, Immediate(0x4000000000000000));
2345 __ j(EQUAL, deopt); 2372 __ j(EQUAL, deopt);
2373 __ Bind(&done);
2346 __ SmiTag(result); 2374 __ SmiTag(result);
2347 break; 2375 break;
2348 } 2376 }
2349 case Token::kSHR: { 2377 case Token::kSHR: {
2350 if (CanDeoptimize()) { 2378 if (CanDeoptimize()) {
2351 __ cmpq(right, Immediate(0)); 2379 __ cmpq(right, Immediate(0));
2352 __ j(LESS, deopt); 2380 __ j(LESS, deopt);
2353 } 2381 }
2354 __ SmiUntag(right); 2382 __ SmiUntag(right);
2355 // sarq operation masks the count to 6 bits. 2383 // sarq operation masks the count to 6 bits.
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
3329 PcDescriptors::kOther, 3357 PcDescriptors::kOther,
3330 locs()); 3358 locs());
3331 __ Drop(2); // Discard type arguments and receiver. 3359 __ Drop(2); // Discard type arguments and receiver.
3332 } 3360 }
3333 3361
3334 } // namespace dart 3362 } // namespace dart
3335 3363
3336 #undef __ 3364 #undef __
3337 3365
3338 #endif // defined TARGET_ARCH_X64 3366 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698