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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 11344011: Relational comparisons for unboxed mints. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: better test coverage Created 8 years, 2 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_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 14174)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -645,8 +645,12 @@
switch (kind) {
case Token::kEQ: return EQUAL;
case Token::kNE: return NOT_EQUAL;
+ case Token::kLT: return LESS;
+ case Token::kGT: return GREATER;
+ case Token::kLTE: return LESS_EQUAL;
+ case Token::kGTE: return GREATER_EQUAL;
default:
- UNIMPLEMENTED();
+ UNREACHABLE();
return OVERFLOW;
}
}
@@ -682,6 +686,71 @@
}
+static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchInstr* branch) {
srdjan 2012/10/29 19:30:25 Isn't it slower to unbox Mint's for comparison, vs
Florian Schneider 2012/10/30 12:09:04 Yes, in the worst cast where we have two boxed min
+ XmmRegister left = locs.in(0).xmm_reg();
+ XmmRegister right = locs.in(1).xmm_reg();
+ Register left_tmp = locs.temp(0).reg();
+ Register right_tmp = locs.temp(1).reg();
+ Register result = branch == NULL ? locs.out().reg() : kNoRegister;
+
+ Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW;
+ switch (kind) {
+ case Token::kLT:
+ hi_cond = LESS;
+ lo_cond = BELOW;
+ break;
+ case Token::kGT:
+ hi_cond = GREATER;
+ lo_cond = ABOVE;
+ break;
+ case Token::kLTE:
+ hi_cond = LESS;
+ lo_cond = BELOW_EQUAL;
+ break;
+ case Token::kGTE:
+ hi_cond = GREATER;
+ lo_cond = ABOVE_EQUAL;
+ break;
+ default:
+ break;
+ }
+ ASSERT(hi_cond != OVERFLOW && lo_cond != OVERFLOW);
+ Label is_true, is_false;
+ // Compare upper halves first.
+ __ pextrd(left_tmp, left, Immediate(1));
+ __ pextrd(right_tmp, right, Immediate(1));
+ __ cmpl(left_tmp, right_tmp);
+ if (branch != NULL) {
+ __ j(hi_cond, compiler->GetBlockLabel(branch->true_successor()));
+ __ j(FlowGraphCompiler::FlipCondition(hi_cond),
+ compiler->GetBlockLabel(branch->false_successor()));
+ } else {
+ __ j(hi_cond, &is_true);
+ __ j(FlowGraphCompiler::FlipCondition(hi_cond), &is_false);
+ }
+
+ // If upper is equal, compare lower half.
+ __ pextrd(left_tmp, left, Immediate(0));
+ __ pextrd(right_tmp, right, Immediate(0));
+ __ cmpl(left_tmp, right_tmp);
+ if (branch != NULL) {
+ branch->EmitBranchOnCondition(compiler, lo_cond);
+ } else {
+ Label done;
+ __ j(lo_cond, &is_true);
+ __ Bind(&is_false);
+ __ LoadObject(result, compiler->bool_false());
+ __ jmp(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, compiler->bool_true());
+ __ Bind(&done);
+ }
+}
+
+
static Condition TokenKindToDoubleCondition(Token::Kind kind) {
switch (kind) {
case Token::kEQ: return EQUAL;
@@ -801,6 +870,17 @@
LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
const intptr_t kNumTemps = 0;
+ if (operands_class_id() == kMintCid) {
+ const intptr_t kNumTemps = 2;
+ LocationSummary* locs =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RequiresXmmRegister());
+ locs->set_in(1, Location::RequiresXmmRegister());
+ locs->set_temp(0, Location::RequiresRegister());
+ locs->set_temp(1, Location::RequiresRegister());
+ locs->set_out(Location::RequiresRegister());
+ return locs;
+ }
if (operands_class_id() == kDoubleCid) {
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -831,6 +911,10 @@
EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
return;
}
+ if (operands_class_id() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
+ return;
+ }
if (operands_class_id() == kDoubleCid) {
EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
return;
@@ -890,6 +974,10 @@
EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
return;
}
+ if (operands_class_id() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
+ return;
+ }
if (operands_class_id() == kDoubleCid) {
EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
return;
@@ -2444,8 +2532,8 @@
Label* deopt = compiler->AddDeoptStub(deopt_id(),
kDeoptBinaryMintOp);
Label done, overflow;
- __ pextrd(lo, right, Immediate(0)); // Lower half left
- __ pextrd(hi, right, Immediate(1)); // Upper half left
+ __ pextrd(lo, right, Immediate(0)); // Lower half
+ __ pextrd(hi, right, Immediate(1)); // Upper half
__ subl(ESP, Immediate(2 * kWordSize));
__ movq(Address(ESP, 0), left);
if (op_kind() == Token::kADD) {

Powered by Google App Engine
This is Rietveld 408576698