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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language_x64.cc
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index afac01fb721262d969ad6a0cda78dfc1d0e6aac5..2dfed3a9f7a38f8d232f285840684f8209e2eb74 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2328,13 +2328,40 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
break;
}
case Token::kTRUNCDIV: {
- // Handle divide by zero in runtime.
- __ testq(right, right);
- __ j(ZERO, deopt);
+ Label not_32bit, done;
+
+ Register temp = locs()->temp(0).reg();
ASSERT(left == RAX);
ASSERT((right != RDX) && (right != RAX));
- ASSERT(locs()->temp(0).reg() == RDX);
+ ASSERT(temp == RDX);
ASSERT(result == RAX);
+
+ // Handle divide by zero in runtime.
+ __ testq(right, right);
+ __ j(ZERO, deopt);
+
+ // Check if both operands fit into 32bits as idiv with 64bit operands
+ // requires twice as many cycles and has much higher latency.
+ // We are checking this before untagging them to avoid corner case
+ // dividing INT_MAX by -1 that raises exception because quotient is
+ // too large for 32bit register.
+ __ movsxl(temp, left);
+ __ cmpq(temp, left);
+ __ j(NOT_EQUAL, &not_32bit);
+ __ movsxl(temp, right);
+ __ cmpq(temp, right);
+ __ j(NOT_EQUAL, &not_32bit);
+
+ // Both operands are 31bit smis. Divide using 32bit idiv.
+ __ SmiUntag(left);
+ __ SmiUntag(right);
+ __ cdq();
+ __ idivl(right);
+ __ movsxl(result, result);
+ __ jmp(&done);
+
+ // Divide using 64bit idiv.
+ __ Bind(&not_32bit);
__ SmiUntag(left);
__ SmiUntag(right);
__ cqo(); // Sign extend RAX -> RDX:RAX.
@@ -2343,6 +2370,7 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// case we cannot tag the result.
__ cmpq(result, Immediate(0x4000000000000000));
__ j(EQUAL, deopt);
+ __ Bind(&done);
__ SmiTag(result);
break;
}

Powered by Google App Engine
This is Rietveld 408576698