| OLD | NEW |
| 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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return OVERFLOW; | 234 return OVERFLOW; |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 | 238 |
| 239 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 239 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| 240 const intptr_t kNumInputs = 2; | 240 const intptr_t kNumInputs = 2; |
| 241 const bool is_checked_strict_equal = | 241 const bool is_checked_strict_equal = |
| 242 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); | 242 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
| 243 if ((receiver_class_id() == kSmiCid) || | 243 if ((receiver_class_id() == kSmiCid) || |
| 244 (receiver_class_id() == kDoubleCid) || | |
| 245 is_checked_strict_equal) { | 244 is_checked_strict_equal) { |
| 246 const intptr_t kNumTemps = 1; | 245 const intptr_t kNumTemps = 1; |
| 247 LocationSummary* locs = | 246 LocationSummary* locs = |
| 248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 249 locs->set_in(0, Location::RequiresRegister()); | 248 locs->set_in(0, Location::RequiresRegister()); |
| 250 locs->set_in(1, Location::RequiresRegister()); | 249 locs->set_in(1, Location::RequiresRegister()); |
| 251 locs->set_temp(0, Location::RequiresRegister()); | 250 locs->set_temp(0, Location::RequiresRegister()); |
| 252 locs->set_out(Location::RequiresRegister()); | 251 locs->set_out(Location::RequiresRegister()); |
| 253 return locs; | 252 return locs; |
| 254 } | 253 } |
| 254 if (receiver_class_id() == kDoubleCid) { |
| 255 const intptr_t kNumTemps = 2; |
| 256 LocationSummary* locs = |
| 257 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 258 locs->set_in(0, Location::RequiresRegister()); |
| 259 locs->set_in(1, Location::RequiresRegister()); |
| 260 locs->set_out(Location::RequiresRegister()); |
| 261 locs->set_temp(0, Location::RequiresRegister()); |
| 262 locs->set_temp(1, Location::XmmRegisterLocation(XMM1)); |
| 263 return locs; |
| 264 } |
| 255 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 265 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 256 const intptr_t kNumTemps = 1; | 266 const intptr_t kNumTemps = 1; |
| 257 LocationSummary* locs = | 267 LocationSummary* locs = |
| 258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 259 locs->set_in(0, Location::RegisterLocation(ECX)); | 269 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 260 locs->set_in(1, Location::RegisterLocation(EDX)); | 270 locs->set_in(1, Location::RegisterLocation(EDX)); |
| 261 locs->set_temp(0, Location::RegisterLocation(EBX)); | 271 locs->set_temp(0, Location::RegisterLocation(EBX)); |
| 262 locs->set_out(Location::RegisterLocation(EAX)); | 272 locs->set_out(Location::RegisterLocation(EAX)); |
| 263 return locs; | 273 return locs; |
| 264 } | 274 } |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 } | 533 } |
| 524 | 534 |
| 525 | 535 |
| 526 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 536 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
| 527 const LocationSummary& locs, | 537 const LocationSummary& locs, |
| 528 Token::Kind kind, | 538 Token::Kind kind, |
| 529 BranchInstr* branch, | 539 BranchInstr* branch, |
| 530 intptr_t deopt_id) { | 540 intptr_t deopt_id) { |
| 531 Register left = locs.in(0).reg(); | 541 Register left = locs.in(0).reg(); |
| 532 Register right = locs.in(1).reg(); | 542 Register right = locs.in(1).reg(); |
| 533 const bool left_is_smi = (branch == NULL) ? | |
| 534 false : (branch->computation()->left()->ResultCid() == kSmiCid); | |
| 535 const bool right_is_smi = (branch == NULL) ? | |
| 536 false : (branch->computation()->right()->ResultCid() == kSmiCid); | |
| 537 // TODO(fschneider): Move smi smi checks outside this instruction. | |
| 538 if (!left_is_smi || !right_is_smi) { | |
| 539 Register temp = locs.temp(0).reg(); | |
| 540 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptSmiCompareSmi); | |
| 541 __ movl(temp, left); | |
| 542 __ orl(temp, right); | |
| 543 __ testl(temp, Immediate(kSmiTagMask)); | |
| 544 __ j(NOT_ZERO, deopt); | |
| 545 } | |
| 546 | 543 |
| 547 Condition true_condition = TokenKindToSmiCondition(kind); | 544 Condition true_condition = TokenKindToSmiCondition(kind); |
| 548 __ cmpl(left, right); | 545 __ cmpl(left, right); |
| 549 | 546 |
| 550 if (branch != NULL) { | 547 if (branch != NULL) { |
| 551 branch->EmitBranchOnCondition(compiler, true_condition); | 548 branch->EmitBranchOnCondition(compiler, true_condition); |
| 552 } else { | 549 } else { |
| 553 Register result = locs.out().reg(); | 550 Register result = locs.out().reg(); |
| 554 Label done, is_true; | 551 Label done, is_true; |
| 555 __ j(true_condition, &is_true); | 552 __ j(true_condition, &is_true); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 Token::kEQ, // kNE reverse occurs at branch. | 667 Token::kEQ, // kNE reverse occurs at branch. |
| 671 locs()); | 668 locs()); |
| 672 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 669 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 673 __ CompareObject(EAX, compiler->bool_true()); | 670 __ CompareObject(EAX, compiler->bool_true()); |
| 674 branch->EmitBranchOnCondition(compiler, branch_condition); | 671 branch->EmitBranchOnCondition(compiler, branch_condition); |
| 675 } | 672 } |
| 676 | 673 |
| 677 | 674 |
| 678 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 675 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 679 const intptr_t kNumInputs = 2; | 676 const intptr_t kNumInputs = 2; |
| 680 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { | 677 if (operands_class_id() == kSmiCid) { |
| 681 const intptr_t kNumTemps = 1; | 678 const intptr_t kNumTemps = 1; |
| 682 LocationSummary* summary = | 679 LocationSummary* summary = |
| 683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 684 summary->set_in(0, Location::RequiresRegister()); | 681 summary->set_in(0, Location::RequiresRegister()); |
| 685 summary->set_in(1, Location::RequiresRegister()); | 682 summary->set_in(1, Location::RequiresRegister()); |
| 686 summary->set_out(Location::RequiresRegister()); | 683 summary->set_out(Location::RequiresRegister()); |
| 687 summary->set_temp(0, Location::RequiresRegister()); | 684 summary->set_temp(0, Location::RequiresRegister()); |
| 688 return summary; | 685 return summary; |
| 689 } | 686 } |
| 687 if (operands_class_id() == kDoubleCid) { |
| 688 const intptr_t kNumTemps = 2; |
| 689 LocationSummary* summary = |
| 690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 691 summary->set_in(0, Location::RequiresRegister()); |
| 692 summary->set_in(1, Location::RequiresRegister()); |
| 693 summary->set_out(Location::RequiresRegister()); |
| 694 summary->set_temp(0, Location::RequiresRegister()); |
| 695 summary->set_temp(1, Location::XmmRegisterLocation(XMM1)); |
| 696 return summary; |
| 697 } |
| 690 const intptr_t kNumTemps = 0; | 698 const intptr_t kNumTemps = 0; |
| 691 LocationSummary* locs = | 699 LocationSummary* locs = |
| 692 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 693 // Pick arbitrary fixed input registers because this is a call. | 701 // Pick arbitrary fixed input registers because this is a call. |
| 694 locs->set_in(0, Location::RegisterLocation(EAX)); | 702 locs->set_in(0, Location::RegisterLocation(EAX)); |
| 695 locs->set_in(1, Location::RegisterLocation(ECX)); | 703 locs->set_in(1, Location::RegisterLocation(ECX)); |
| 696 locs->set_out(Location::RegisterLocation(EAX)); | 704 locs->set_out(Location::RegisterLocation(EAX)); |
| 697 return locs; | 705 return locs; |
| 698 } | 706 } |
| 699 | 707 |
| (...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 } | 2217 } |
| 2210 __ j(ABOVE_EQUAL, deopt); | 2218 __ j(ABOVE_EQUAL, deopt); |
| 2211 } | 2219 } |
| 2212 | 2220 |
| 2213 | 2221 |
| 2214 } // namespace dart | 2222 } // namespace dart |
| 2215 | 2223 |
| 2216 #undef __ | 2224 #undef __ |
| 2217 | 2225 |
| 2218 #endif // defined TARGET_ARCH_X64 | 2226 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |