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

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

Issue 11362210: Restrict immediate operands to smi where only smis are supported. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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) 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_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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 locs->set_in(0, Location::RequiresXmmRegister()); 275 locs->set_in(0, Location::RequiresXmmRegister());
276 locs->set_in(1, Location::RequiresXmmRegister()); 276 locs->set_in(1, Location::RequiresXmmRegister());
277 locs->set_out(Location::RequiresRegister()); 277 locs->set_out(Location::RequiresRegister());
278 return locs; 278 return locs;
279 } 279 }
280 if (receiver_class_id() == kSmiCid) { 280 if (receiver_class_id() == kSmiCid) {
281 const intptr_t kNumTemps = 0; 281 const intptr_t kNumTemps = 0;
282 LocationSummary* locs = 282 LocationSummary* locs =
283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
284 locs->set_in(0, Location::RegisterOrConstant(left())); 284 locs->set_in(0, Location::RegisterOrConstant(left()));
285 locs->set_in(1, Location::RegisterOrConstant(right())); 285 // Only one input can be a constant operand.
286 locs->set_in(1, locs->in(0).IsConstant()
287 ? Location::RequiresRegister()
288 : Location::RegisterOrConstant(right()));
286 locs->set_out(Location::RequiresRegister()); 289 locs->set_out(Location::RequiresRegister());
287 return locs; 290 return locs;
288 } 291 }
289 if (is_checked_strict_equal) { 292 if (is_checked_strict_equal) {
290 const intptr_t kNumTemps = 1; 293 const intptr_t kNumTemps = 1;
291 LocationSummary* locs = 294 LocationSummary* locs =
292 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 295 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
293 locs->set_in(0, Location::RequiresRegister()); 296 locs->set_in(0, Location::RequiresRegister());
294 locs->set_in(1, Location::RequiresRegister()); 297 locs->set_in(1, Location::RequiresRegister());
295 locs->set_temp(0, Location::RequiresRegister()); 298 locs->set_temp(0, Location::RequiresRegister());
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 __ Bind(&done); 603 __ Bind(&done);
601 } 604 }
602 605
603 606
604 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 607 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
605 const LocationSummary& locs, 608 const LocationSummary& locs,
606 Token::Kind kind, 609 Token::Kind kind,
607 BranchInstr* branch) { 610 BranchInstr* branch) {
608 Location left = locs.in(0); 611 Location left = locs.in(0);
609 Location right = locs.in(1); 612 Location right = locs.in(1);
613 ASSERT(!left.IsConstant() || !right.IsConstant());
610 614
611 Condition true_condition = TokenKindToSmiCondition(kind); 615 Condition true_condition = TokenKindToSmiCondition(kind);
612 616
613 if (left.IsConstant() && right.IsConstant()) {
614 bool result = false;
615 // One of them could be NULL (for equality only).
616 if (left.constant().IsNull() || right.constant().IsNull()) {
617 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
618 result = left.constant().IsNull() && right.constant().IsNull();
619 if (kind == Token::kNE) {
620 result = !result;
621 }
622 } else {
623 // TODO(vegorov): should be eliminated earlier by constant propagation.
624 result = FlowGraphCompiler::EvaluateCondition(
625 true_condition,
626 Smi::Cast(left.constant()).Value(),
627 Smi::Cast(right.constant()).Value());
628 }
629
630 if (branch != NULL) {
631 branch->EmitBranchOnValue(compiler, result);
632 } else {
633 __ LoadObject(locs.out().reg(), result ? compiler->bool_true()
634 : compiler->bool_false());
635 }
636
637 return;
638 }
639
640 if (left.IsConstant()) { 617 if (left.IsConstant()) {
641 __ CompareObject(right.reg(), left.constant()); 618 __ CompareObject(right.reg(), left.constant());
642 true_condition = FlowGraphCompiler::FlipCondition(true_condition); 619 true_condition = FlowGraphCompiler::FlipCondition(true_condition);
643 } else if (right.IsConstant()) { 620 } else if (right.IsConstant()) {
644 __ CompareObject(left.reg(), right.constant()); 621 __ CompareObject(left.reg(), right.constant());
645 } else { 622 } else {
646 __ cmpq(left.reg(), right.reg()); 623 __ cmpq(left.reg(), right.reg());
647 } 624 }
648 625
649 if (branch != NULL) { 626 if (branch != NULL) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 LocationSummary* summary = 761 LocationSummary* summary =
785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 762 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
786 summary->set_in(0, Location::RequiresXmmRegister()); 763 summary->set_in(0, Location::RequiresXmmRegister());
787 summary->set_in(1, Location::RequiresXmmRegister()); 764 summary->set_in(1, Location::RequiresXmmRegister());
788 summary->set_out(Location::RequiresRegister()); 765 summary->set_out(Location::RequiresRegister());
789 return summary; 766 return summary;
790 } else if (operands_class_id() == kSmiCid) { 767 } else if (operands_class_id() == kSmiCid) {
791 LocationSummary* summary = 768 LocationSummary* summary =
792 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
793 summary->set_in(0, Location::RegisterOrConstant(left())); 770 summary->set_in(0, Location::RegisterOrConstant(left()));
794 summary->set_in(1, Location::RegisterOrConstant(right())); 771 // Only one input can be a constant operand.
772 summary->set_in(1, summary->in(0).IsConstant()
773 ? Location::RequiresRegister()
774 : Location::RegisterOrConstant(right()));
795 summary->set_out(Location::RequiresRegister()); 775 summary->set_out(Location::RequiresRegister());
796 return summary; 776 return summary;
797 } 777 }
798 LocationSummary* locs = 778 LocationSummary* locs =
799 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 779 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
800 // Pick arbitrary fixed input registers because this is a call. 780 // Pick arbitrary fixed input registers because this is a call.
801 locs->set_in(0, Location::RegisterLocation(RAX)); 781 locs->set_in(0, Location::RegisterLocation(RAX));
802 locs->set_in(1, Location::RegisterLocation(RCX)); 782 locs->set_in(1, Location::RegisterLocation(RCX));
803 locs->set_out(Location::RegisterLocation(RAX)); 783 locs->set_out(Location::RegisterLocation(RAX));
804 return locs; 784 return locs;
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 summary->set_temp(0, Location::RegisterLocation(RBX)); 1570 summary->set_temp(0, Location::RegisterLocation(RBX));
1591 // Will be used for for sign extension. 1571 // Will be used for for sign extension.
1592 summary->set_temp(1, Location::RegisterLocation(RDX)); 1572 summary->set_temp(1, Location::RegisterLocation(RDX));
1593 summary->set_temp(2, Location::RequiresRegister()); 1573 summary->set_temp(2, Location::RequiresRegister());
1594 return summary; 1574 return summary;
1595 } else if (op_kind() == Token::kSHR) { 1575 } else if (op_kind() == Token::kSHR) {
1596 const intptr_t kNumTemps = 0; 1576 const intptr_t kNumTemps = 0;
1597 LocationSummary* summary = 1577 LocationSummary* summary =
1598 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1599 summary->set_in(0, Location::RequiresRegister()); 1579 summary->set_in(0, Location::RequiresRegister());
1600 summary->set_in(1, Location::RegisterLocation(RCX)); 1580 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
1601 summary->set_out(Location::SameAsFirstInput()); 1581 summary->set_out(Location::SameAsFirstInput());
1602 return summary; 1582 return summary;
1603 } else if (op_kind() == Token::kSHL) { 1583 } else if (op_kind() == Token::kSHL) {
1604 const intptr_t kNumTemps = 1; 1584 const intptr_t kNumTemps = 1;
1605 LocationSummary* summary = 1585 LocationSummary* summary =
1606 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1607 summary->set_in(0, Location::RequiresRegister()); 1587 summary->set_in(0, Location::RequiresRegister());
1608 summary->set_in(1, Location::FixedRegisterOrConstant(right(), RCX)); 1588 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
1609 summary->set_temp(0, Location::RequiresRegister()); 1589 summary->set_temp(0, Location::RequiresRegister());
1610 summary->set_out(Location::SameAsFirstInput()); 1590 summary->set_out(Location::SameAsFirstInput());
1611 return summary; 1591 return summary;
1612 } else { 1592 } else {
1613 const intptr_t kNumTemps = 0; 1593 const intptr_t kNumTemps = 0;
1614 LocationSummary* summary = 1594 LocationSummary* summary =
1615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1595 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1616 summary->set_in(0, Location::RequiresRegister()); 1596 summary->set_in(0, Location::RequiresRegister());
1617 summary->set_in(1, Location::RequiresRegister()); 1597 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
1618 summary->set_out(Location::SameAsFirstInput()); 1598 summary->set_out(Location::SameAsFirstInput());
1619 return summary; 1599 return summary;
1620 } 1600 }
1621 } 1601 }
1622 1602
1623 1603
1624 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1604 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1625 Register left = locs()->in(0).reg(); 1605 Register left = locs()->in(0).reg();
1626 Register result = locs()->out().reg(); 1606 Register result = locs()->out().reg();
1627 ASSERT(left == result); 1607 ASSERT(left == result);
(...skipping 12 matching lines...) Expand all
1640 case Token::kADD: { 1620 case Token::kADD: {
1641 __ addq(left, Immediate(imm)); 1621 __ addq(left, Immediate(imm));
1642 if (deopt != NULL) __ j(OVERFLOW, deopt); 1622 if (deopt != NULL) __ j(OVERFLOW, deopt);
1643 break; 1623 break;
1644 } 1624 }
1645 case Token::kSUB: { 1625 case Token::kSUB: {
1646 __ subq(left, Immediate(imm)); 1626 __ subq(left, Immediate(imm));
1647 if (deopt != NULL) __ j(OVERFLOW, deopt); 1627 if (deopt != NULL) __ j(OVERFLOW, deopt);
1648 break; 1628 break;
1649 } 1629 }
1630 case Token::kMUL: {
1631 // Keep left value tagged and untag right value.
1632 const intptr_t value = Smi::Cast(constant).Value();
1633 __ imulq(left, Immediate(value));
1634 if (deopt != NULL) __ j(OVERFLOW, deopt);
1635 break;
1636 }
1650 case Token::kBIT_AND: { 1637 case Token::kBIT_AND: {
1651 // No overflow check. 1638 // No overflow check.
1652 __ andq(left, Immediate(imm)); 1639 __ andq(left, Immediate(imm));
1653 break; 1640 break;
1654 } 1641 }
1655 case Token::kBIT_OR: { 1642 case Token::kBIT_OR: {
1656 // No overflow check. 1643 // No overflow check.
1657 __ orq(left, Immediate(imm)); 1644 __ orq(left, Immediate(imm));
1658 break; 1645 break;
1659 } 1646 }
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
2240 __ testq(value, Immediate(kSmiTagMask)); 2227 __ testq(value, Immediate(kSmiTagMask));
2241 __ j(NOT_ZERO, deopt); 2228 __ j(NOT_ZERO, deopt);
2242 } 2229 }
2243 2230
2244 2231
2245 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 2232 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
2246 const intptr_t kNumInputs = 2; 2233 const intptr_t kNumInputs = 2;
2247 const intptr_t kNumTemps = 0; 2234 const intptr_t kNumTemps = 0;
2248 LocationSummary* locs = 2235 LocationSummary* locs =
2249 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2236 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2250 locs->set_in(0, Location::RequiresRegister()); 2237 locs->set_in(0, Location::RegisterOrSmiConstant(array()));
2251 locs->set_in(1, Location::RegisterOrConstant(index())); 2238 locs->set_in(1, Location::RegisterOrSmiConstant(index()));
2252 return locs; 2239 return locs;
2253 } 2240 }
2254 2241
2255 2242
2256 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2243 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2257 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2244 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2258 kDeoptCheckArrayBound); 2245 kDeoptCheckArrayBound);
2259 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) { 2246 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) {
2260 // Unconditionally deoptimize for constant bounds checks because they 2247 // Unconditionally deoptimize for constant bounds checks because they
2261 // only occur only when index is out-of-bounds. 2248 // only occur only when index is out-of-bounds.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2344 2331
2345 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2332 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2346 UNIMPLEMENTED(); 2333 UNIMPLEMENTED();
2347 } 2334 }
2348 2335
2349 } // namespace dart 2336 } // namespace dart
2350 2337
2351 #undef __ 2338 #undef __
2352 2339
2353 #endif // defined TARGET_ARCH_X64 2340 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698