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

Side by Side Diff: vm/intermediate_language_ia32.cc

Issue 10823228: Remove duplicate code for smi and double comparison from the compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 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
« no previous file with comments | « no previous file | vm/intermediate_language_x64.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 const intptr_t kNumTemps = 0; 250 const intptr_t kNumTemps = 0;
251 LocationSummary* locs = 251 LocationSummary* locs =
252 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 252 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
253 locs->set_in(0, Location::RegisterLocation(ECX)); 253 locs->set_in(0, Location::RegisterLocation(ECX));
254 locs->set_in(1, Location::RegisterLocation(EDX)); 254 locs->set_in(1, Location::RegisterLocation(EDX));
255 locs->set_out(Location::RegisterLocation(EAX)); 255 locs->set_out(Location::RegisterLocation(EAX));
256 return locs; 256 return locs;
257 } 257 }
258 258
259 259
260 // Optional integer arguments can often be null. Null is not collected
261 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well?
262 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
263 EqualityCompareComp* comp) {
264 Register left = comp->locs()->in(0).reg();
265 Register right = comp->locs()->in(1).reg();
266 Register temp = comp->locs()->temp(0).reg();
267 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
268 comp->token_pos(),
269 comp->try_index(),
270 kDeoptSmiCompareSmi,
271 left,
272 right);
273 __ movl(temp, left);
274 __ orl(temp, right);
275 __ testl(temp, Immediate(kSmiTagMask));
276 __ j(NOT_ZERO, deopt);
277 __ cmpl(left, right);
278 Register result = comp->locs()->out().reg();
279 Label load_true, done;
280 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump);
281 __ LoadObject(result, compiler->bool_false());
282 __ jmp(&done, Assembler::kNearJump);
283 __ Bind(&load_true);
284 __ LoadObject(result, compiler->bool_true());
285 __ Bind(&done);
286 }
287
288
289 // TODO(srdjan): Add support for mixed Smi/Double equality
290 // (see LoadDoubleOrSmiToXmm).
291 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler,
292 EqualityCompareComp* comp) {
293 Register left = comp->locs()->in(0).reg();
294 Register right = comp->locs()->in(1).reg();
295 Register temp = comp->locs()->temp(0).reg();
296 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
297 comp->token_pos(),
298 comp->try_index(),
299 kDeoptDoubleCompareDouble,
300 left,
301 right);
302 Label done, is_false, is_true;
303 __ CompareClassId(left, kDouble, temp);
304 __ j(NOT_EQUAL, deopt);
305 __ CompareClassId(right, kDouble, temp);
306 __ j(NOT_EQUAL, deopt);
307 __ movsd(XMM0, FieldAddress(left, Double::value_offset()));
308 __ movsd(XMM1, FieldAddress(right, Double::value_offset()));
309 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()),
310 XMM0, XMM1,
311 comp->locs()->out().reg());
312 }
313
314
315 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 260 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
316 EqualityCompareComp* comp) { 261 EqualityCompareComp* comp) {
317 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 262 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
318 comp->deopt_id(), 263 comp->deopt_id(),
319 comp->token_pos(), 264 comp->token_pos(),
320 comp->try_index()); 265 comp->try_index());
321 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 266 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
322 const int kNumberOfArguments = 2; 267 const int kNumberOfArguments = 2;
323 const Array& kNoArgumentNames = Array::Handle(); 268 const Array& kNoArgumentNames = Array::Handle();
324 const int kNumArgumentsChecked = 2; 269 const int kNumArgumentsChecked = 2;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 __ jmp(&done); 417 __ jmp(&done);
473 __ Bind(&non_null_compare); // Receiver is not null. 418 __ Bind(&non_null_compare); // Receiver is not null.
474 __ pushl(left); 419 __ pushl(left);
475 __ pushl(right); 420 __ pushl(right);
476 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 421 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
477 deopt_id, token_pos, try_index); 422 deopt_id, token_pos, try_index);
478 __ Bind(&done); 423 __ Bind(&done);
479 } 424 }
480 425
481 426
482 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
483 if (receiver_class_id() == kSmi) {
484 EmitSmiEqualityCompare(compiler, this);
485 return;
486 }
487 if (receiver_class_id() == kDouble) {
488 EmitDoubleEqualityCompare(compiler, this);
489 return;
490 }
491 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
492 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
493 deopt_id(), token_pos(), try_index());
494 } else {
495 Register left = locs()->in(0).reg();
496 Register right = locs()->in(1).reg();
497 __ pushl(left);
498 __ pushl(right);
499 EmitEqualityAsInstanceCall(compiler, this);
500 }
501 }
502
503
504 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
505 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) {
506 const intptr_t kNumInputs = 2;
507 const intptr_t kNumTemps = 1;
508 LocationSummary* summary =
509 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
510 summary->set_in(0, Location::RequiresRegister());
511 summary->set_in(1, Location::RequiresRegister());
512 summary->set_out(Location::RequiresRegister());
513 summary->set_temp(0, Location::RequiresRegister());
514 return summary;
515 }
516 ASSERT(operands_class_id() == kObject);
517 return MakeCallSummary();
518 }
519
520
521 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 427 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
522 const LocationSummary& locs, 428 const LocationSummary& locs,
523 Token::Kind kind, 429 Token::Kind kind,
524 BranchInstr* branch, 430 BranchInstr* branch,
525 intptr_t deopt_id, 431 intptr_t deopt_id,
526 intptr_t token_pos, 432 intptr_t token_pos,
527 intptr_t try_index) { 433 intptr_t try_index) {
528 Register left = locs.in(0).reg(); 434 Register left = locs.in(0).reg();
529 Register right = locs.in(1).reg(); 435 Register right = locs.in(1).reg();
530 Register temp = locs.temp(0).reg(); 436 Register temp = locs.temp(0).reg();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 if (branch != NULL) { 502 if (branch != NULL) {
597 compiler->EmitDoubleCompareBranch( 503 compiler->EmitDoubleCompareBranch(
598 true_condition, XMM0, XMM1, branch); 504 true_condition, XMM0, XMM1, branch);
599 } else { 505 } else {
600 compiler->EmitDoubleCompareBool( 506 compiler->EmitDoubleCompareBool(
601 true_condition, XMM0, XMM1, locs.out().reg()); 507 true_condition, XMM0, XMM1, locs.out().reg());
602 } 508 }
603 } 509 }
604 510
605 511
512 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
513 if (receiver_class_id() == kSmi) {
514 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
515 deopt_id(), token_pos(), try_index());
516 return;
517 }
518 if (receiver_class_id() == kDouble) {
519 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
520 deopt_id(), token_pos(), try_index());
521 return;
522 }
523 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
524 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
525 deopt_id(), token_pos(), try_index());
526 } else {
527 Register left = locs()->in(0).reg();
528 Register right = locs()->in(1).reg();
529 __ pushl(left);
530 __ pushl(right);
531 EmitEqualityAsInstanceCall(compiler, this);
532 }
533 }
534
535
536 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
537 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) {
538 const intptr_t kNumInputs = 2;
539 const intptr_t kNumTemps = 1;
540 LocationSummary* summary =
541 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
542 summary->set_in(0, Location::RequiresRegister());
543 summary->set_in(1, Location::RequiresRegister());
544 summary->set_out(Location::RequiresRegister());
545 summary->set_temp(0, Location::RequiresRegister());
546 return summary;
547 }
548 ASSERT(operands_class_id() == kObject);
549 return MakeCallSummary();
550 }
551
552
606 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 553 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
607 if (operands_class_id() == kSmi) { 554 if (operands_class_id() == kSmi) {
608 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 555 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
609 deopt_id(), token_pos(), try_index()); 556 deopt_id(), token_pos(), try_index());
610 return; 557 return;
611 } 558 }
612 if (operands_class_id() == kDouble) { 559 if (operands_class_id() == kDouble) {
613 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 560 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
614 deopt_id(), token_pos(), try_index()); 561 deopt_id(), token_pos(), try_index());
615 return; 562 return;
(...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 ASSERT(locs()->out().reg() == EAX); 2054 ASSERT(locs()->out().reg() == EAX);
2108 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2055 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2109 EmitBranchOnCondition(compiler, branch_condition); 2056 EmitBranchOnCondition(compiler, branch_condition);
2110 } 2057 }
2111 2058
2112 } // namespace dart 2059 } // namespace dart
2113 2060
2114 #undef __ 2061 #undef __
2115 2062
2116 #endif // defined TARGET_ARCH_X64 2063 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698