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

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

Issue 99573005: Add mutable double boxes for fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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 | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 16 matching lines...) Expand all
27 27
28 // Generic summary for call instructions that have all arguments pushed 28 // Generic summary for call instructions that have all arguments pushed
29 // on the stack and return the result in a fixed register EAX. 29 // on the stack and return the result in a fixed register EAX.
30 LocationSummary* Instruction::MakeCallSummary() { 30 LocationSummary* Instruction::MakeCallSummary() {
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
32 result->set_out(Location::RegisterLocation(EAX)); 32 result->set_out(Location::RegisterLocation(EAX));
33 return result; 33 return result;
34 } 34 }
35 35
36 36
37 LocationSummary* PushArgumentInstr::MakeLocationSummary() const { 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const {
38 const intptr_t kNumInputs = 1; 38 const intptr_t kNumInputs = 1;
39 const intptr_t kNumTemps= 0; 39 const intptr_t kNumTemps= 0;
40 LocationSummary* locs = 40 LocationSummary* locs =
41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
42 locs->set_in(0, Location::AnyOrConstant(value())); 42 locs->set_in(0, Location::AnyOrConstant(value()));
43 return locs; 43 return locs;
44 } 44 }
45 45
46 46
47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode 48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
49 // where PushArgument is handled by BindInstr::EmitNativeCode. 49 // where PushArgument is handled by BindInstr::EmitNativeCode.
50 if (compiler->is_optimizing()) { 50 if (compiler->is_optimizing()) {
51 Location value = locs()->in(0); 51 Location value = locs()->in(0);
52 if (value.IsRegister()) { 52 if (value.IsRegister()) {
53 __ pushl(value.reg()); 53 __ pushl(value.reg());
54 } else if (value.IsConstant()) { 54 } else if (value.IsConstant()) {
55 __ PushObject(value.constant()); 55 __ PushObject(value.constant());
56 } else { 56 } else {
57 ASSERT(value.IsStackSlot()); 57 ASSERT(value.IsStackSlot());
58 __ pushl(value.ToStackSlotAddress()); 58 __ pushl(value.ToStackSlotAddress());
59 } 59 }
60 } 60 }
61 } 61 }
62 62
63 63
64 LocationSummary* ReturnInstr::MakeLocationSummary() const { 64 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const {
65 const intptr_t kNumInputs = 1; 65 const intptr_t kNumInputs = 1;
66 const intptr_t kNumTemps = 0; 66 const intptr_t kNumTemps = 0;
67 LocationSummary* locs = 67 LocationSummary* locs =
68 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 68 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
69 locs->set_in(0, Location::RegisterLocation(EAX)); 69 locs->set_in(0, Location::RegisterLocation(EAX));
70 return locs; 70 return locs;
71 } 71 }
72 72
73 73
74 // Attempt optimized compilation at return instruction instead of at the entry. 74 // Attempt optimized compilation at return instruction instead of at the entry.
(...skipping 26 matching lines...) Expand all
101 101
102 // Generate 1 byte NOP so that the debugger can patch the 102 // Generate 1 byte NOP so that the debugger can patch the
103 // return pattern with a call to the debug stub. 103 // return pattern with a call to the debug stub.
104 __ nop(1); 104 __ nop(1);
105 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 105 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
106 Isolate::kNoDeoptId, 106 Isolate::kNoDeoptId,
107 token_pos()); 107 token_pos());
108 } 108 }
109 109
110 110
111 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 111 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
112 const intptr_t kNumInputs = 0; 112 const intptr_t kNumInputs = 0;
113 return LocationSummary::Make(kNumInputs, 113 return LocationSummary::Make(kNumInputs,
114 Location::RequiresRegister(), 114 Location::RequiresRegister(),
115 LocationSummary::kNoCall); 115 LocationSummary::kNoCall);
116 } 116 }
117 117
118 118
119 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 119 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
120 Register result = locs()->out().reg(); 120 Register result = locs()->out().reg();
121 __ movl(result, Address(EBP, local().index() * kWordSize)); 121 __ movl(result, Address(EBP, local().index() * kWordSize));
122 } 122 }
123 123
124 124
125 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { 125 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
126 const intptr_t kNumInputs = 1; 126 const intptr_t kNumInputs = 1;
127 return LocationSummary::Make(kNumInputs, 127 return LocationSummary::Make(kNumInputs,
128 Location::SameAsFirstInput(), 128 Location::SameAsFirstInput(),
129 LocationSummary::kNoCall); 129 LocationSummary::kNoCall);
130 } 130 }
131 131
132 132
133 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 133 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
134 Register value = locs()->in(0).reg(); 134 Register value = locs()->in(0).reg();
135 Register result = locs()->out().reg(); 135 Register result = locs()->out().reg();
136 ASSERT(result == value); // Assert that register assignment is correct. 136 ASSERT(result == value); // Assert that register assignment is correct.
137 __ movl(Address(EBP, local().index() * kWordSize), value); 137 __ movl(Address(EBP, local().index() * kWordSize), value);
138 } 138 }
139 139
140 140
141 LocationSummary* ConstantInstr::MakeLocationSummary() const { 141 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
142 const intptr_t kNumInputs = 0; 142 const intptr_t kNumInputs = 0;
143 return LocationSummary::Make(kNumInputs, 143 return LocationSummary::Make(kNumInputs,
144 Location::RequiresRegister(), 144 Location::RequiresRegister(),
145 LocationSummary::kNoCall); 145 LocationSummary::kNoCall);
146 } 146 }
147 147
148 148
149 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 149 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
150 // The register allocator drops constant definitions that have no uses. 150 // The register allocator drops constant definitions that have no uses.
151 if (!locs()->out().IsInvalid()) { 151 if (!locs()->out().IsInvalid()) {
152 Register result = locs()->out().reg(); 152 Register result = locs()->out().reg();
153 __ LoadObjectSafely(result, value()); 153 __ LoadObjectSafely(result, value());
154 } 154 }
155 } 155 }
156 156
157 157
158 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 158 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
159 const intptr_t kNumInputs = 3; 159 const intptr_t kNumInputs = 3;
160 const intptr_t kNumTemps = 0; 160 const intptr_t kNumTemps = 0;
161 LocationSummary* summary = 161 LocationSummary* summary =
162 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 162 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
163 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. 163 summary->set_in(0, Location::RegisterLocation(EAX)); // Value.
164 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. 164 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator.
165 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. 165 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments.
166 summary->set_out(Location::RegisterLocation(EAX)); 166 summary->set_out(Location::RegisterLocation(EAX));
167 return summary; 167 return summary;
168 } 168 }
169 169
170 170
171 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 171 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
172 const intptr_t kNumInputs = 1; 172 const intptr_t kNumInputs = 1;
173 const intptr_t kNumTemps = 0; 173 const intptr_t kNumTemps = 0;
174 LocationSummary* locs = 174 LocationSummary* locs =
175 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 175 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
176 locs->set_in(0, Location::RegisterLocation(EAX)); 176 locs->set_in(0, Location::RegisterLocation(EAX));
177 locs->set_out(Location::RegisterLocation(EAX)); 177 locs->set_out(Location::RegisterLocation(EAX));
178 return locs; 178 return locs;
179 } 179 }
180 180
181 181
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 case Token::kGT: return GREATER; 222 case Token::kGT: return GREATER;
223 case Token::kLTE: return LESS_EQUAL; 223 case Token::kLTE: return LESS_EQUAL;
224 case Token::kGTE: return GREATER_EQUAL; 224 case Token::kGTE: return GREATER_EQUAL;
225 default: 225 default:
226 UNREACHABLE(); 226 UNREACHABLE();
227 return OVERFLOW; 227 return OVERFLOW;
228 } 228 }
229 } 229 }
230 230
231 231
232 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 232 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
233 const intptr_t kNumInputs = 2; 233 const intptr_t kNumInputs = 2;
234 if (operation_cid() == kMintCid) { 234 if (operation_cid() == kMintCid) {
235 const intptr_t kNumTemps = 1; 235 const intptr_t kNumTemps = 1;
236 LocationSummary* locs = 236 LocationSummary* locs =
237 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 237 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
238 locs->set_in(0, Location::RequiresFpuRegister()); 238 locs->set_in(0, Location::RequiresFpuRegister());
239 locs->set_in(1, Location::RequiresFpuRegister()); 239 locs->set_in(1, Location::RequiresFpuRegister());
240 locs->set_temp(0, Location::RequiresRegister()); 240 locs->set_temp(0, Location::RequiresRegister());
241 locs->set_out(Location::RequiresRegister()); 241 locs->set_out(Location::RequiresRegister());
242 return locs; 242 return locs;
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 542 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
543 BranchInstr* branch) { 543 BranchInstr* branch) {
544 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 544 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
545 545
546 BranchLabels labels = compiler->CreateBranchLabels(branch); 546 BranchLabels labels = compiler->CreateBranchLabels(branch);
547 Condition true_condition = EmitComparisonCode(compiler, labels); 547 Condition true_condition = EmitComparisonCode(compiler, labels);
548 EmitBranchOnCondition(compiler, true_condition, labels); 548 EmitBranchOnCondition(compiler, true_condition, labels);
549 } 549 }
550 550
551 551
552 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 552 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const {
553 const intptr_t kNumInputs = 2; 553 const intptr_t kNumInputs = 2;
554 const intptr_t kNumTemps = 0; 554 const intptr_t kNumTemps = 0;
555 LocationSummary* locs = 555 LocationSummary* locs =
556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
557 locs->set_in(0, Location::RequiresRegister()); 557 locs->set_in(0, Location::RequiresRegister());
558 // Only one input can be a constant operand. The case of two constant 558 // Only one input can be a constant operand. The case of two constant
559 // operands should be handled by constant propagation. 559 // operands should be handled by constant propagation.
560 locs->set_in(1, Location::RegisterOrConstant(right())); 560 locs->set_in(1, Location::RegisterOrConstant(right()));
561 return locs; 561 return locs;
562 } 562 }
(...skipping 23 matching lines...) Expand all
586 586
587 587
588 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 588 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
589 BranchInstr* branch) { 589 BranchInstr* branch) {
590 BranchLabels labels = compiler->CreateBranchLabels(branch); 590 BranchLabels labels = compiler->CreateBranchLabels(branch);
591 Condition true_condition = EmitComparisonCode(compiler, labels); 591 Condition true_condition = EmitComparisonCode(compiler, labels);
592 EmitBranchOnCondition(compiler, true_condition, labels); 592 EmitBranchOnCondition(compiler, true_condition, labels);
593 } 593 }
594 594
595 595
596 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 596 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const {
597 const intptr_t kNumInputs = 2; 597 const intptr_t kNumInputs = 2;
598 const intptr_t kNumTemps = 0; 598 const intptr_t kNumTemps = 0;
599 if (operation_cid() == kMintCid) { 599 if (operation_cid() == kMintCid) {
600 const intptr_t kNumTemps = 2; 600 const intptr_t kNumTemps = 2;
601 LocationSummary* locs = 601 LocationSummary* locs =
602 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 602 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
603 locs->set_in(0, Location::RequiresFpuRegister()); 603 locs->set_in(0, Location::RequiresFpuRegister());
604 locs->set_in(1, Location::RequiresFpuRegister()); 604 locs->set_in(1, Location::RequiresFpuRegister());
605 locs->set_temp(0, Location::RequiresRegister()); 605 locs->set_temp(0, Location::RequiresRegister());
606 locs->set_temp(1, Location::RequiresRegister()); 606 locs->set_temp(1, Location::RequiresRegister());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 660
661 661
662 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 662 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
663 BranchInstr* branch) { 663 BranchInstr* branch) {
664 BranchLabels labels = compiler->CreateBranchLabels(branch); 664 BranchLabels labels = compiler->CreateBranchLabels(branch);
665 Condition true_condition = EmitComparisonCode(compiler, labels); 665 Condition true_condition = EmitComparisonCode(compiler, labels);
666 EmitBranchOnCondition(compiler, true_condition, labels); 666 EmitBranchOnCondition(compiler, true_condition, labels);
667 } 667 }
668 668
669 669
670 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 670 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
671 const intptr_t kNumInputs = 0; 671 const intptr_t kNumInputs = 0;
672 const intptr_t kNumTemps = 3; 672 const intptr_t kNumTemps = 3;
673 LocationSummary* locs = 673 LocationSummary* locs =
674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
675 locs->set_temp(0, Location::RegisterLocation(EAX)); 675 locs->set_temp(0, Location::RegisterLocation(EAX));
676 locs->set_temp(1, Location::RegisterLocation(ECX)); 676 locs->set_temp(1, Location::RegisterLocation(ECX));
677 locs->set_temp(2, Location::RegisterLocation(EDX)); 677 locs->set_temp(2, Location::RegisterLocation(EDX));
678 locs->set_out(Location::RegisterLocation(EAX)); 678 locs->set_out(Location::RegisterLocation(EAX));
679 return locs; 679 return locs;
680 } 680 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 return false; 714 return false;
715 } 715 }
716 const int64_t index = Smi::Cast(constant->value()).AsInt64Value(); 716 const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
717 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); 717 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid);
718 const intptr_t offset = FlowGraphCompiler::DataOffsetFor(cid); 718 const intptr_t offset = FlowGraphCompiler::DataOffsetFor(cid);
719 const int64_t displacement = index * scale + offset; 719 const int64_t displacement = index * scale + offset;
720 return Utils::IsInt(32, displacement); 720 return Utils::IsInt(32, displacement);
721 } 721 }
722 722
723 723
724 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { 724 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const {
725 const intptr_t kNumInputs = 1; 725 const intptr_t kNumInputs = 1;
726 // TODO(fschneider): Allow immediate operands for the char code. 726 // TODO(fschneider): Allow immediate operands for the char code.
727 return LocationSummary::Make(kNumInputs, 727 return LocationSummary::Make(kNumInputs,
728 Location::RequiresRegister(), 728 Location::RequiresRegister(),
729 LocationSummary::kNoCall); 729 LocationSummary::kNoCall);
730 } 730 }
731 731
732 732
733 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 733 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
734 Register char_code = locs()->in(0).reg(); 734 Register char_code = locs()->in(0).reg();
735 Register result = locs()->out().reg(); 735 Register result = locs()->out().reg();
736 __ movl(result, 736 __ movl(result,
737 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 737 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
738 __ movl(result, Address(result, 738 __ movl(result, Address(result,
739 char_code, 739 char_code,
740 TIMES_HALF_WORD_SIZE, // Char code is a smi. 740 TIMES_HALF_WORD_SIZE, // Char code is a smi.
741 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 741 Symbols::kNullCharCodeSymbolOffset * kWordSize));
742 } 742 }
743 743
744 744
745 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { 745 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
746 const intptr_t kNumInputs = 1; 746 const intptr_t kNumInputs = 1;
747 const intptr_t kNumTemps = 0; 747 const intptr_t kNumTemps = 0;
748 LocationSummary* summary = 748 LocationSummary* summary =
749 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 749 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
750 summary->set_in(0, Location::RegisterLocation(EAX)); 750 summary->set_in(0, Location::RegisterLocation(EAX));
751 summary->set_out(Location::RegisterLocation(EAX)); 751 summary->set_out(Location::RegisterLocation(EAX));
752 return summary; 752 return summary;
753 } 753 }
754 754
755 755
756 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 756 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
757 Register array = locs()->in(0).reg(); 757 Register array = locs()->in(0).reg();
758 __ pushl(array); 758 __ pushl(array);
759 const int kNumberOfArguments = 1; 759 const int kNumberOfArguments = 1;
760 const Array& kNoArgumentNames = Object::null_array(); 760 const Array& kNoArgumentNames = Object::null_array();
761 compiler->GenerateStaticCall(deopt_id(), 761 compiler->GenerateStaticCall(deopt_id(),
762 token_pos(), 762 token_pos(),
763 CallFunction(), 763 CallFunction(),
764 kNumberOfArguments, 764 kNumberOfArguments,
765 kNoArgumentNames, 765 kNoArgumentNames,
766 locs()); 766 locs());
767 ASSERT(locs()->out().reg() == EAX); 767 ASSERT(locs()->out().reg() == EAX);
768 } 768 }
769 769
770 770
771 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { 771 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
772 const intptr_t kNumInputs = 1; 772 const intptr_t kNumInputs = 1;
773 return LocationSummary::Make(kNumInputs, 773 return LocationSummary::Make(kNumInputs,
774 Location::RequiresRegister(), 774 Location::RequiresRegister(),
775 LocationSummary::kNoCall); 775 LocationSummary::kNoCall);
776 } 776 }
777 777
778 778
779 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 779 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
780 Register object = locs()->in(0).reg(); 780 Register object = locs()->in(0).reg();
781 Register result = locs()->out().reg(); 781 Register result = locs()->out().reg();
782 __ movl(result, FieldAddress(object, offset())); 782 __ movl(result, FieldAddress(object, offset()));
783 } 783 }
784 784
785 785
786 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 786 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const {
787 const intptr_t kNumInputs = 1; 787 const intptr_t kNumInputs = 1;
788 return LocationSummary::Make(kNumInputs, 788 return LocationSummary::Make(kNumInputs,
789 Location::RequiresRegister(), 789 Location::RequiresRegister(),
790 LocationSummary::kNoCall); 790 LocationSummary::kNoCall);
791 } 791 }
792 792
793 793
794 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 794 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
795 Register object = locs()->in(0).reg(); 795 Register object = locs()->in(0).reg();
796 Register result = locs()->out().reg(); 796 Register result = locs()->out().reg();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 return kUnboxedFloat32x4; 872 return kUnboxedFloat32x4;
873 case kTypedDataInt32x4ArrayCid: 873 case kTypedDataInt32x4ArrayCid:
874 return kUnboxedInt32x4; 874 return kUnboxedInt32x4;
875 default: 875 default:
876 UNIMPLEMENTED(); 876 UNIMPLEMENTED();
877 return kTagged; 877 return kTagged;
878 } 878 }
879 } 879 }
880 880
881 881
882 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 882 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const {
883 const intptr_t kNumInputs = 2; 883 const intptr_t kNumInputs = 2;
884 const intptr_t kNumTemps = 0; 884 const intptr_t kNumTemps = 0;
885 LocationSummary* locs = 885 LocationSummary* locs =
886 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 886 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
887 locs->set_in(0, Location::RequiresRegister()); 887 locs->set_in(0, Location::RequiresRegister());
888 if (CanBeImmediateIndex(index(), class_id())) { 888 if (CanBeImmediateIndex(index(), class_id())) {
889 // CanBeImmediateIndex must return false for unsafe smis. 889 // CanBeImmediateIndex must return false for unsafe smis.
890 locs->set_in(1, Location::Constant(index()->BoundConstant())); 890 locs->set_in(1, Location::Constant(index()->BoundConstant()));
891 } else { 891 } else {
892 // The index is either untagged (element size == 1) or a smi (for all 892 // The index is either untagged (element size == 1) or a smi (for all
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 return kUnboxedFloat32x4; 1041 return kUnboxedFloat32x4;
1042 case kTypedDataInt32x4ArrayCid: 1042 case kTypedDataInt32x4ArrayCid:
1043 return kUnboxedInt32x4; 1043 return kUnboxedInt32x4;
1044 default: 1044 default:
1045 UNIMPLEMENTED(); 1045 UNIMPLEMENTED();
1046 return kTagged; 1046 return kTagged;
1047 } 1047 }
1048 } 1048 }
1049 1049
1050 1050
1051 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1051 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const {
1052 const intptr_t kNumInputs = 3; 1052 const intptr_t kNumInputs = 3;
1053 const intptr_t kNumTemps = 0; 1053 const intptr_t kNumTemps = 0;
1054 LocationSummary* locs = 1054 LocationSummary* locs =
1055 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1055 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1056 locs->set_in(0, Location::RequiresRegister()); 1056 locs->set_in(0, Location::RequiresRegister());
1057 if (CanBeImmediateIndex(index(), class_id())) { 1057 if (CanBeImmediateIndex(index(), class_id())) {
1058 // CanBeImmediateIndex must return false for unsafe smis. 1058 // CanBeImmediateIndex must return false for unsafe smis.
1059 locs->set_in(1, Location::Constant(index()->BoundConstant())); 1059 locs->set_in(1, Location::Constant(index()->BoundConstant()));
1060 } else { 1060 } else {
1061 // The index is either untagged (element size == 1) or a smi (for all 1061 // The index is either untagged (element size == 1) or a smi (for all
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 case kTypedDataInt32x4ArrayCid: 1225 case kTypedDataInt32x4ArrayCid:
1226 case kTypedDataFloat32x4ArrayCid: 1226 case kTypedDataFloat32x4ArrayCid:
1227 __ movups(element_address, locs()->in(2).fpu_reg()); 1227 __ movups(element_address, locs()->in(2).fpu_reg());
1228 break; 1228 break;
1229 default: 1229 default:
1230 UNREACHABLE(); 1230 UNREACHABLE();
1231 } 1231 }
1232 } 1232 }
1233 1233
1234 1234
1235 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { 1235 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const {
1236 const intptr_t kNumInputs = 1; 1236 const intptr_t kNumInputs = 1;
1237 LocationSummary* summary = 1237 LocationSummary* summary =
1238 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 1238 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
1239 summary->set_in(0, Location::RequiresRegister()); 1239 summary->set_in(0, Location::RequiresRegister());
1240 const bool field_has_length = field().needs_length_check(); 1240 const bool field_has_length = field().needs_length_check();
1241 const bool need_value_temp_reg = 1241 const bool need_value_temp_reg =
1242 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && 1242 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
1243 (field().guarded_cid() != kSmiCid))); 1243 (field().guarded_cid() != kSmiCid)));
1244 if (need_value_temp_reg) { 1244 if (need_value_temp_reg) {
1245 summary->AddTemp(Location::RequiresRegister()); 1245 summary->AddTemp(Location::RequiresRegister());
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 __ j(NOT_EQUAL, fail); 1574 __ j(NOT_EQUAL, fail);
1575 } else { 1575 } else {
1576 UNREACHABLE(); 1576 UNREACHABLE();
1577 } 1577 }
1578 } 1578 }
1579 } 1579 }
1580 __ Bind(&ok); 1580 __ Bind(&ok);
1581 } 1581 }
1582 1582
1583 1583
1584 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 1584 class StoreInstanceFieldSlowPath : public SlowPathCode {
1585 public:
1586 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction)
1587 : instruction_(instruction) { }
1588
1589 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1590 __ Comment("StoreInstanceFieldSlowPath");
1591 __ Bind(entry_label());
1592 const Class& double_class = compiler->double_class();
1593 const Code& stub =
1594 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1595 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1596
1597 LocationSummary* locs = instruction_->locs();
1598 locs->live_registers()->Remove(locs->out());
1599
1600 compiler->SaveLiveRegisters(locs);
1601 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
1602 &label,
1603 PcDescriptors::kOther,
1604 locs);
1605 __ MoveRegister(locs->temp(0).reg(), EAX);
1606 compiler->RestoreLiveRegisters(locs);
1607
1608 __ jmp(exit_label());
1609 }
1610
1611 private:
1612 StoreInstanceFieldInstr* instruction_;
1613 };
1614
1615
1616 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1585 const intptr_t kNumInputs = 2; 1617 const intptr_t kNumInputs = 2;
1586 const intptr_t kNumTemps = 0; 1618 const intptr_t kNumTemps = 0;
1587 LocationSummary* summary = 1619 LocationSummary* summary =
1588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1620 new LocationSummary(kNumInputs, kNumTemps,
1621 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1622 ? LocationSummary::kCallOnSlowPath
1623 : LocationSummary::kNoCall);
1624
1589 summary->set_in(0, Location::RequiresRegister()); 1625 summary->set_in(0, Location::RequiresRegister());
1590 summary->set_in(1, ShouldEmitStoreBarrier() 1626 if (IsUnboxedStore() && opt) {
1627 summary->set_in(1, Location::RequiresFpuRegister());
1628 summary->AddTemp(Location::RequiresRegister());
1629 summary->AddTemp(Location::RequiresRegister());
1630 } else if (IsPotentialUnboxedStore()) {
1631 summary->set_in(1, ShouldEmitStoreBarrier()
1632 ? Location::WritableRegister()
1633 : Location::RequiresRegister());
1634 summary->AddTemp(Location::RequiresRegister());
1635 summary->AddTemp(Location::RequiresRegister());
1636 summary->AddTemp(opt ? Location::RequiresFpuRegister()
1637 : Location::FpuRegisterLocation(XMM1));
1638 } else {
1639 summary->set_in(1, ShouldEmitStoreBarrier()
1591 ? Location::WritableRegister() 1640 ? Location::WritableRegister()
1592 : Location::RegisterOrConstant(value())); 1641 : Location::RegisterOrConstant(value()));
1642 }
1593 return summary; 1643 return summary;
1594 } 1644 }
1595 1645
1596 1646
1597 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1647 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1648 Label skip_store;
1649
1598 Register instance_reg = locs()->in(0).reg(); 1650 Register instance_reg = locs()->in(0).reg();
1651
1652 if (IsUnboxedStore() && compiler->is_optimizing()) {
1653 XmmRegister value = locs()->in(1).fpu_reg();
1654 Register temp = locs()->temp(0).reg();
1655 Register temp2 = locs()->temp(1).reg();
1656
1657 if (is_initialization_) {
1658 StoreInstanceFieldSlowPath* slow_path =
1659 new StoreInstanceFieldSlowPath(this);
1660 compiler->AddSlowPathCode(slow_path);
1661
1662 __ TryAllocate(compiler->double_class(),
1663 slow_path->entry_label(),
1664 Assembler::kFarJump,
1665 temp);
1666 __ Bind(slow_path->exit_label());
1667 __ movl(temp2, temp);
1668 __ StoreIntoObject(instance_reg,
1669 FieldAddress(instance_reg, field().Offset()),
1670 temp2);
1671 } else {
1672 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1673 }
1674 __ movsd(FieldAddress(temp, Double::value_offset()), value);
1675 return;
1676 }
1677
1678 if (IsPotentialUnboxedStore()) {
1679 Register value_reg = locs()->in(1).reg();
1680 Register temp = locs()->temp(0).reg();
1681 Register temp2 = locs()->temp(1).reg();
1682 FpuRegister fpu_temp = locs()->temp(2).fpu_reg();
1683
1684 Label store_pointer, copy_payload;
1685 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1686 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()),
1687 Immediate(kDoubleCid));
1688 __ j(NOT_EQUAL, &store_pointer);
1689 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()),
1690 Immediate(kNullCid));
1691 __ j(EQUAL, &store_pointer);
1692
1693 const Immediate& raw_null =
1694 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1695 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1696 __ cmpl(temp, raw_null);
1697 __ j(NOT_EQUAL, &copy_payload);
1698
1699 StoreInstanceFieldSlowPath* slow_path =
1700 new StoreInstanceFieldSlowPath(this);
1701 compiler->AddSlowPathCode(slow_path);
1702
1703 if (!compiler->is_optimizing()) {
1704 locs()->live_registers()->Add(locs()->in(0));
1705 locs()->live_registers()->Add(locs()->in(1));
1706 }
1707
1708 __ TryAllocate(compiler->double_class(),
1709 slow_path->entry_label(),
1710 Assembler::kFarJump,
1711 temp);
1712 __ Bind(slow_path->exit_label());
1713 __ movl(temp2, temp);
1714 __ StoreIntoObject(instance_reg,
1715 FieldAddress(instance_reg, field().Offset()),
1716 temp2);
1717
1718 __ Bind(&copy_payload);
1719 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset()));
1720 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp);
1721 __ jmp(&skip_store);
1722 __ Bind(&store_pointer);
1723 }
1724
1599 if (ShouldEmitStoreBarrier()) { 1725 if (ShouldEmitStoreBarrier()) {
1600 Register value_reg = locs()->in(1).reg(); 1726 Register value_reg = locs()->in(1).reg();
1601 __ StoreIntoObject(instance_reg, 1727 __ StoreIntoObject(instance_reg,
1602 FieldAddress(instance_reg, field().Offset()), 1728 FieldAddress(instance_reg, field().Offset()),
1603 value_reg, 1729 value_reg,
1604 CanValueBeSmi()); 1730 CanValueBeSmi());
1605 } else { 1731 } else {
1606 if (locs()->in(1).IsConstant()) { 1732 if (locs()->in(1).IsConstant()) {
1607 __ StoreIntoObjectNoBarrier( 1733 __ StoreIntoObjectNoBarrier(
1608 instance_reg, 1734 instance_reg,
1609 FieldAddress(instance_reg, field().Offset()), 1735 FieldAddress(instance_reg, field().Offset()),
1610 locs()->in(1).constant()); 1736 locs()->in(1).constant());
1611 } else { 1737 } else {
1612 Register value_reg = locs()->in(1).reg(); 1738 Register value_reg = locs()->in(1).reg();
1613 __ StoreIntoObjectNoBarrier(instance_reg, 1739 __ StoreIntoObjectNoBarrier(instance_reg,
1614 FieldAddress(instance_reg, field().Offset()), value_reg); 1740 FieldAddress(instance_reg, field().Offset()), value_reg);
1615 } 1741 }
1616 } 1742 }
1743 __ Bind(&skip_store);
1617 } 1744 }
1618 1745
1619 1746
1620 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { 1747 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1621 const intptr_t kNumInputs = 1; 1748 const intptr_t kNumInputs = 1;
1622 const intptr_t kNumTemps = 0; 1749 const intptr_t kNumTemps = 0;
1623 LocationSummary* summary = 1750 LocationSummary* summary =
1624 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1751 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1625 summary->set_in(0, Location::RequiresRegister()); 1752 summary->set_in(0, Location::RequiresRegister());
1626 // By specifying same register as input, our simple register allocator can 1753 // By specifying same register as input, our simple register allocator can
1627 // generate better code. 1754 // generate better code.
1628 summary->set_out(Location::SameAsFirstInput()); 1755 summary->set_out(Location::SameAsFirstInput());
1629 return summary; 1756 return summary;
1630 } 1757 }
1631 1758
1632 1759
1633 // When the parser is building an implicit static getter for optimization, 1760 // When the parser is building an implicit static getter for optimization,
1634 // it can generate a function body where deoptimization ids do not line up 1761 // it can generate a function body where deoptimization ids do not line up
1635 // with the unoptimized code. 1762 // with the unoptimized code.
1636 // 1763 //
1637 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1764 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1638 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1765 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1639 Register field = locs()->in(0).reg(); 1766 Register field = locs()->in(0).reg();
1640 Register result = locs()->out().reg(); 1767 Register result = locs()->out().reg();
1641 __ movl(result, FieldAddress(field, Field::value_offset())); 1768 __ movl(result, FieldAddress(field, Field::value_offset()));
1642 } 1769 }
1643 1770
1644 1771
1645 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { 1772 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1646 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1773 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1647 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1774 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1648 : Location::RequiresRegister()); 1775 : Location::RequiresRegister());
1649 locs->set_temp(0, Location::RequiresRegister()); 1776 locs->set_temp(0, Location::RequiresRegister());
1650 return locs; 1777 return locs;
1651 } 1778 }
1652 1779
1653 1780
1654 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1781 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1655 Register value = locs()->in(0).reg(); 1782 Register value = locs()->in(0).reg();
1656 Register temp = locs()->temp(0).reg(); 1783 Register temp = locs()->temp(0).reg();
1657 1784
1658 __ LoadObject(temp, field()); 1785 __ LoadObject(temp, field());
1659 if (this->value()->NeedsStoreBuffer()) { 1786 if (this->value()->NeedsStoreBuffer()) {
1660 __ StoreIntoObject(temp, 1787 __ StoreIntoObject(temp,
1661 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); 1788 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi());
1662 } else { 1789 } else {
1663 __ StoreIntoObjectNoBarrier( 1790 __ StoreIntoObjectNoBarrier(
1664 temp, FieldAddress(temp, Field::value_offset()), value); 1791 temp, FieldAddress(temp, Field::value_offset()), value);
1665 } 1792 }
1666 } 1793 }
1667 1794
1668 1795
1669 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { 1796 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1670 const intptr_t kNumInputs = 3; 1797 const intptr_t kNumInputs = 3;
1671 const intptr_t kNumTemps = 0; 1798 const intptr_t kNumTemps = 0;
1672 LocationSummary* summary = 1799 LocationSummary* summary =
1673 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1800 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1674 summary->set_in(0, Location::RegisterLocation(EAX)); 1801 summary->set_in(0, Location::RegisterLocation(EAX));
1675 summary->set_in(1, Location::RegisterLocation(ECX)); 1802 summary->set_in(1, Location::RegisterLocation(ECX));
1676 summary->set_in(2, Location::RegisterLocation(EDX)); 1803 summary->set_in(2, Location::RegisterLocation(EDX));
1677 summary->set_out(Location::RegisterLocation(EAX)); 1804 summary->set_out(Location::RegisterLocation(EAX));
1678 return summary; 1805 return summary;
1679 } 1806 }
1680 1807
1681 1808
1682 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1809 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1683 ASSERT(locs()->in(0).reg() == EAX); // Value. 1810 ASSERT(locs()->in(0).reg() == EAX); // Value.
1684 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1811 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1685 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1812 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1686 1813
1687 compiler->GenerateInstanceOf(token_pos(), 1814 compiler->GenerateInstanceOf(token_pos(),
1688 deopt_id(), 1815 deopt_id(),
1689 type(), 1816 type(),
1690 negate_result(), 1817 negate_result(),
1691 locs()); 1818 locs());
1692 ASSERT(locs()->out().reg() == EAX); 1819 ASSERT(locs()->out().reg() == EAX);
1693 } 1820 }
1694 1821
1695 1822
1696 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { 1823 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1697 const intptr_t kNumInputs = 1; 1824 const intptr_t kNumInputs = 1;
1698 const intptr_t kNumTemps = 0; 1825 const intptr_t kNumTemps = 0;
1699 LocationSummary* locs = 1826 LocationSummary* locs =
1700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1827 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1701 locs->set_in(0, Location::RegisterLocation(ECX)); 1828 locs->set_in(0, Location::RegisterLocation(ECX));
1702 locs->set_out(Location::RegisterLocation(EAX)); 1829 locs->set_out(Location::RegisterLocation(EAX));
1703 return locs; 1830 return locs;
1704 } 1831 }
1705 1832
1706 1833
1707 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1834 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1708 // Allocate the array. EDX = length, ECX = element type. 1835 // Allocate the array. EDX = length, ECX = element type.
1709 ASSERT(locs()->in(0).reg() == ECX); 1836 ASSERT(locs()->in(0).reg() == ECX);
1710 __ movl(EDX, Immediate(Smi::RawValue(num_elements()))); 1837 __ movl(EDX, Immediate(Smi::RawValue(num_elements())));
1711 compiler->GenerateCall(token_pos(), 1838 compiler->GenerateCall(token_pos(),
1712 &StubCode::AllocateArrayLabel(), 1839 &StubCode::AllocateArrayLabel(),
1713 PcDescriptors::kOther, 1840 PcDescriptors::kOther,
1714 locs()); 1841 locs());
1715 ASSERT(locs()->out().reg() == EAX); 1842 ASSERT(locs()->out().reg() == EAX);
1716 } 1843 }
1717 1844
1718 1845
1719 LocationSummary* 1846 LocationSummary*
1720 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { 1847 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const {
1721 return MakeCallSummary(); 1848 return MakeCallSummary();
1722 } 1849 }
1723 1850
1724 1851
1725 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( 1852 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
1726 FlowGraphCompiler* compiler) { 1853 FlowGraphCompiler* compiler) {
1727 compiler->GenerateRuntimeCall(token_pos(), 1854 compiler->GenerateRuntimeCall(token_pos(),
1728 deopt_id(), 1855 deopt_id(),
1729 kAllocateObjectWithBoundsCheckRuntimeEntry, 1856 kAllocateObjectWithBoundsCheckRuntimeEntry,
1730 3, 1857 3,
1731 locs()); 1858 locs());
1732 __ Drop(3); 1859 __ Drop(3);
1733 ASSERT(locs()->out().reg() == EAX); 1860 ASSERT(locs()->out().reg() == EAX);
1734 __ popl(EAX); // Pop new instance. 1861 __ popl(EAX); // Pop new instance.
1735 } 1862 }
1736 1863
1737 1864
1738 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { 1865 class BoxDoubleSlowPath : public SlowPathCode {
1739 return LocationSummary::Make(1, 1866 public:
1740 Location::RequiresRegister(), 1867 explicit BoxDoubleSlowPath(Instruction* instruction)
1741 LocationSummary::kNoCall); 1868 : instruction_(instruction) { }
1869
1870 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1871 __ Comment("BoxDoubleSlowPath");
1872 __ Bind(entry_label());
1873 const Class& double_class = compiler->double_class();
1874 const Code& stub =
1875 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1876 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1877
1878 LocationSummary* locs = instruction_->locs();
1879 locs->live_registers()->Remove(locs->out());
1880
1881 compiler->SaveLiveRegisters(locs);
1882 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
1883 &label,
1884 PcDescriptors::kOther,
1885 locs);
1886 __ MoveRegister(locs->out().reg(), EAX);
1887 compiler->RestoreLiveRegisters(locs);
1888
1889 __ jmp(exit_label());
1890 }
1891
1892 private:
1893 Instruction* instruction_;
1894 };
1895
1896
1897 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1898 const intptr_t kNumInputs = 1;
1899 const intptr_t kNumTemps = 0;
1900 LocationSummary* locs =
1901 new LocationSummary(
1902 kNumInputs, kNumTemps,
1903 (opt && !IsPotentialUnboxedLoad())
1904 ? LocationSummary::kNoCall
1905 : LocationSummary::kCallOnSlowPath);
1906
1907 locs->set_in(0, Location::RequiresRegister());
1908
1909 if (IsUnboxedLoad() && opt) {
1910 locs->AddTemp(Location::RequiresRegister());
1911 } else if (IsPotentialUnboxedLoad()) {
1912 locs->AddTemp(opt ? Location::RequiresFpuRegister()
1913 : Location::FpuRegisterLocation(XMM1));
1914 locs->AddTemp(Location::RequiresRegister());
1915 }
1916 locs->set_out(Location::RequiresRegister());
1917 return locs;
1742 } 1918 }
1743 1919
1744 1920
1745 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1921 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1746 Register instance_reg = locs()->in(0).reg(); 1922 Register instance_reg = locs()->in(0).reg();
1747 Register result_reg = locs()->out().reg(); 1923 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1924 XmmRegister result = locs()->out().fpu_reg();
1925 Register temp = locs()->temp(0).reg();
1926 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
1927 __ movsd(result, FieldAddress(temp, Double::value_offset()));
1928 return;
1929 }
1748 1930
1749 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1931 Label done;
1932 Register result = locs()->out().reg();
1933 if (IsPotentialUnboxedLoad()) {
1934 Register temp = locs()->temp(1).reg();
1935 XmmRegister value = locs()->temp(0).fpu_reg();
1936
1937 Label load_pointer;
1938 __ LoadObject(result, Field::ZoneHandle(field()->raw()));
1939
1940 FieldAddress field_cid_operand(result, Field::guarded_cid_offset());
1941 FieldAddress field_nullability_operand(result, Field::is_nullable_offset());
1942
1943 __ cmpl(field_cid_operand, Immediate(kDoubleCid));
1944 __ j(NOT_EQUAL, &load_pointer);
1945
1946 __ cmpl(field_nullability_operand, Immediate(kNullCid));
1947 __ j(EQUAL, &load_pointer);
1948
1949 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1950 compiler->AddSlowPathCode(slow_path);
1951
1952 if (!compiler->is_optimizing()) {
1953 locs()->live_registers()->Add(locs()->in(0));
1954 }
1955
1956 __ TryAllocate(compiler->double_class(),
1957 slow_path->entry_label(),
1958 Assembler::kFarJump,
1959 result);
1960 __ Bind(slow_path->exit_label());
1961 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
1962 __ movsd(value, FieldAddress(temp, Double::value_offset()));
1963 __ movsd(FieldAddress(result, Double::value_offset()), value);
1964 __ jmp(&done);
1965 __ Bind(&load_pointer);
1966 }
1967 __ movl(result, FieldAddress(instance_reg, offset_in_bytes()));
1968 __ Bind(&done);
1750 } 1969 }
1751 1970
1752 1971
1753 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { 1972 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
1754 const intptr_t kNumInputs = 1; 1973 const intptr_t kNumInputs = 1;
1755 const intptr_t kNumTemps = 0; 1974 const intptr_t kNumTemps = 0;
1756 LocationSummary* locs = 1975 LocationSummary* locs =
1757 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1976 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1758 locs->set_in(0, Location::RegisterLocation(EAX)); 1977 locs->set_in(0, Location::RegisterLocation(EAX));
1759 locs->set_out(Location::RegisterLocation(EAX)); 1978 locs->set_out(Location::RegisterLocation(EAX));
1760 return locs; 1979 return locs;
1761 } 1980 }
1762 1981
1763 1982
(...skipping 11 matching lines...) Expand all
1775 deopt_id(), 1994 deopt_id(),
1776 kInstantiateTypeRuntimeEntry, 1995 kInstantiateTypeRuntimeEntry,
1777 2, 1996 2,
1778 locs()); 1997 locs());
1779 __ Drop(2); // Drop instantiator and uninstantiated type. 1998 __ Drop(2); // Drop instantiator and uninstantiated type.
1780 __ popl(result_reg); // Pop instantiated type. 1999 __ popl(result_reg); // Pop instantiated type.
1781 ASSERT(instantiator_reg == result_reg); 2000 ASSERT(instantiator_reg == result_reg);
1782 } 2001 }
1783 2002
1784 2003
1785 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 2004 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2005 bool opt) const {
1786 const intptr_t kNumInputs = 1; 2006 const intptr_t kNumInputs = 1;
1787 const intptr_t kNumTemps = 0; 2007 const intptr_t kNumTemps = 0;
1788 LocationSummary* locs = 2008 LocationSummary* locs =
1789 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2009 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1790 locs->set_in(0, Location::RegisterLocation(EAX)); 2010 locs->set_in(0, Location::RegisterLocation(EAX));
1791 locs->set_out(Location::RegisterLocation(EAX)); 2011 locs->set_out(Location::RegisterLocation(EAX));
1792 return locs; 2012 return locs;
1793 } 2013 }
1794 2014
1795 2015
(...skipping 29 matching lines...) Expand all
1825 2, 2045 2,
1826 locs()); 2046 locs());
1827 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 2047 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1828 __ popl(result_reg); // Pop instantiated type arguments. 2048 __ popl(result_reg); // Pop instantiated type arguments.
1829 __ Bind(&type_arguments_instantiated); 2049 __ Bind(&type_arguments_instantiated);
1830 ASSERT(instantiator_reg == result_reg); 2050 ASSERT(instantiator_reg == result_reg);
1831 } 2051 }
1832 2052
1833 2053
1834 LocationSummary* 2054 LocationSummary*
1835 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 2055 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
1836 const intptr_t kNumInputs = 1; 2056 const intptr_t kNumInputs = 1;
1837 const intptr_t kNumTemps = 0; 2057 const intptr_t kNumTemps = 0;
1838 LocationSummary* locs = 2058 LocationSummary* locs =
1839 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2059 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1840 locs->set_in(0, Location::RequiresRegister()); 2060 locs->set_in(0, Location::RequiresRegister());
1841 locs->set_out(Location::SameAsFirstInput()); 2061 locs->set_out(Location::SameAsFirstInput());
1842 return locs; 2062 return locs;
1843 } 2063 }
1844 2064
1845 2065
(...skipping 22 matching lines...) Expand all
1868 // instantiate the type arguments. 2088 // instantiate the type arguments.
1869 __ LoadObject(result_reg, type_arguments()); 2089 __ LoadObject(result_reg, type_arguments());
1870 // result_reg: uninstantiated type arguments. 2090 // result_reg: uninstantiated type arguments.
1871 2091
1872 __ Bind(&type_arguments_instantiated); 2092 __ Bind(&type_arguments_instantiated);
1873 // result_reg: uninstantiated or instantiated type arguments. 2093 // result_reg: uninstantiated or instantiated type arguments.
1874 } 2094 }
1875 2095
1876 2096
1877 LocationSummary* 2097 LocationSummary*
1878 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 2098 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
1879 const intptr_t kNumInputs = 1; 2099 const intptr_t kNumInputs = 1;
1880 const intptr_t kNumTemps = 0; 2100 const intptr_t kNumTemps = 0;
1881 LocationSummary* locs = 2101 LocationSummary* locs =
1882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2102 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1883 locs->set_in(0, Location::RequiresRegister()); 2103 locs->set_in(0, Location::RequiresRegister());
1884 locs->set_out(Location::SameAsFirstInput()); 2104 locs->set_out(Location::SameAsFirstInput());
1885 return locs; 2105 return locs;
1886 } 2106 }
1887 2107
1888 2108
(...skipping 19 matching lines...) Expand all
1908 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); 2128 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
1909 // Null was used in VisitExtractConstructorTypeArguments as the 2129 // Null was used in VisitExtractConstructorTypeArguments as the
1910 // instantiated type arguments, no proper instantiator needed. 2130 // instantiated type arguments, no proper instantiator needed.
1911 __ movl(instantiator_reg, 2131 __ movl(instantiator_reg,
1912 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 2132 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1913 __ Bind(&instantiator_not_null); 2133 __ Bind(&instantiator_not_null);
1914 // instantiator_reg: instantiator or kNoInstantiator. 2134 // instantiator_reg: instantiator or kNoInstantiator.
1915 } 2135 }
1916 2136
1917 2137
1918 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 2138 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
1919 const intptr_t kNumInputs = 0; 2139 const intptr_t kNumInputs = 0;
1920 const intptr_t kNumTemps = 1; 2140 const intptr_t kNumTemps = 1;
1921 LocationSummary* locs = 2141 LocationSummary* locs =
1922 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2142 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1923 locs->set_temp(0, Location::RegisterLocation(EDX)); 2143 locs->set_temp(0, Location::RegisterLocation(EDX));
1924 locs->set_out(Location::RegisterLocation(EAX)); 2144 locs->set_out(Location::RegisterLocation(EAX));
1925 return locs; 2145 return locs;
1926 } 2146 }
1927 2147
1928 2148
1929 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2149 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1930 ASSERT(locs()->temp(0).reg() == EDX); 2150 ASSERT(locs()->temp(0).reg() == EDX);
1931 ASSERT(locs()->out().reg() == EAX); 2151 ASSERT(locs()->out().reg() == EAX);
1932 2152
1933 __ movl(EDX, Immediate(num_context_variables())); 2153 __ movl(EDX, Immediate(num_context_variables()));
1934 const ExternalLabel label("alloc_context", 2154 const ExternalLabel label("alloc_context",
1935 StubCode::AllocateContextEntryPoint()); 2155 StubCode::AllocateContextEntryPoint());
1936 compiler->GenerateCall(token_pos(), 2156 compiler->GenerateCall(token_pos(),
1937 &label, 2157 &label,
1938 PcDescriptors::kOther, 2158 PcDescriptors::kOther,
1939 locs()); 2159 locs());
1940 } 2160 }
1941 2161
1942 2162
1943 LocationSummary* CloneContextInstr::MakeLocationSummary() const { 2163 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
1944 const intptr_t kNumInputs = 1; 2164 const intptr_t kNumInputs = 1;
1945 const intptr_t kNumTemps = 0; 2165 const intptr_t kNumTemps = 0;
1946 LocationSummary* locs = 2166 LocationSummary* locs =
1947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2167 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1948 locs->set_in(0, Location::RegisterLocation(EAX)); 2168 locs->set_in(0, Location::RegisterLocation(EAX));
1949 locs->set_out(Location::RegisterLocation(EAX)); 2169 locs->set_out(Location::RegisterLocation(EAX));
1950 return locs; 2170 return locs;
1951 } 2171 }
1952 2172
1953 2173
1954 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2174 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1955 Register context_value = locs()->in(0).reg(); 2175 Register context_value = locs()->in(0).reg();
1956 Register result = locs()->out().reg(); 2176 Register result = locs()->out().reg();
1957 2177
1958 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2178 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1959 __ pushl(context_value); 2179 __ pushl(context_value);
1960 compiler->GenerateRuntimeCall(token_pos(), 2180 compiler->GenerateRuntimeCall(token_pos(),
1961 deopt_id(), 2181 deopt_id(),
1962 kCloneContextRuntimeEntry, 2182 kCloneContextRuntimeEntry,
1963 1, 2183 1,
1964 locs()); 2184 locs());
1965 __ popl(result); // Remove argument. 2185 __ popl(result); // Remove argument.
1966 __ popl(result); // Get result (cloned context). 2186 __ popl(result); // Get result (cloned context).
1967 } 2187 }
1968 2188
1969 2189
1970 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { 2190 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const {
1971 UNREACHABLE(); 2191 UNREACHABLE();
1972 return NULL; 2192 return NULL;
1973 } 2193 }
1974 2194
1975 2195
1976 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2196 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1977 __ Bind(compiler->GetJumpLabel(this)); 2197 __ Bind(compiler->GetJumpLabel(this));
1978 compiler->AddExceptionHandler(catch_try_index(), 2198 compiler->AddExceptionHandler(catch_try_index(),
1979 try_index(), 2199 try_index(),
1980 compiler->assembler()->CodeSize(), 2200 compiler->assembler()->CodeSize(),
(...skipping 12 matching lines...) Expand all
1993 2213
1994 // Restore stack and initialize the two exception variables: 2214 // Restore stack and initialize the two exception variables:
1995 // exception and stack trace variables. 2215 // exception and stack trace variables.
1996 __ movl(Address(EBP, exception_var().index() * kWordSize), 2216 __ movl(Address(EBP, exception_var().index() * kWordSize),
1997 kExceptionObjectReg); 2217 kExceptionObjectReg);
1998 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 2218 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
1999 kStackTraceObjectReg); 2219 kStackTraceObjectReg);
2000 } 2220 }
2001 2221
2002 2222
2003 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 2223 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const {
2004 const intptr_t kNumInputs = 0; 2224 const intptr_t kNumInputs = 0;
2005 const intptr_t kNumTemps = 0; 2225 const intptr_t kNumTemps = 0;
2006 LocationSummary* summary = 2226 LocationSummary* summary =
2007 new LocationSummary(kNumInputs, 2227 new LocationSummary(kNumInputs,
2008 kNumTemps, 2228 kNumTemps,
2009 LocationSummary::kCallOnSlowPath); 2229 LocationSummary::kCallOnSlowPath);
2010 return summary; 2230 return summary;
2011 } 2231 }
2012 2232
2013 2233
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 __ shll(left, right); 2403 __ shll(left, right);
2184 __ sarl(left, right); 2404 __ sarl(left, right);
2185 __ cmpl(left, temp); 2405 __ cmpl(left, temp);
2186 __ j(NOT_EQUAL, deopt); // Overflow. 2406 __ j(NOT_EQUAL, deopt); // Overflow.
2187 // Shift for result now we know there is no overflow. 2407 // Shift for result now we know there is no overflow.
2188 __ shll(left, right); 2408 __ shll(left, right);
2189 } 2409 }
2190 } 2410 }
2191 2411
2192 2412
2193 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 2413 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const {
2194 const intptr_t kNumInputs = 2; 2414 const intptr_t kNumInputs = 2;
2195 if (op_kind() == Token::kTRUNCDIV) { 2415 if (op_kind() == Token::kTRUNCDIV) {
2196 const intptr_t kNumTemps = 1; 2416 const intptr_t kNumTemps = 1;
2197 LocationSummary* summary = 2417 LocationSummary* summary =
2198 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2418 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2199 if (RightIsPowerOfTwoConstant()) { 2419 if (RightIsPowerOfTwoConstant()) {
2200 summary->set_in(0, Location::RequiresRegister()); 2420 summary->set_in(0, Location::RequiresRegister());
2201 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2421 ConstantInstr* right_constant = right()->definition()->AsConstant();
2202 // The programmer only controls one bit, so the constant is safe. 2422 // The programmer only controls one bit, so the constant is safe.
2203 summary->set_in(1, Location::Constant(right_constant->value())); 2423 summary->set_in(1, Location::Constant(right_constant->value()));
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
2553 UNREACHABLE(); 2773 UNREACHABLE();
2554 break; 2774 break;
2555 } 2775 }
2556 default: 2776 default:
2557 UNREACHABLE(); 2777 UNREACHABLE();
2558 break; 2778 break;
2559 } 2779 }
2560 } 2780 }
2561 2781
2562 2782
2563 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { 2783 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const {
2564 intptr_t left_cid = left()->Type()->ToCid(); 2784 intptr_t left_cid = left()->Type()->ToCid();
2565 intptr_t right_cid = right()->Type()->ToCid(); 2785 intptr_t right_cid = right()->Type()->ToCid();
2566 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 2786 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
2567 const intptr_t kNumInputs = 2; 2787 const intptr_t kNumInputs = 2;
2568 const bool need_temp = (left_cid != kSmiCid) && (right_cid != kSmiCid); 2788 const bool need_temp = (left_cid != kSmiCid) && (right_cid != kSmiCid);
2569 const intptr_t kNumTemps = need_temp ? 1 : 0; 2789 const intptr_t kNumTemps = need_temp ? 1 : 0;
2570 LocationSummary* summary = 2790 LocationSummary* summary =
2571 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2572 summary->set_in(0, Location::RequiresRegister()); 2792 summary->set_in(0, Location::RequiresRegister());
2573 summary->set_in(1, Location::RequiresRegister()); 2793 summary->set_in(1, Location::RequiresRegister());
(...skipping 15 matching lines...) Expand all
2589 } else { 2809 } else {
2590 Register temp = locs()->temp(0).reg(); 2810 Register temp = locs()->temp(0).reg();
2591 __ movl(temp, left); 2811 __ movl(temp, left);
2592 __ orl(temp, right); 2812 __ orl(temp, right);
2593 __ testl(temp, Immediate(kSmiTagMask)); 2813 __ testl(temp, Immediate(kSmiTagMask));
2594 } 2814 }
2595 __ j(ZERO, deopt); 2815 __ j(ZERO, deopt);
2596 } 2816 }
2597 2817
2598 2818
2599 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { 2819 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2600 const intptr_t kNumInputs = 1; 2820 const intptr_t kNumInputs = 1;
2601 const intptr_t kNumTemps = 0; 2821 const intptr_t kNumTemps = 0;
2602 LocationSummary* summary = 2822 LocationSummary* summary =
2603 new LocationSummary(kNumInputs, 2823 new LocationSummary(kNumInputs,
2604 kNumTemps, 2824 kNumTemps,
2605 LocationSummary::kCallOnSlowPath); 2825 LocationSummary::kCallOnSlowPath);
2606 summary->set_in(0, Location::RequiresFpuRegister()); 2826 summary->set_in(0, Location::RequiresFpuRegister());
2607 summary->set_out(Location::RequiresRegister()); 2827 summary->set_out(Location::RequiresRegister());
2608 return summary; 2828 return summary;
2609 } 2829 }
2610 2830
2611 2831
2612 class BoxDoubleSlowPath : public SlowPathCode {
2613 public:
2614 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
2615 : instruction_(instruction) { }
2616
2617 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2618 __ Comment("BoxDoubleSlowPath");
2619 __ Bind(entry_label());
2620 const Class& double_class = compiler->double_class();
2621 const Code& stub =
2622 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2623 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2624
2625 LocationSummary* locs = instruction_->locs();
2626 locs->live_registers()->Remove(locs->out());
2627
2628 compiler->SaveLiveRegisters(locs);
2629 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
2630 &label,
2631 PcDescriptors::kOther,
2632 locs);
2633 __ MoveRegister(locs->out().reg(), EAX);
2634 compiler->RestoreLiveRegisters(locs);
2635
2636 __ jmp(exit_label());
2637 }
2638
2639 private:
2640 BoxDoubleInstr* instruction_;
2641 };
2642
2643
2644 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2832 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2645 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2833 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2646 compiler->AddSlowPathCode(slow_path); 2834 compiler->AddSlowPathCode(slow_path);
2647 2835
2648 Register out_reg = locs()->out().reg(); 2836 Register out_reg = locs()->out().reg();
2649 XmmRegister value = locs()->in(0).fpu_reg(); 2837 XmmRegister value = locs()->in(0).fpu_reg();
2650 2838
2651 __ TryAllocate(compiler->double_class(), 2839 __ TryAllocate(compiler->double_class(),
2652 slow_path->entry_label(), 2840 slow_path->entry_label(),
2653 Assembler::kFarJump, 2841 Assembler::kFarJump,
2654 out_reg); 2842 out_reg);
2655 __ Bind(slow_path->exit_label()); 2843 __ Bind(slow_path->exit_label());
2656 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 2844 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
2657 } 2845 }
2658 2846
2659 2847
2660 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 2848 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
2661 const intptr_t kNumInputs = 1; 2849 const intptr_t kNumInputs = 1;
2662 const intptr_t value_cid = value()->Type()->ToCid(); 2850 const intptr_t value_cid = value()->Type()->ToCid();
2663 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); 2851 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
2664 const bool needs_writable_input = (value_cid == kSmiCid); 2852 const bool needs_writable_input = (value_cid == kSmiCid);
2665 const intptr_t kNumTemps = needs_temp ? 1 : 0; 2853 const intptr_t kNumTemps = needs_temp ? 1 : 0;
2666 LocationSummary* summary = 2854 LocationSummary* summary =
2667 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2855 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2668 summary->set_in(0, needs_writable_input 2856 summary->set_in(0, needs_writable_input
2669 ? Location::WritableRegister() 2857 ? Location::WritableRegister()
2670 : Location::RequiresRegister()); 2858 : Location::RequiresRegister());
(...skipping 25 matching lines...) Expand all
2696 __ jmp(&done); 2884 __ jmp(&done);
2697 __ Bind(&is_smi); 2885 __ Bind(&is_smi);
2698 __ movl(temp, value); 2886 __ movl(temp, value);
2699 __ SmiUntag(temp); 2887 __ SmiUntag(temp);
2700 __ cvtsi2sd(result, temp); 2888 __ cvtsi2sd(result, temp);
2701 __ Bind(&done); 2889 __ Bind(&done);
2702 } 2890 }
2703 } 2891 }
2704 2892
2705 2893
2706 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { 2894 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2707 const intptr_t kNumInputs = 1; 2895 const intptr_t kNumInputs = 1;
2708 const intptr_t kNumTemps = 0; 2896 const intptr_t kNumTemps = 0;
2709 LocationSummary* summary = 2897 LocationSummary* summary =
2710 new LocationSummary(kNumInputs, 2898 new LocationSummary(kNumInputs,
2711 kNumTemps, 2899 kNumTemps,
2712 LocationSummary::kCallOnSlowPath); 2900 LocationSummary::kCallOnSlowPath);
2713 summary->set_in(0, Location::RequiresFpuRegister()); 2901 summary->set_in(0, Location::RequiresFpuRegister());
2714 summary->set_out(Location::RequiresRegister()); 2902 summary->set_out(Location::RequiresRegister());
2715 return summary; 2903 return summary;
2716 } 2904 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 2945
2758 __ TryAllocate(compiler->float32x4_class(), 2946 __ TryAllocate(compiler->float32x4_class(),
2759 slow_path->entry_label(), 2947 slow_path->entry_label(),
2760 Assembler::kFarJump, 2948 Assembler::kFarJump,
2761 out_reg); 2949 out_reg);
2762 __ Bind(slow_path->exit_label()); 2950 __ Bind(slow_path->exit_label());
2763 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); 2951 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
2764 } 2952 }
2765 2953
2766 2954
2767 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { 2955 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2768 const intptr_t value_cid = value()->Type()->ToCid(); 2956 const intptr_t value_cid = value()->Type()->ToCid();
2769 const intptr_t kNumInputs = 1; 2957 const intptr_t kNumInputs = 1;
2770 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; 2958 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
2771 LocationSummary* summary = 2959 LocationSummary* summary =
2772 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2960 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2773 summary->set_in(0, Location::RequiresRegister()); 2961 summary->set_in(0, Location::RequiresRegister());
2774 if (kNumTemps > 0) { 2962 if (kNumTemps > 0) {
2775 ASSERT(kNumTemps == 1); 2963 ASSERT(kNumTemps == 1);
2776 summary->set_temp(0, Location::RequiresRegister()); 2964 summary->set_temp(0, Location::RequiresRegister());
2777 } 2965 }
(...skipping 12 matching lines...) Expand all
2790 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 2978 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2791 __ testl(value, Immediate(kSmiTagMask)); 2979 __ testl(value, Immediate(kSmiTagMask));
2792 __ j(ZERO, deopt); 2980 __ j(ZERO, deopt);
2793 __ CompareClassId(value, kFloat32x4Cid, temp); 2981 __ CompareClassId(value, kFloat32x4Cid, temp);
2794 __ j(NOT_EQUAL, deopt); 2982 __ j(NOT_EQUAL, deopt);
2795 } 2983 }
2796 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 2984 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
2797 } 2985 }
2798 2986
2799 2987
2800 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { 2988 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
2801 const intptr_t kNumInputs = 1; 2989 const intptr_t kNumInputs = 1;
2802 const intptr_t kNumTemps = 0; 2990 const intptr_t kNumTemps = 0;
2803 LocationSummary* summary = 2991 LocationSummary* summary =
2804 new LocationSummary(kNumInputs, 2992 new LocationSummary(kNumInputs,
2805 kNumTemps, 2993 kNumTemps,
2806 LocationSummary::kCallOnSlowPath); 2994 LocationSummary::kCallOnSlowPath);
2807 summary->set_in(0, Location::RequiresFpuRegister()); 2995 summary->set_in(0, Location::RequiresFpuRegister());
2808 summary->set_out(Location::RequiresRegister()); 2996 summary->set_out(Location::RequiresRegister());
2809 return summary; 2997 return summary;
2810 } 2998 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2851 3039
2852 __ TryAllocate(compiler->int32x4_class(), 3040 __ TryAllocate(compiler->int32x4_class(),
2853 slow_path->entry_label(), 3041 slow_path->entry_label(),
2854 Assembler::kFarJump, 3042 Assembler::kFarJump,
2855 out_reg); 3043 out_reg);
2856 __ Bind(slow_path->exit_label()); 3044 __ Bind(slow_path->exit_label());
2857 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); 3045 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
2858 } 3046 }
2859 3047
2860 3048
2861 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { 3049 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const {
2862 const intptr_t value_cid = value()->Type()->ToCid(); 3050 const intptr_t value_cid = value()->Type()->ToCid();
2863 const intptr_t kNumInputs = 1; 3051 const intptr_t kNumInputs = 1;
2864 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; 3052 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1;
2865 LocationSummary* summary = 3053 LocationSummary* summary =
2866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3054 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2867 summary->set_in(0, Location::RequiresRegister()); 3055 summary->set_in(0, Location::RequiresRegister());
2868 if (kNumTemps > 0) { 3056 if (kNumTemps > 0) {
2869 ASSERT(kNumTemps == 1); 3057 ASSERT(kNumTemps == 1);
2870 summary->set_temp(0, Location::RequiresRegister()); 3058 summary->set_temp(0, Location::RequiresRegister());
2871 } 3059 }
(...skipping 13 matching lines...) Expand all
2885 __ testl(value, Immediate(kSmiTagMask)); 3073 __ testl(value, Immediate(kSmiTagMask));
2886 __ j(ZERO, deopt); 3074 __ j(ZERO, deopt);
2887 __ CompareClassId(value, kInt32x4Cid, temp); 3075 __ CompareClassId(value, kInt32x4Cid, temp);
2888 __ j(NOT_EQUAL, deopt); 3076 __ j(NOT_EQUAL, deopt);
2889 } 3077 }
2890 __ movups(result, FieldAddress(value, Int32x4::value_offset())); 3078 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
2891 } 3079 }
2892 3080
2893 3081
2894 3082
2895 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { 3083 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
2896 const intptr_t kNumInputs = 2; 3084 const intptr_t kNumInputs = 2;
2897 const intptr_t kNumTemps = 0; 3085 const intptr_t kNumTemps = 0;
2898 LocationSummary* summary = 3086 LocationSummary* summary =
2899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3087 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2900 summary->set_in(0, Location::RequiresFpuRegister()); 3088 summary->set_in(0, Location::RequiresFpuRegister());
2901 summary->set_in(1, Location::RequiresFpuRegister()); 3089 summary->set_in(1, Location::RequiresFpuRegister());
2902 summary->set_out(Location::SameAsFirstInput()); 3090 summary->set_out(Location::SameAsFirstInput());
2903 return summary; 3091 return summary;
2904 } 3092 }
2905 3093
2906 3094
2907 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3095 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2908 XmmRegister left = locs()->in(0).fpu_reg(); 3096 XmmRegister left = locs()->in(0).fpu_reg();
2909 XmmRegister right = locs()->in(1).fpu_reg(); 3097 XmmRegister right = locs()->in(1).fpu_reg();
2910 3098
2911 ASSERT(locs()->out().fpu_reg() == left); 3099 ASSERT(locs()->out().fpu_reg() == left);
2912 3100
2913 switch (op_kind()) { 3101 switch (op_kind()) {
2914 case Token::kADD: __ addsd(left, right); break; 3102 case Token::kADD: __ addsd(left, right); break;
2915 case Token::kSUB: __ subsd(left, right); break; 3103 case Token::kSUB: __ subsd(left, right); break;
2916 case Token::kMUL: __ mulsd(left, right); break; 3104 case Token::kMUL: __ mulsd(left, right); break;
2917 case Token::kDIV: __ divsd(left, right); break; 3105 case Token::kDIV: __ divsd(left, right); break;
2918 default: UNREACHABLE(); 3106 default: UNREACHABLE();
2919 } 3107 }
2920 } 3108 }
2921 3109
2922 3110
2923 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { 3111 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
2924 const intptr_t kNumInputs = 2; 3112 const intptr_t kNumInputs = 2;
2925 const intptr_t kNumTemps = 0; 3113 const intptr_t kNumTemps = 0;
2926 LocationSummary* summary = 3114 LocationSummary* summary =
2927 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3115 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2928 summary->set_in(0, Location::RequiresFpuRegister()); 3116 summary->set_in(0, Location::RequiresFpuRegister());
2929 summary->set_in(1, Location::RequiresFpuRegister()); 3117 summary->set_in(1, Location::RequiresFpuRegister());
2930 summary->set_out(Location::SameAsFirstInput()); 3118 summary->set_out(Location::SameAsFirstInput());
2931 return summary; 3119 return summary;
2932 } 3120 }
2933 3121
2934 3122
2935 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3123 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2936 XmmRegister left = locs()->in(0).fpu_reg(); 3124 XmmRegister left = locs()->in(0).fpu_reg();
2937 XmmRegister right = locs()->in(1).fpu_reg(); 3125 XmmRegister right = locs()->in(1).fpu_reg();
2938 3126
2939 ASSERT(locs()->out().fpu_reg() == left); 3127 ASSERT(locs()->out().fpu_reg() == left);
2940 3128
2941 switch (op_kind()) { 3129 switch (op_kind()) {
2942 case Token::kADD: __ addps(left, right); break; 3130 case Token::kADD: __ addps(left, right); break;
2943 case Token::kSUB: __ subps(left, right); break; 3131 case Token::kSUB: __ subps(left, right); break;
2944 case Token::kMUL: __ mulps(left, right); break; 3132 case Token::kMUL: __ mulps(left, right); break;
2945 case Token::kDIV: __ divps(left, right); break; 3133 case Token::kDIV: __ divps(left, right); break;
2946 default: UNREACHABLE(); 3134 default: UNREACHABLE();
2947 } 3135 }
2948 } 3136 }
2949 3137
2950 3138
2951 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { 3139 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const {
2952 const intptr_t kNumInputs = 1; 3140 const intptr_t kNumInputs = 1;
2953 const intptr_t kNumTemps = 0; 3141 const intptr_t kNumTemps = 0;
2954 LocationSummary* summary = 3142 LocationSummary* summary =
2955 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3143 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2956 summary->set_in(0, Location::RequiresFpuRegister()); 3144 summary->set_in(0, Location::RequiresFpuRegister());
2957 summary->set_out(Location::SameAsFirstInput()); 3145 summary->set_out(Location::SameAsFirstInput());
2958 return summary; 3146 return summary;
2959 } 3147 }
2960 3148
2961 3149
(...skipping 21 matching lines...) Expand all
2983 break; 3171 break;
2984 case MethodRecognizer::kFloat32x4Shuffle: 3172 case MethodRecognizer::kFloat32x4Shuffle:
2985 case MethodRecognizer::kInt32x4Shuffle: 3173 case MethodRecognizer::kInt32x4Shuffle:
2986 __ shufps(value, value, Immediate(mask_)); 3174 __ shufps(value, value, Immediate(mask_));
2987 break; 3175 break;
2988 default: UNREACHABLE(); 3176 default: UNREACHABLE();
2989 } 3177 }
2990 } 3178 }
2991 3179
2992 3180
2993 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { 3181 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const {
2994 const intptr_t kNumInputs = 2; 3182 const intptr_t kNumInputs = 2;
2995 const intptr_t kNumTemps = 0; 3183 const intptr_t kNumTemps = 0;
2996 LocationSummary* summary = 3184 LocationSummary* summary =
2997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2998 summary->set_in(0, Location::RequiresFpuRegister()); 3186 summary->set_in(0, Location::RequiresFpuRegister());
2999 summary->set_in(1, Location::RequiresFpuRegister()); 3187 summary->set_in(1, Location::RequiresFpuRegister());
3000 summary->set_out(Location::SameAsFirstInput()); 3188 summary->set_out(Location::SameAsFirstInput());
3001 return summary; 3189 return summary;
3002 } 3190 }
3003 3191
3004 3192
3005 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3193 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3006 XmmRegister left = locs()->in(0).fpu_reg(); 3194 XmmRegister left = locs()->in(0).fpu_reg();
3007 XmmRegister right = locs()->in(1).fpu_reg(); 3195 XmmRegister right = locs()->in(1).fpu_reg();
3008 3196
3009 ASSERT(locs()->out().fpu_reg() == left); 3197 ASSERT(locs()->out().fpu_reg() == left);
3010 switch (op_kind()) { 3198 switch (op_kind()) {
3011 case MethodRecognizer::kFloat32x4ShuffleMix: 3199 case MethodRecognizer::kFloat32x4ShuffleMix:
3012 case MethodRecognizer::kInt32x4ShuffleMix: 3200 case MethodRecognizer::kInt32x4ShuffleMix:
3013 __ shufps(left, right, Immediate(mask_)); 3201 __ shufps(left, right, Immediate(mask_));
3014 break; 3202 break;
3015 default: UNREACHABLE(); 3203 default: UNREACHABLE();
3016 } 3204 }
3017 } 3205 }
3018 3206
3019 3207
3020 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { 3208 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const {
3021 const intptr_t kNumInputs = 1; 3209 const intptr_t kNumInputs = 1;
3022 const intptr_t kNumTemps = 0; 3210 const intptr_t kNumTemps = 0;
3023 LocationSummary* summary = 3211 LocationSummary* summary =
3024 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3212 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3025 summary->set_in(0, Location::RequiresFpuRegister()); 3213 summary->set_in(0, Location::RequiresFpuRegister());
3026 summary->set_out(Location::RequiresRegister()); 3214 summary->set_out(Location::RequiresRegister());
3027 return summary; 3215 return summary;
3028 } 3216 }
3029 3217
3030 3218
3031 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3219 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3032 XmmRegister value = locs()->in(0).fpu_reg(); 3220 XmmRegister value = locs()->in(0).fpu_reg();
3033 Register out = locs()->out().reg(); 3221 Register out = locs()->out().reg();
3034 3222
3035 __ movmskps(out, value); 3223 __ movmskps(out, value);
3036 __ SmiTag(out); 3224 __ SmiTag(out);
3037 } 3225 }
3038 3226
3039 3227
3040 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { 3228 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
3229 bool opt) const {
3041 const intptr_t kNumInputs = 4; 3230 const intptr_t kNumInputs = 4;
3042 const intptr_t kNumTemps = 0; 3231 const intptr_t kNumTemps = 0;
3043 LocationSummary* summary = 3232 LocationSummary* summary =
3044 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3233 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3045 summary->set_in(0, Location::RequiresFpuRegister()); 3234 summary->set_in(0, Location::RequiresFpuRegister());
3046 summary->set_in(1, Location::RequiresFpuRegister()); 3235 summary->set_in(1, Location::RequiresFpuRegister());
3047 summary->set_in(2, Location::RequiresFpuRegister()); 3236 summary->set_in(2, Location::RequiresFpuRegister());
3048 summary->set_in(3, Location::RequiresFpuRegister()); 3237 summary->set_in(3, Location::RequiresFpuRegister());
3049 summary->set_out(Location::SameAsFirstInput()); 3238 summary->set_out(Location::SameAsFirstInput());
3050 return summary; 3239 return summary;
(...skipping 16 matching lines...) Expand all
3067 __ cvtsd2ss(v0, v0); 3256 __ cvtsd2ss(v0, v0);
3068 __ movss(Address(ESP, 8), v0); 3257 __ movss(Address(ESP, 8), v0);
3069 __ movsd(v0, v3); 3258 __ movsd(v0, v3);
3070 __ cvtsd2ss(v0, v0); 3259 __ cvtsd2ss(v0, v0);
3071 __ movss(Address(ESP, 12), v0); 3260 __ movss(Address(ESP, 12), v0);
3072 __ movups(v0, Address(ESP, 0)); 3261 __ movups(v0, Address(ESP, 0));
3073 __ addl(ESP, Immediate(16)); 3262 __ addl(ESP, Immediate(16));
3074 } 3263 }
3075 3264
3076 3265
3077 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { 3266 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const {
3078 const intptr_t kNumInputs = 0; 3267 const intptr_t kNumInputs = 0;
3079 const intptr_t kNumTemps = 0; 3268 const intptr_t kNumTemps = 0;
3080 LocationSummary* summary = 3269 LocationSummary* summary =
3081 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3082 summary->set_out(Location::RequiresFpuRegister()); 3271 summary->set_out(Location::RequiresFpuRegister());
3083 return summary; 3272 return summary;
3084 } 3273 }
3085 3274
3086 3275
3087 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3276 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3088 XmmRegister value = locs()->out().fpu_reg(); 3277 XmmRegister value = locs()->out().fpu_reg();
3089 __ xorps(value, value); 3278 __ xorps(value, value);
3090 } 3279 }
3091 3280
3092 3281
3093 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { 3282 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const {
3094 const intptr_t kNumInputs = 1; 3283 const intptr_t kNumInputs = 1;
3095 const intptr_t kNumTemps = 0; 3284 const intptr_t kNumTemps = 0;
3096 LocationSummary* summary = 3285 LocationSummary* summary =
3097 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3286 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3098 summary->set_in(0, Location::RequiresFpuRegister()); 3287 summary->set_in(0, Location::RequiresFpuRegister());
3099 summary->set_out(Location::SameAsFirstInput()); 3288 summary->set_out(Location::SameAsFirstInput());
3100 return summary; 3289 return summary;
3101 } 3290 }
3102 3291
3103 3292
3104 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3293 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3105 XmmRegister value = locs()->out().fpu_reg(); 3294 XmmRegister value = locs()->out().fpu_reg();
3106 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); 3295 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg());
3107 // Convert to Float32. 3296 // Convert to Float32.
3108 __ cvtsd2ss(value, value); 3297 __ cvtsd2ss(value, value);
3109 // Splat across all lanes. 3298 // Splat across all lanes.
3110 __ shufps(value, value, Immediate(0x00)); 3299 __ shufps(value, value, Immediate(0x00));
3111 } 3300 }
3112 3301
3113 3302
3114 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { 3303 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const {
3115 const intptr_t kNumInputs = 2; 3304 const intptr_t kNumInputs = 2;
3116 const intptr_t kNumTemps = 0; 3305 const intptr_t kNumTemps = 0;
3117 LocationSummary* summary = 3306 LocationSummary* summary =
3118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3307 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3119 summary->set_in(0, Location::RequiresFpuRegister()); 3308 summary->set_in(0, Location::RequiresFpuRegister());
3120 summary->set_in(1, Location::RequiresFpuRegister()); 3309 summary->set_in(1, Location::RequiresFpuRegister());
3121 summary->set_out(Location::SameAsFirstInput()); 3310 summary->set_out(Location::SameAsFirstInput());
3122 return summary; 3311 return summary;
3123 } 3312 }
3124 3313
(...skipping 22 matching lines...) Expand all
3147 break; 3336 break;
3148 case MethodRecognizer::kFloat32x4LessThanOrEqual: 3337 case MethodRecognizer::kFloat32x4LessThanOrEqual:
3149 __ cmppsle(left, right); 3338 __ cmppsle(left, right);
3150 break; 3339 break;
3151 3340
3152 default: UNREACHABLE(); 3341 default: UNREACHABLE();
3153 } 3342 }
3154 } 3343 }
3155 3344
3156 3345
3157 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { 3346 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const {
3158 const intptr_t kNumInputs = 2; 3347 const intptr_t kNumInputs = 2;
3159 const intptr_t kNumTemps = 0; 3348 const intptr_t kNumTemps = 0;
3160 LocationSummary* summary = 3349 LocationSummary* summary =
3161 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3162 summary->set_in(0, Location::RequiresFpuRegister()); 3351 summary->set_in(0, Location::RequiresFpuRegister());
3163 summary->set_in(1, Location::RequiresFpuRegister()); 3352 summary->set_in(1, Location::RequiresFpuRegister());
3164 summary->set_out(Location::SameAsFirstInput()); 3353 summary->set_out(Location::SameAsFirstInput());
3165 return summary; 3354 return summary;
3166 } 3355 }
3167 3356
3168 3357
3169 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3358 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3170 XmmRegister left = locs()->in(0).fpu_reg(); 3359 XmmRegister left = locs()->in(0).fpu_reg();
3171 XmmRegister right = locs()->in(1).fpu_reg(); 3360 XmmRegister right = locs()->in(1).fpu_reg();
3172 3361
3173 ASSERT(locs()->out().fpu_reg() == left); 3362 ASSERT(locs()->out().fpu_reg() == left);
3174 3363
3175 switch (op_kind()) { 3364 switch (op_kind()) {
3176 case MethodRecognizer::kFloat32x4Min: 3365 case MethodRecognizer::kFloat32x4Min:
3177 __ minps(left, right); 3366 __ minps(left, right);
3178 break; 3367 break;
3179 case MethodRecognizer::kFloat32x4Max: 3368 case MethodRecognizer::kFloat32x4Max:
3180 __ maxps(left, right); 3369 __ maxps(left, right);
3181 break; 3370 break;
3182 default: UNREACHABLE(); 3371 default: UNREACHABLE();
3183 } 3372 }
3184 } 3373 }
3185 3374
3186 3375
3187 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { 3376 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const {
3188 const intptr_t kNumInputs = 2; 3377 const intptr_t kNumInputs = 2;
3189 const intptr_t kNumTemps = 0; 3378 const intptr_t kNumTemps = 0;
3190 LocationSummary* summary = 3379 LocationSummary* summary =
3191 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3380 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3192 summary->set_in(0, Location::RequiresFpuRegister()); 3381 summary->set_in(0, Location::RequiresFpuRegister());
3193 summary->set_in(1, Location::RequiresFpuRegister()); 3382 summary->set_in(1, Location::RequiresFpuRegister());
3194 summary->set_out(Location::SameAsFirstInput()); 3383 summary->set_out(Location::SameAsFirstInput());
3195 return summary; 3384 return summary;
3196 } 3385 }
3197 3386
3198 3387
3199 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3388 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3200 XmmRegister left = locs()->in(0).fpu_reg(); 3389 XmmRegister left = locs()->in(0).fpu_reg();
3201 XmmRegister right = locs()->in(1).fpu_reg(); 3390 XmmRegister right = locs()->in(1).fpu_reg();
3202 3391
3203 ASSERT(locs()->out().fpu_reg() == left); 3392 ASSERT(locs()->out().fpu_reg() == left);
3204 3393
3205 switch (op_kind()) { 3394 switch (op_kind()) {
3206 case MethodRecognizer::kFloat32x4Scale: 3395 case MethodRecognizer::kFloat32x4Scale:
3207 __ cvtsd2ss(left, left); 3396 __ cvtsd2ss(left, left);
3208 __ shufps(left, left, Immediate(0x00)); 3397 __ shufps(left, left, Immediate(0x00));
3209 __ mulps(left, right); 3398 __ mulps(left, right);
3210 break; 3399 break;
3211 default: UNREACHABLE(); 3400 default: UNREACHABLE();
3212 } 3401 }
3213 } 3402 }
3214 3403
3215 3404
3216 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { 3405 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const {
3217 const intptr_t kNumInputs = 1; 3406 const intptr_t kNumInputs = 1;
3218 const intptr_t kNumTemps = 0; 3407 const intptr_t kNumTemps = 0;
3219 LocationSummary* summary = 3408 LocationSummary* summary =
3220 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3409 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3221 summary->set_in(0, Location::RequiresFpuRegister()); 3410 summary->set_in(0, Location::RequiresFpuRegister());
3222 summary->set_out(Location::SameAsFirstInput()); 3411 summary->set_out(Location::SameAsFirstInput());
3223 return summary; 3412 return summary;
3224 } 3413 }
3225 3414
3226 3415
(...skipping 10 matching lines...) Expand all
3237 __ reciprocalps(left); 3426 __ reciprocalps(left);
3238 break; 3427 break;
3239 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 3428 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3240 __ rsqrtps(left); 3429 __ rsqrtps(left);
3241 break; 3430 break;
3242 default: UNREACHABLE(); 3431 default: UNREACHABLE();
3243 } 3432 }
3244 } 3433 }
3245 3434
3246 3435
3247 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { 3436 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const {
3248 const intptr_t kNumInputs = 1; 3437 const intptr_t kNumInputs = 1;
3249 const intptr_t kNumTemps = 0; 3438 const intptr_t kNumTemps = 0;
3250 LocationSummary* summary = 3439 LocationSummary* summary =
3251 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3440 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3252 summary->set_in(0, Location::RequiresFpuRegister()); 3441 summary->set_in(0, Location::RequiresFpuRegister());
3253 summary->set_out(Location::SameAsFirstInput()); 3442 summary->set_out(Location::SameAsFirstInput());
3254 return summary; 3443 return summary;
3255 } 3444 }
3256 3445
3257 3446
3258 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3447 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3259 XmmRegister left = locs()->in(0).fpu_reg(); 3448 XmmRegister left = locs()->in(0).fpu_reg();
3260 3449
3261 ASSERT(locs()->out().fpu_reg() == left); 3450 ASSERT(locs()->out().fpu_reg() == left);
3262 switch (op_kind()) { 3451 switch (op_kind()) {
3263 case MethodRecognizer::kFloat32x4Negate: 3452 case MethodRecognizer::kFloat32x4Negate:
3264 __ negateps(left); 3453 __ negateps(left);
3265 break; 3454 break;
3266 case MethodRecognizer::kFloat32x4Absolute: 3455 case MethodRecognizer::kFloat32x4Absolute:
3267 __ absps(left); 3456 __ absps(left);
3268 break; 3457 break;
3269 default: UNREACHABLE(); 3458 default: UNREACHABLE();
3270 } 3459 }
3271 } 3460 }
3272 3461
3273 3462
3274 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { 3463 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const {
3275 const intptr_t kNumInputs = 3; 3464 const intptr_t kNumInputs = 3;
3276 const intptr_t kNumTemps = 0; 3465 const intptr_t kNumTemps = 0;
3277 LocationSummary* summary = 3466 LocationSummary* summary =
3278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3467 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3279 summary->set_in(0, Location::RequiresFpuRegister()); 3468 summary->set_in(0, Location::RequiresFpuRegister());
3280 summary->set_in(1, Location::RequiresFpuRegister()); 3469 summary->set_in(1, Location::RequiresFpuRegister());
3281 summary->set_in(2, Location::RequiresFpuRegister()); 3470 summary->set_in(2, Location::RequiresFpuRegister());
3282 summary->set_out(Location::SameAsFirstInput()); 3471 summary->set_out(Location::SameAsFirstInput());
3283 return summary; 3472 return summary;
3284 } 3473 }
3285 3474
3286 3475
3287 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3476 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3288 XmmRegister left = locs()->in(0).fpu_reg(); 3477 XmmRegister left = locs()->in(0).fpu_reg();
3289 XmmRegister lower = locs()->in(1).fpu_reg(); 3478 XmmRegister lower = locs()->in(1).fpu_reg();
3290 XmmRegister upper = locs()->in(2).fpu_reg(); 3479 XmmRegister upper = locs()->in(2).fpu_reg();
3291 ASSERT(locs()->out().fpu_reg() == left); 3480 ASSERT(locs()->out().fpu_reg() == left);
3292 __ minps(left, upper); 3481 __ minps(left, upper);
3293 __ maxps(left, lower); 3482 __ maxps(left, lower);
3294 } 3483 }
3295 3484
3296 3485
3297 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { 3486 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const {
3298 const intptr_t kNumInputs = 2; 3487 const intptr_t kNumInputs = 2;
3299 const intptr_t kNumTemps = 0; 3488 const intptr_t kNumTemps = 0;
3300 LocationSummary* summary = 3489 LocationSummary* summary =
3301 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3490 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3302 summary->set_in(0, Location::RequiresFpuRegister()); 3491 summary->set_in(0, Location::RequiresFpuRegister());
3303 summary->set_in(1, Location::RequiresFpuRegister()); 3492 summary->set_in(1, Location::RequiresFpuRegister());
3304 summary->set_out(Location::SameAsFirstInput()); 3493 summary->set_out(Location::SameAsFirstInput());
3305 return summary; 3494 return summary;
3306 } 3495 }
3307 3496
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3355 __ movss(Address(ESP, 12), replacement); 3544 __ movss(Address(ESP, 12), replacement);
3356 // Move updated value into output register. 3545 // Move updated value into output register.
3357 __ movups(replacement, Address(ESP, 0)); 3546 __ movups(replacement, Address(ESP, 0));
3358 __ addl(ESP, Immediate(16)); 3547 __ addl(ESP, Immediate(16));
3359 break; 3548 break;
3360 default: UNREACHABLE(); 3549 default: UNREACHABLE();
3361 } 3550 }
3362 } 3551 }
3363 3552
3364 3553
3365 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { 3554 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const {
3366 const intptr_t kNumInputs = 1; 3555 const intptr_t kNumInputs = 1;
3367 const intptr_t kNumTemps = 0; 3556 const intptr_t kNumTemps = 0;
3368 LocationSummary* summary = 3557 LocationSummary* summary =
3369 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3558 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3370 summary->set_in(0, Location::RequiresFpuRegister()); 3559 summary->set_in(0, Location::RequiresFpuRegister());
3371 summary->set_out(Location::SameAsFirstInput()); 3560 summary->set_out(Location::SameAsFirstInput());
3372 return summary; 3561 return summary;
3373 } 3562 }
3374 3563
3375 3564
3376 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3565 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3377 // NOP. 3566 // NOP.
3378 } 3567 }
3379 3568
3380 3569
3381 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { 3570 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
3571 bool opt) const {
3382 const intptr_t kNumInputs = 4; 3572 const intptr_t kNumInputs = 4;
3383 const intptr_t kNumTemps = 0; 3573 const intptr_t kNumTemps = 0;
3384 LocationSummary* summary = 3574 LocationSummary* summary =
3385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3575 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3386 summary->set_in(0, Location::RequiresRegister()); 3576 summary->set_in(0, Location::RequiresRegister());
3387 summary->set_in(1, Location::RequiresRegister()); 3577 summary->set_in(1, Location::RequiresRegister());
3388 summary->set_in(2, Location::RequiresRegister()); 3578 summary->set_in(2, Location::RequiresRegister());
3389 summary->set_in(3, Location::RequiresRegister()); 3579 summary->set_in(3, Location::RequiresRegister());
3390 summary->set_out(Location::RequiresFpuRegister()); 3580 summary->set_out(Location::RequiresFpuRegister());
3391 return summary; 3581 return summary;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3433 __ jmp(&w_done); 3623 __ jmp(&w_done);
3434 __ Bind(&w_false); 3624 __ Bind(&w_false);
3435 __ movl(Address(ESP, 12), Immediate(0x0)); 3625 __ movl(Address(ESP, 12), Immediate(0x0));
3436 __ Bind(&w_done); 3626 __ Bind(&w_done);
3437 3627
3438 __ movups(result, Address(ESP, 0)); 3628 __ movups(result, Address(ESP, 0));
3439 __ addl(ESP, Immediate(16)); 3629 __ addl(ESP, Immediate(16));
3440 } 3630 }
3441 3631
3442 3632
3443 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { 3633 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const {
3444 const intptr_t kNumInputs = 1; 3634 const intptr_t kNumInputs = 1;
3445 const intptr_t kNumTemps = 0; 3635 const intptr_t kNumTemps = 0;
3446 LocationSummary* summary = 3636 LocationSummary* summary =
3447 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3637 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3448 summary->set_in(0, Location::RequiresFpuRegister()); 3638 summary->set_in(0, Location::RequiresFpuRegister());
3449 summary->set_out(Location::RequiresRegister()); 3639 summary->set_out(Location::RequiresRegister());
3450 return summary; 3640 return summary;
3451 } 3641 }
3452 3642
3453 3643
(...skipping 24 matching lines...) Expand all
3478 __ testl(result, result); 3668 __ testl(result, result);
3479 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); 3669 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
3480 __ LoadObject(result, Bool::False()); 3670 __ LoadObject(result, Bool::False());
3481 __ jmp(&done); 3671 __ jmp(&done);
3482 __ Bind(&non_zero); 3672 __ Bind(&non_zero);
3483 __ LoadObject(result, Bool::True()); 3673 __ LoadObject(result, Bool::True());
3484 __ Bind(&done); 3674 __ Bind(&done);
3485 } 3675 }
3486 3676
3487 3677
3488 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { 3678 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const {
3489 const intptr_t kNumInputs = 3; 3679 const intptr_t kNumInputs = 3;
3490 const intptr_t kNumTemps = 1; 3680 const intptr_t kNumTemps = 1;
3491 LocationSummary* summary = 3681 LocationSummary* summary =
3492 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3682 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3493 summary->set_in(0, Location::RequiresFpuRegister()); 3683 summary->set_in(0, Location::RequiresFpuRegister());
3494 summary->set_in(1, Location::RequiresFpuRegister()); 3684 summary->set_in(1, Location::RequiresFpuRegister());
3495 summary->set_in(2, Location::RequiresFpuRegister()); 3685 summary->set_in(2, Location::RequiresFpuRegister());
3496 summary->set_temp(0, Location::RequiresFpuRegister()); 3686 summary->set_temp(0, Location::RequiresFpuRegister());
3497 summary->set_out(Location::SameAsFirstInput()); 3687 summary->set_out(Location::SameAsFirstInput());
3498 return summary; 3688 return summary;
(...skipping 13 matching lines...) Expand all
3512 __ notps(temp); 3702 __ notps(temp);
3513 // mask = mask & trueValue. 3703 // mask = mask & trueValue.
3514 __ andps(mask, trueValue); 3704 __ andps(mask, trueValue);
3515 // temp = temp & falseValue. 3705 // temp = temp & falseValue.
3516 __ andps(temp, falseValue); 3706 __ andps(temp, falseValue);
3517 // out = mask | temp. 3707 // out = mask | temp.
3518 __ orps(mask, temp); 3708 __ orps(mask, temp);
3519 } 3709 }
3520 3710
3521 3711
3522 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { 3712 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const {
3523 const intptr_t kNumInputs = 2; 3713 const intptr_t kNumInputs = 2;
3524 const intptr_t kNumTemps = 0; 3714 const intptr_t kNumTemps = 0;
3525 LocationSummary* summary = 3715 LocationSummary* summary =
3526 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3716 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3527 summary->set_in(0, Location::RequiresFpuRegister()); 3717 summary->set_in(0, Location::RequiresFpuRegister());
3528 summary->set_in(1, Location::RequiresRegister()); 3718 summary->set_in(1, Location::RequiresRegister());
3529 summary->set_out(Location::SameAsFirstInput()); 3719 summary->set_out(Location::SameAsFirstInput());
3530 return summary; 3720 return summary;
3531 } 3721 }
3532 3722
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3568 break; 3758 break;
3569 default: UNREACHABLE(); 3759 default: UNREACHABLE();
3570 } 3760 }
3571 __ Bind(&exitPath); 3761 __ Bind(&exitPath);
3572 // Copy mask back to register. 3762 // Copy mask back to register.
3573 __ movups(mask, Address(ESP, 0)); 3763 __ movups(mask, Address(ESP, 0));
3574 __ addl(ESP, Immediate(16)); 3764 __ addl(ESP, Immediate(16));
3575 } 3765 }
3576 3766
3577 3767
3578 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { 3768 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const {
3579 const intptr_t kNumInputs = 1; 3769 const intptr_t kNumInputs = 1;
3580 const intptr_t kNumTemps = 0; 3770 const intptr_t kNumTemps = 0;
3581 LocationSummary* summary = 3771 LocationSummary* summary =
3582 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3772 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3583 summary->set_in(0, Location::RequiresFpuRegister()); 3773 summary->set_in(0, Location::RequiresFpuRegister());
3584 summary->set_out(Location::SameAsFirstInput()); 3774 summary->set_out(Location::SameAsFirstInput());
3585 return summary; 3775 return summary;
3586 } 3776 }
3587 3777
3588 3778
3589 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3779 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3590 // NOP. 3780 // NOP.
3591 } 3781 }
3592 3782
3593 3783
3594 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { 3784 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const {
3595 const intptr_t kNumInputs = 2; 3785 const intptr_t kNumInputs = 2;
3596 const intptr_t kNumTemps = 0; 3786 const intptr_t kNumTemps = 0;
3597 LocationSummary* summary = 3787 LocationSummary* summary =
3598 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3788 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3599 summary->set_in(0, Location::RequiresFpuRegister()); 3789 summary->set_in(0, Location::RequiresFpuRegister());
3600 summary->set_in(1, Location::RequiresFpuRegister()); 3790 summary->set_in(1, Location::RequiresFpuRegister());
3601 summary->set_out(Location::SameAsFirstInput()); 3791 summary->set_out(Location::SameAsFirstInput());
3602 return summary; 3792 return summary;
3603 } 3793 }
3604 3794
(...skipping 19 matching lines...) Expand all
3624 __ addpl(left, right); 3814 __ addpl(left, right);
3625 break; 3815 break;
3626 case Token::kSUB: 3816 case Token::kSUB:
3627 __ subpl(left, right); 3817 __ subpl(left, right);
3628 break; 3818 break;
3629 default: UNREACHABLE(); 3819 default: UNREACHABLE();
3630 } 3820 }
3631 } 3821 }
3632 3822
3633 3823
3634 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { 3824 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
3635 if ((kind() == MethodRecognizer::kMathSin) || 3825 if ((kind() == MethodRecognizer::kMathSin) ||
3636 (kind() == MethodRecognizer::kMathCos)) { 3826 (kind() == MethodRecognizer::kMathCos)) {
3637 const intptr_t kNumInputs = 1; 3827 const intptr_t kNumInputs = 1;
3638 const intptr_t kNumTemps = 0; 3828 const intptr_t kNumTemps = 0;
3639 LocationSummary* summary = 3829 LocationSummary* summary =
3640 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 3830 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3641 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 3831 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
3642 summary->set_out(Location::FpuRegisterLocation(XMM1)); 3832 summary->set_out(Location::FpuRegisterLocation(XMM1));
3643 return summary; 3833 return summary;
3644 } 3834 }
(...skipping 15 matching lines...) Expand all
3660 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 3850 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
3661 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 3851 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
3662 __ CallRuntime(TargetFunction(), InputCount()); 3852 __ CallRuntime(TargetFunction(), InputCount());
3663 __ fstpl(Address(ESP, 0)); 3853 __ fstpl(Address(ESP, 0));
3664 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); 3854 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0));
3665 __ leave(); 3855 __ leave();
3666 } 3856 }
3667 } 3857 }
3668 3858
3669 3859
3670 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3860 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
3671 if (result_cid() == kDoubleCid) { 3861 if (result_cid() == kDoubleCid) {
3672 const intptr_t kNumInputs = 2; 3862 const intptr_t kNumInputs = 2;
3673 const intptr_t kNumTemps = 1; 3863 const intptr_t kNumTemps = 1;
3674 LocationSummary* summary = 3864 LocationSummary* summary =
3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3865 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3676 summary->set_in(0, Location::RequiresFpuRegister()); 3866 summary->set_in(0, Location::RequiresFpuRegister());
3677 summary->set_in(1, Location::RequiresFpuRegister()); 3867 summary->set_in(1, Location::RequiresFpuRegister());
3678 // Reuse the left register so that code can be made shorter. 3868 // Reuse the left register so that code can be made shorter.
3679 summary->set_out(Location::SameAsFirstInput()); 3869 summary->set_out(Location::SameAsFirstInput());
3680 summary->set_temp(0, Location::RequiresRegister()); 3870 summary->set_temp(0, Location::RequiresRegister());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3748 __ cmpl(left, right); 3938 __ cmpl(left, right);
3749 ASSERT(result == left); 3939 ASSERT(result == left);
3750 if (is_min) { 3940 if (is_min) {
3751 __ cmovgel(result, right); 3941 __ cmovgel(result, right);
3752 } else { 3942 } else {
3753 __ cmovlessl(result, right); 3943 __ cmovlessl(result, right);
3754 } 3944 }
3755 } 3945 }
3756 3946
3757 3947
3758 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3948 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
3759 const intptr_t kNumInputs = 1; 3949 const intptr_t kNumInputs = 1;
3760 return LocationSummary::Make(kNumInputs, 3950 return LocationSummary::Make(kNumInputs,
3761 Location::SameAsFirstInput(), 3951 Location::SameAsFirstInput(),
3762 LocationSummary::kNoCall); 3952 LocationSummary::kNoCall);
3763 } 3953 }
3764 3954
3765 3955
3766 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3956 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3767 Register value = locs()->in(0).reg(); 3957 Register value = locs()->in(0).reg();
3768 ASSERT(value == locs()->out().reg()); 3958 ASSERT(value == locs()->out().reg());
3769 switch (op_kind()) { 3959 switch (op_kind()) {
3770 case Token::kNEGATE: { 3960 case Token::kNEGATE: {
3771 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3961 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3772 kDeoptUnaryOp); 3962 kDeoptUnaryOp);
3773 __ negl(value); 3963 __ negl(value);
3774 __ j(OVERFLOW, deopt); 3964 __ j(OVERFLOW, deopt);
3775 break; 3965 break;
3776 } 3966 }
3777 case Token::kBIT_NOT: 3967 case Token::kBIT_NOT:
3778 __ notl(value); 3968 __ notl(value);
3779 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 3969 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
3780 break; 3970 break;
3781 default: 3971 default:
3782 UNREACHABLE(); 3972 UNREACHABLE();
3783 } 3973 }
3784 } 3974 }
3785 3975
3786 3976
3787 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { 3977 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3788 const intptr_t kNumInputs = 1; 3978 const intptr_t kNumInputs = 1;
3789 const intptr_t kNumTemps = 0; 3979 const intptr_t kNumTemps = 0;
3790 LocationSummary* summary = 3980 LocationSummary* summary =
3791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3981 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3792 summary->set_in(0, Location::RequiresFpuRegister()); 3982 summary->set_in(0, Location::RequiresFpuRegister());
3793 summary->set_out(Location::SameAsFirstInput()); 3983 summary->set_out(Location::SameAsFirstInput());
3794 return summary; 3984 return summary;
3795 } 3985 }
3796 3986
3797 3987
3798 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3988 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3799 XmmRegister value = locs()->in(0).fpu_reg(); 3989 XmmRegister value = locs()->in(0).fpu_reg();
3800 ASSERT(locs()->out().fpu_reg() == value); 3990 ASSERT(locs()->out().fpu_reg() == value);
3801 __ DoubleNegate(value); 3991 __ DoubleNegate(value);
3802 } 3992 }
3803 3993
3804 3994
3805 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { 3995 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
3806 const intptr_t kNumInputs = 1; 3996 const intptr_t kNumInputs = 1;
3807 const intptr_t kNumTemps = 0; 3997 const intptr_t kNumTemps = 0;
3808 LocationSummary* result = 3998 LocationSummary* result =
3809 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3999 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3810 result->set_in(0, Location::WritableRegister()); 4000 result->set_in(0, Location::WritableRegister());
3811 result->set_out(Location::RequiresFpuRegister()); 4001 result->set_out(Location::RequiresFpuRegister());
3812 return result; 4002 return result;
3813 } 4003 }
3814 4004
3815 4005
3816 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4006 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3817 Register value = locs()->in(0).reg(); 4007 Register value = locs()->in(0).reg();
3818 FpuRegister result = locs()->out().fpu_reg(); 4008 FpuRegister result = locs()->out().fpu_reg();
3819 __ SmiUntag(value); 4009 __ SmiUntag(value);
3820 __ cvtsi2sd(result, value); 4010 __ cvtsi2sd(result, value);
3821 } 4011 }
3822 4012
3823 4013
3824 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 4014 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
3825 const intptr_t kNumInputs = 1; 4015 const intptr_t kNumInputs = 1;
3826 const intptr_t kNumTemps = 0; 4016 const intptr_t kNumTemps = 0;
3827 LocationSummary* result = 4017 LocationSummary* result =
3828 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4018 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3829 result->set_in(0, Location::RegisterLocation(ECX)); 4019 result->set_in(0, Location::RegisterLocation(ECX));
3830 result->set_out(Location::RegisterLocation(EAX)); 4020 result->set_out(Location::RegisterLocation(EAX));
3831 return result; 4021 return result;
3832 } 4022 }
3833 4023
3834 4024
(...skipping 23 matching lines...) Expand all
3858 compiler->GenerateStaticCall(deopt_id(), 4048 compiler->GenerateStaticCall(deopt_id(),
3859 instance_call()->token_pos(), 4049 instance_call()->token_pos(),
3860 target, 4050 target,
3861 kNumberOfArguments, 4051 kNumberOfArguments,
3862 Object::null_array(), // No argument names., 4052 Object::null_array(), // No argument names.,
3863 locs()); 4053 locs());
3864 __ Bind(&done); 4054 __ Bind(&done);
3865 } 4055 }
3866 4056
3867 4057
3868 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 4058 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
3869 const intptr_t kNumInputs = 1; 4059 const intptr_t kNumInputs = 1;
3870 const intptr_t kNumTemps = 0; 4060 const intptr_t kNumTemps = 0;
3871 LocationSummary* result = new LocationSummary( 4061 LocationSummary* result = new LocationSummary(
3872 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4062 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3873 result->set_in(0, Location::RequiresFpuRegister()); 4063 result->set_in(0, Location::RequiresFpuRegister());
3874 result->set_out(Location::RequiresRegister()); 4064 result->set_out(Location::RequiresRegister());
3875 return result; 4065 return result;
3876 } 4066 }
3877 4067
3878 4068
3879 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4069 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3880 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 4070 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
3881 Register result = locs()->out().reg(); 4071 Register result = locs()->out().reg();
3882 XmmRegister value = locs()->in(0).fpu_reg(); 4072 XmmRegister value = locs()->in(0).fpu_reg();
3883 __ cvttsd2si(result, value); 4073 __ cvttsd2si(result, value);
3884 // Check for overflow and that it fits into Smi. 4074 // Check for overflow and that it fits into Smi.
3885 __ cmpl(result, Immediate(0xC0000000)); 4075 __ cmpl(result, Immediate(0xC0000000));
3886 __ j(NEGATIVE, deopt); 4076 __ j(NEGATIVE, deopt);
3887 __ SmiTag(result); 4077 __ SmiTag(result);
3888 } 4078 }
3889 4079
3890 4080
3891 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 4081 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
3892 const intptr_t kNumInputs = 1; 4082 const intptr_t kNumInputs = 1;
3893 const intptr_t kNumTemps = 0; 4083 const intptr_t kNumTemps = 0;
3894 LocationSummary* result = 4084 LocationSummary* result =
3895 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4085 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3896 result->set_in(0, Location::RequiresFpuRegister()); 4086 result->set_in(0, Location::RequiresFpuRegister());
3897 result->set_out(Location::RequiresFpuRegister()); 4087 result->set_out(Location::RequiresFpuRegister());
3898 return result; 4088 return result;
3899 } 4089 }
3900 4090
3901 4091
3902 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4092 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3903 XmmRegister value = locs()->in(0).fpu_reg(); 4093 XmmRegister value = locs()->in(0).fpu_reg();
3904 XmmRegister result = locs()->out().fpu_reg(); 4094 XmmRegister result = locs()->out().fpu_reg();
3905 switch (recognized_kind()) { 4095 switch (recognized_kind()) {
3906 case MethodRecognizer::kDoubleTruncate: 4096 case MethodRecognizer::kDoubleTruncate:
3907 __ roundsd(result, value, Assembler::kRoundToZero); 4097 __ roundsd(result, value, Assembler::kRoundToZero);
3908 break; 4098 break;
3909 case MethodRecognizer::kDoubleFloor: 4099 case MethodRecognizer::kDoubleFloor:
3910 __ roundsd(result, value, Assembler::kRoundDown); 4100 __ roundsd(result, value, Assembler::kRoundDown);
3911 break; 4101 break;
3912 case MethodRecognizer::kDoubleCeil: 4102 case MethodRecognizer::kDoubleCeil:
3913 __ roundsd(result, value, Assembler::kRoundUp); 4103 __ roundsd(result, value, Assembler::kRoundUp);
3914 break; 4104 break;
3915 default: 4105 default:
3916 UNREACHABLE(); 4106 UNREACHABLE();
3917 } 4107 }
3918 } 4108 }
3919 4109
3920 4110
3921 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 4111 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
3922 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4112 ASSERT((InputCount() == 1) || (InputCount() == 2));
3923 const intptr_t kNumTemps = 0; 4113 const intptr_t kNumTemps = 0;
3924 LocationSummary* result = 4114 LocationSummary* result =
3925 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4115 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3926 result->set_in(0, Location::FpuRegisterLocation(XMM1)); 4116 result->set_in(0, Location::FpuRegisterLocation(XMM1));
3927 if (InputCount() == 2) { 4117 if (InputCount() == 2) {
3928 result->set_in(1, Location::FpuRegisterLocation(XMM2)); 4118 result->set_in(1, Location::FpuRegisterLocation(XMM2));
3929 } 4119 }
3930 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4120 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3931 result->AddTemp(Location::RegisterLocation(EAX)); 4121 result->AddTemp(Location::RegisterLocation(EAX));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3982 } 4172 }
3983 __ Bind(&do_call); 4173 __ Bind(&do_call);
3984 __ CallRuntime(TargetFunction(), InputCount()); 4174 __ CallRuntime(TargetFunction(), InputCount());
3985 __ fstpl(Address(ESP, 0)); 4175 __ fstpl(Address(ESP, 0));
3986 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); 4176 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0));
3987 __ Bind(&skip_call); 4177 __ Bind(&skip_call);
3988 __ leave(); 4178 __ leave();
3989 } 4179 }
3990 4180
3991 4181
3992 LocationSummary* MergedMathInstr::MakeLocationSummary() const { 4182 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
3993 if (kind() == MergedMathInstr::kTruncDivMod) { 4183 if (kind() == MergedMathInstr::kTruncDivMod) {
3994 const intptr_t kNumInputs = 2; 4184 const intptr_t kNumInputs = 2;
3995 const intptr_t kNumTemps = 1; 4185 const intptr_t kNumTemps = 1;
3996 LocationSummary* summary = 4186 LocationSummary* summary =
3997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4187 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3998 // Both inputs must be writable because they will be untagged. 4188 // Both inputs must be writable because they will be untagged.
3999 summary->set_in(0, Location::RegisterLocation(EAX)); 4189 summary->set_in(0, Location::RegisterLocation(EAX));
4000 summary->set_in(1, Location::WritableRegister()); 4190 summary->set_in(1, Location::WritableRegister());
4001 summary->set_out(Location::RequiresRegister()); 4191 summary->set_out(Location::RequiresRegister());
4002 // Will be used for sign extension and division. 4192 // Will be used for sign extension and division.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos))); 4322 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos)));
4133 __ movsd(sin_address, XMM0); 4323 __ movsd(sin_address, XMM0);
4134 __ movsd(cos_address, XMM1); 4324 __ movsd(cos_address, XMM1);
4135 return; 4325 return;
4136 } 4326 }
4137 4327
4138 UNIMPLEMENTED(); 4328 UNIMPLEMENTED();
4139 } 4329 }
4140 4330
4141 4331
4142 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 4332 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4333 bool opt) const {
4143 return MakeCallSummary(); 4334 return MakeCallSummary();
4144 } 4335 }
4145 4336
4146 4337
4147 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4338 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4148 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4339 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4149 kDeoptPolymorphicInstanceCallTestFail); 4340 kDeoptPolymorphicInstanceCallTestFail);
4150 if (ic_data().NumberOfChecks() == 0) { 4341 if (ic_data().NumberOfChecks() == 0) {
4151 __ jmp(deopt); 4342 __ jmp(deopt);
4152 return; 4343 return;
(...skipping 22 matching lines...) Expand all
4175 EDI, // Class id register. 4366 EDI, // Class id register.
4176 instance_call()->ArgumentCount(), 4367 instance_call()->ArgumentCount(),
4177 instance_call()->argument_names(), 4368 instance_call()->argument_names(),
4178 deopt, 4369 deopt,
4179 deopt_id(), 4370 deopt_id(),
4180 instance_call()->token_pos(), 4371 instance_call()->token_pos(),
4181 locs()); 4372 locs());
4182 } 4373 }
4183 4374
4184 4375
4185 LocationSummary* BranchInstr::MakeLocationSummary() const { 4376 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
4186 UNREACHABLE(); 4377 comparison()->InitializeLocationSummary(opt);
4187 return NULL; 4378 // Branches don't produce a result.
4379 comparison()->locs()->set_out(Location::NoLocation());
4380 return comparison()->locs();
4188 } 4381 }
4189 4382
4190 4383
4191 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4384 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4192 comparison()->EmitBranchCode(compiler, this); 4385 comparison()->EmitBranchCode(compiler, this);
4193 } 4386 }
4194 4387
4195 4388
4196 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 4389 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
4197 const intptr_t kNumInputs = 1; 4390 const intptr_t kNumInputs = 1;
4198 const intptr_t kNumTemps = 0; 4391 const intptr_t kNumTemps = 0;
4199 LocationSummary* summary = 4392 LocationSummary* summary =
4200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4393 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4201 summary->set_in(0, Location::RequiresRegister()); 4394 summary->set_in(0, Location::RequiresRegister());
4202 if (!IsNullCheck()) { 4395 if (!IsNullCheck()) {
4203 summary->AddTemp(Location::RequiresRegister()); 4396 summary->AddTemp(Location::RequiresRegister());
4204 } 4397 }
4205 return summary; 4398 return summary;
4206 } 4399 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4246 __ j(EQUAL, &is_ok, Assembler::kNearJump); 4439 __ j(EQUAL, &is_ok, Assembler::kNearJump);
4247 } else { 4440 } else {
4248 __ j(EQUAL, &is_ok); 4441 __ j(EQUAL, &is_ok);
4249 } 4442 }
4250 } 4443 }
4251 } 4444 }
4252 __ Bind(&is_ok); 4445 __ Bind(&is_ok);
4253 } 4446 }
4254 4447
4255 4448
4256 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { 4449 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const {
4257 const intptr_t kNumInputs = 1; 4450 const intptr_t kNumInputs = 1;
4258 const intptr_t kNumTemps = 0; 4451 const intptr_t kNumTemps = 0;
4259 LocationSummary* summary = 4452 LocationSummary* summary =
4260 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4453 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4261 summary->set_in(0, Location::RequiresRegister()); 4454 summary->set_in(0, Location::RequiresRegister());
4262 return summary; 4455 return summary;
4263 } 4456 }
4264 4457
4265 4458
4266 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4459 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4267 Register value = locs()->in(0).reg(); 4460 Register value = locs()->in(0).reg();
4268 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4461 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4269 kDeoptCheckSmi); 4462 kDeoptCheckSmi);
4270 __ testl(value, Immediate(kSmiTagMask)); 4463 __ testl(value, Immediate(kSmiTagMask));
4271 __ j(NOT_ZERO, deopt); 4464 __ j(NOT_ZERO, deopt);
4272 } 4465 }
4273 4466
4274 4467
4275 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 4468 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const {
4276 const intptr_t kNumInputs = 2; 4469 const intptr_t kNumInputs = 2;
4277 const intptr_t kNumTemps = 0; 4470 const intptr_t kNumTemps = 0;
4278 LocationSummary* locs = 4471 LocationSummary* locs =
4279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4472 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4280 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 4473 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
4281 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); 4474 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
4282 return locs; 4475 return locs;
4283 } 4476 }
4284 4477
4285 4478
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4318 __ j(ABOVE_EQUAL, deopt); 4511 __ j(ABOVE_EQUAL, deopt);
4319 } else { 4512 } else {
4320 Register length = length_loc.reg(); 4513 Register length = length_loc.reg();
4321 Register index = index_loc.reg(); 4514 Register index = index_loc.reg();
4322 __ cmpl(index, length); 4515 __ cmpl(index, length);
4323 __ j(ABOVE_EQUAL, deopt); 4516 __ j(ABOVE_EQUAL, deopt);
4324 } 4517 }
4325 } 4518 }
4326 4519
4327 4520
4328 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { 4521 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const {
4329 const intptr_t kNumInputs = 1; 4522 const intptr_t kNumInputs = 1;
4330 const intptr_t value_cid = value()->Type()->ToCid(); 4523 const intptr_t value_cid = value()->Type()->ToCid();
4331 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); 4524 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid));
4332 const bool needs_writable_input = (value_cid == kSmiCid); 4525 const bool needs_writable_input = (value_cid == kSmiCid);
4333 const intptr_t kNumTemps = needs_temp ? 1 : 0; 4526 const intptr_t kNumTemps = needs_temp ? 1 : 0;
4334 LocationSummary* summary = 4527 LocationSummary* summary =
4335 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4528 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4336 summary->set_in(0, needs_writable_input 4529 summary->set_in(0, needs_writable_input
4337 ? Location::WritableRegister() 4530 ? Location::WritableRegister()
4338 : Location::RequiresRegister()); 4531 : Location::RequiresRegister());
(...skipping 27 matching lines...) Expand all
4366 __ Bind(&is_smi); 4559 __ Bind(&is_smi);
4367 __ movl(temp, value); 4560 __ movl(temp, value);
4368 __ SmiUntag(temp); 4561 __ SmiUntag(temp);
4369 __ movd(result, temp); 4562 __ movd(result, temp);
4370 __ pmovsxdq(result, result); 4563 __ pmovsxdq(result, result);
4371 __ Bind(&done); 4564 __ Bind(&done);
4372 } 4565 }
4373 } 4566 }
4374 4567
4375 4568
4376 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { 4569 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const {
4377 const intptr_t kNumInputs = 1; 4570 const intptr_t kNumInputs = 1;
4378 const intptr_t kNumTemps = 2; 4571 const intptr_t kNumTemps = 2;
4379 LocationSummary* summary = 4572 LocationSummary* summary =
4380 new LocationSummary(kNumInputs, 4573 new LocationSummary(kNumInputs,
4381 kNumTemps, 4574 kNumTemps,
4382 LocationSummary::kCallOnSlowPath); 4575 LocationSummary::kCallOnSlowPath);
4383 summary->set_in(0, Location::RequiresFpuRegister()); 4576 summary->set_in(0, Location::RequiresFpuRegister());
4384 summary->set_temp(0, Location::RegisterLocation(EAX)); 4577 summary->set_temp(0, Location::RegisterLocation(EAX));
4385 summary->set_temp(1, Location::RegisterLocation(EDX)); 4578 summary->set_temp(1, Location::RegisterLocation(EDX));
4386 // TODO(fschneider): Save one temp by using result register as a temp. 4579 // TODO(fschneider): Save one temp by using result register as a temp.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4454 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), 4647 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
4455 slow_path->entry_label(), 4648 slow_path->entry_label(),
4456 Assembler::kFarJump, 4649 Assembler::kFarJump,
4457 out_reg); 4650 out_reg);
4458 __ Bind(slow_path->exit_label()); 4651 __ Bind(slow_path->exit_label());
4459 __ movsd(FieldAddress(out_reg, Mint::value_offset()), value); 4652 __ movsd(FieldAddress(out_reg, Mint::value_offset()), value);
4460 __ Bind(&done); 4653 __ Bind(&done);
4461 } 4654 }
4462 4655
4463 4656
4464 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 4657 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const {
4465 const intptr_t kNumInputs = 2; 4658 const intptr_t kNumInputs = 2;
4466 switch (op_kind()) { 4659 switch (op_kind()) {
4467 case Token::kBIT_AND: 4660 case Token::kBIT_AND:
4468 case Token::kBIT_OR: 4661 case Token::kBIT_OR:
4469 case Token::kBIT_XOR: { 4662 case Token::kBIT_XOR: {
4470 const intptr_t kNumTemps = 4663 const intptr_t kNumTemps =
4471 FLAG_throw_on_javascript_int_overflow ? 1 : 0; 4664 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
4472 LocationSummary* summary = 4665 LocationSummary* summary =
4473 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4666 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4474 summary->set_in(0, Location::RequiresFpuRegister()); 4667 summary->set_in(0, Location::RequiresFpuRegister());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 } 4737 }
4545 default: UNREACHABLE(); 4738 default: UNREACHABLE();
4546 } 4739 }
4547 if (FLAG_throw_on_javascript_int_overflow) { 4740 if (FLAG_throw_on_javascript_int_overflow) {
4548 Register tmp = locs()->temp(0).reg(); 4741 Register tmp = locs()->temp(0).reg();
4549 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp); 4742 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
4550 } 4743 }
4551 } 4744 }
4552 4745
4553 4746
4554 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { 4747 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const {
4555 const intptr_t kNumInputs = 2; 4748 const intptr_t kNumInputs = 2;
4556 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; 4749 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
4557 LocationSummary* summary = 4750 LocationSummary* summary =
4558 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4751 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4559 summary->set_in(0, Location::RequiresFpuRegister()); 4752 summary->set_in(0, Location::RequiresFpuRegister());
4560 summary->set_in(1, Location::RegisterLocation(ECX)); 4753 summary->set_in(1, Location::RegisterLocation(ECX));
4561 summary->set_temp(0, Location::RequiresRegister()); 4754 summary->set_temp(0, Location::RequiresRegister());
4562 if (op_kind() == Token::kSHL) { 4755 if (op_kind() == Token::kSHL) {
4563 summary->set_temp(1, Location::RequiresRegister()); 4756 summary->set_temp(1, Location::RequiresRegister());
4564 } 4757 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4618 __ movq(left, Address(ESP, 0)); 4811 __ movq(left, Address(ESP, 0));
4619 __ addl(ESP, Immediate(2 * kWordSize)); 4812 __ addl(ESP, Immediate(2 * kWordSize));
4620 __ Bind(&done); 4813 __ Bind(&done);
4621 if (FLAG_throw_on_javascript_int_overflow) { 4814 if (FLAG_throw_on_javascript_int_overflow) {
4622 Register tmp = locs()->temp(0).reg(); 4815 Register tmp = locs()->temp(0).reg();
4623 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp); 4816 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
4624 } 4817 }
4625 } 4818 }
4626 4819
4627 4820
4628 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { 4821 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const {
4629 const intptr_t kNumInputs = 1; 4822 const intptr_t kNumInputs = 1;
4630 const intptr_t kNumTemps = 4823 const intptr_t kNumTemps =
4631 FLAG_throw_on_javascript_int_overflow ? 1 : 0; 4824 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
4632 LocationSummary* summary = 4825 LocationSummary* summary =
4633 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4826 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4634 summary->set_in(0, Location::RequiresFpuRegister()); 4827 summary->set_in(0, Location::RequiresFpuRegister());
4635 summary->set_out(Location::SameAsFirstInput()); 4828 summary->set_out(Location::SameAsFirstInput());
4636 if (FLAG_throw_on_javascript_int_overflow) { 4829 if (FLAG_throw_on_javascript_int_overflow) {
4637 summary->set_temp(0, Location::RequiresRegister()); 4830 summary->set_temp(0, Location::RequiresRegister());
4638 } 4831 }
(...skipping 12 matching lines...) Expand all
4651 } 4844 }
4652 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 4845 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
4653 __ pxor(value, XMM0); 4846 __ pxor(value, XMM0);
4654 if (FLAG_throw_on_javascript_int_overflow) { 4847 if (FLAG_throw_on_javascript_int_overflow) {
4655 Register tmp = locs()->temp(0).reg(); 4848 Register tmp = locs()->temp(0).reg();
4656 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); 4849 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp);
4657 } 4850 }
4658 } 4851 }
4659 4852
4660 4853
4661 LocationSummary* ThrowInstr::MakeLocationSummary() const { 4854 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const {
4662 return new LocationSummary(0, 0, LocationSummary::kCall); 4855 return new LocationSummary(0, 0, LocationSummary::kCall);
4663 } 4856 }
4664 4857
4665 4858
4666 4859
4667 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4860 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4668 compiler->GenerateRuntimeCall(token_pos(), 4861 compiler->GenerateRuntimeCall(token_pos(),
4669 deopt_id(), 4862 deopt_id(),
4670 kThrowRuntimeEntry, 4863 kThrowRuntimeEntry,
4671 1, 4864 1,
4672 locs()); 4865 locs());
4673 __ int3(); 4866 __ int3();
4674 } 4867 }
4675 4868
4676 4869
4677 LocationSummary* ReThrowInstr::MakeLocationSummary() const { 4870 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const {
4678 return new LocationSummary(0, 0, LocationSummary::kCall); 4871 return new LocationSummary(0, 0, LocationSummary::kCall);
4679 } 4872 }
4680 4873
4681 4874
4682 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4875 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4683 compiler->SetNeedsStacktrace(catch_try_index()); 4876 compiler->SetNeedsStacktrace(catch_try_index());
4684 compiler->GenerateRuntimeCall(token_pos(), 4877 compiler->GenerateRuntimeCall(token_pos(),
4685 deopt_id(), 4878 deopt_id(),
4686 kReThrowRuntimeEntry, 4879 kReThrowRuntimeEntry,
4687 2, 4880 2,
(...skipping 19 matching lines...) Expand all
4707 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4900 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4708 deopt_id_, 4901 deopt_id_,
4709 Scanner::kDummyTokenIndex); 4902 Scanner::kDummyTokenIndex);
4710 } 4903 }
4711 if (HasParallelMove()) { 4904 if (HasParallelMove()) {
4712 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4905 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4713 } 4906 }
4714 } 4907 }
4715 4908
4716 4909
4717 LocationSummary* GotoInstr::MakeLocationSummary() const { 4910 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const {
4718 return new LocationSummary(0, 0, LocationSummary::kNoCall); 4911 return new LocationSummary(0, 0, LocationSummary::kNoCall);
4719 } 4912 }
4720 4913
4721 4914
4722 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4915 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4723 if (!compiler->is_optimizing()) { 4916 if (!compiler->is_optimizing()) {
4724 compiler->EmitEdgeCounter(); 4917 compiler->EmitEdgeCounter();
4725 // Add a deoptimization descriptor for deoptimizing instructions that 4918 // Add a deoptimization descriptor for deoptimizing instructions that
4726 // may be inserted before this instruction. This descriptor points 4919 // may be inserted before this instruction. This descriptor points
4727 // after the edge counter for uniformity with ARM and MIPS, where we can 4920 // after the edge counter for uniformity with ARM and MIPS, where we can
4728 // reuse pattern matching that matches backwards from the end of the 4921 // reuse pattern matching that matches backwards from the end of the
4729 // pattern. 4922 // pattern.
4730 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4923 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4731 GetDeoptId(), 4924 GetDeoptId(),
4732 Scanner::kDummyTokenIndex); 4925 Scanner::kDummyTokenIndex);
4733 } 4926 }
4734 if (HasParallelMove()) { 4927 if (HasParallelMove()) {
4735 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4928 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4736 } 4929 }
4737 4930
4738 // We can fall through if the successor is the next block in the list. 4931 // We can fall through if the successor is the next block in the list.
4739 // Otherwise, we need a jump. 4932 // Otherwise, we need a jump.
4740 if (!compiler->CanFallThroughTo(successor())) { 4933 if (!compiler->CanFallThroughTo(successor())) {
4741 __ jmp(compiler->GetJumpLabel(successor())); 4934 __ jmp(compiler->GetJumpLabel(successor()));
4742 } 4935 }
4743 } 4936 }
4744 4937
4745 4938
4746 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 4939 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
4747 return LocationSummary::Make(0, 4940 return LocationSummary::Make(0,
4748 Location::RequiresRegister(), 4941 Location::RequiresRegister(),
4749 LocationSummary::kNoCall); 4942 LocationSummary::kNoCall);
4750 } 4943 }
4751 4944
4752 4945
4753 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4946 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4754 __ MoveRegister(locs()->out().reg(), CTX); 4947 __ MoveRegister(locs()->out().reg(), CTX);
4755 } 4948 }
4756 4949
4757 4950
4758 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 4951 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
4759 const intptr_t kNumInputs = 2; 4952 const intptr_t kNumInputs = 2;
4760 const intptr_t kNumTemps = 0; 4953 const intptr_t kNumTemps = 0;
4761 if (needs_number_check()) { 4954 if (needs_number_check()) {
4762 LocationSummary* locs = 4955 LocationSummary* locs =
4763 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4956 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4764 locs->set_in(0, Location::RegisterLocation(EAX)); 4957 locs->set_in(0, Location::RegisterLocation(EAX));
4765 locs->set_in(1, Location::RegisterLocation(ECX)); 4958 locs->set_in(1, Location::RegisterLocation(ECX));
4766 locs->set_out(Location::RegisterLocation(EAX)); 4959 locs->set_out(Location::RegisterLocation(EAX));
4767 return locs; 4960 return locs;
4768 } 4961 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4834 } 5027 }
4835 5028
4836 5029
4837 // Detect pattern when one value is zero and another is a power of 2. 5030 // Detect pattern when one value is zero and another is a power of 2.
4838 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 5031 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
4839 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 5032 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
4840 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 5033 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
4841 } 5034 }
4842 5035
4843 5036
4844 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { 5037 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
4845 LocationSummary* locs = comparison()->MakeLocationSummary(); 5038 comparison()->InitializeLocationSummary(opt);
4846 // TODO(vegorov): support byte register constraints in the register allocator. 5039 // TODO(vegorov): support byte register constraints in the register allocator.
4847 locs->set_out(Location::RegisterLocation(EDX)); 5040 comparison()->locs()->set_out(Location::RegisterLocation(EDX));
4848 return locs; 5041 return comparison()->locs();
4849 } 5042 }
4850 5043
4851 5044
4852 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5045 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4853 ASSERT(locs()->out().reg() == EDX); 5046 ASSERT(locs()->out().reg() == EDX);
4854 5047
4855 // Clear upper part of the out register. We are going to use setcc on it 5048 // Clear upper part of the out register. We are going to use setcc on it
4856 // which is a byte move. 5049 // which is a byte move.
4857 __ xorl(EDX, EDX); 5050 __ xorl(EDX, EDX);
4858 5051
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4891 __ subl(EDX, Immediate(1)); 5084 __ subl(EDX, Immediate(1));
4892 __ andl(EDX, Immediate( 5085 __ andl(EDX, Immediate(
4893 Smi::RawValue(true_value) - Smi::RawValue(false_value))); 5086 Smi::RawValue(true_value) - Smi::RawValue(false_value)));
4894 if (false_value != 0) { 5087 if (false_value != 0) {
4895 __ addl(EDX, Immediate(Smi::RawValue(false_value))); 5088 __ addl(EDX, Immediate(Smi::RawValue(false_value)));
4896 } 5089 }
4897 } 5090 }
4898 } 5091 }
4899 5092
4900 5093
4901 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 5094 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
4902 const intptr_t kNumInputs = 0; 5095 const intptr_t kNumInputs = 0;
4903 const intptr_t kNumTemps = 1; 5096 const intptr_t kNumTemps = 1;
4904 LocationSummary* result = 5097 LocationSummary* result =
4905 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5098 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4906 result->set_out(Location::RegisterLocation(EAX)); 5099 result->set_out(Location::RegisterLocation(EAX));
4907 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 5100 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
4908 return result; 5101 return result;
4909 } 5102 }
4910 5103
4911 5104
4912 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5105 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4913 // The arguments to the stub include the closure, as does the arguments 5106 // The arguments to the stub include the closure, as does the arguments
4914 // descriptor. 5107 // descriptor.
4915 Register temp_reg = locs()->temp(0).reg(); 5108 Register temp_reg = locs()->temp(0).reg();
4916 int argument_count = ArgumentCount(); 5109 int argument_count = ArgumentCount();
4917 const Array& arguments_descriptor = 5110 const Array& arguments_descriptor =
4918 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 5111 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
4919 argument_names())); 5112 argument_names()));
4920 __ LoadObject(temp_reg, arguments_descriptor); 5113 __ LoadObject(temp_reg, arguments_descriptor);
4921 ASSERT(temp_reg == EDX); 5114 ASSERT(temp_reg == EDX);
4922 compiler->GenerateDartCall(deopt_id(), 5115 compiler->GenerateDartCall(deopt_id(),
4923 token_pos(), 5116 token_pos(),
4924 &StubCode::CallClosureFunctionLabel(), 5117 &StubCode::CallClosureFunctionLabel(),
4925 PcDescriptors::kClosureCall, 5118 PcDescriptors::kClosureCall,
4926 locs()); 5119 locs());
4927 __ Drop(argument_count); 5120 __ Drop(argument_count);
4928 } 5121 }
4929 5122
4930 5123
4931 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 5124 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
4932 return LocationSummary::Make(1, 5125 return LocationSummary::Make(1,
4933 Location::RequiresRegister(), 5126 Location::RequiresRegister(),
4934 LocationSummary::kNoCall); 5127 LocationSummary::kNoCall);
4935 } 5128 }
4936 5129
4937 5130
4938 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5131 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4939 Register value = locs()->in(0).reg(); 5132 Register value = locs()->in(0).reg();
4940 Register result = locs()->out().reg(); 5133 Register result = locs()->out().reg();
4941 5134
4942 Label done; 5135 Label done;
4943 __ LoadObject(result, Bool::True()); 5136 __ LoadObject(result, Bool::True());
4944 __ CompareRegisters(result, value); 5137 __ CompareRegisters(result, value);
4945 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 5138 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
4946 __ LoadObject(result, Bool::False()); 5139 __ LoadObject(result, Bool::False());
4947 __ Bind(&done); 5140 __ Bind(&done);
4948 } 5141 }
4949 5142
4950 5143
4951 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { 5144 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const {
4952 const intptr_t kNumInputs = 2; 5145 const intptr_t kNumInputs = 2;
4953 const intptr_t kNumTemps = 0; 5146 const intptr_t kNumTemps = 0;
4954 LocationSummary* locs = 5147 LocationSummary* locs =
4955 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5148 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4956 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 5149 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
4957 : Location::RequiresRegister()); 5150 : Location::RequiresRegister());
4958 locs->set_in(1, Location::RequiresRegister()); 5151 locs->set_in(1, Location::RequiresRegister());
4959 return locs; 5152 return locs;
4960 } 5153 }
4961 5154
4962 5155
4963 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5156 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4964 Register value_reg = locs()->in(0).reg(); 5157 Register value_reg = locs()->in(0).reg();
4965 Register dest_reg = locs()->in(1).reg(); 5158 Register dest_reg = locs()->in(1).reg();
4966 5159
4967 if (value()->NeedsStoreBuffer()) { 5160 if (value()->NeedsStoreBuffer()) {
4968 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 5161 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
4969 value_reg); 5162 value_reg);
4970 } else { 5163 } else {
4971 __ StoreIntoObjectNoBarrier( 5164 __ StoreIntoObjectNoBarrier(
4972 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); 5165 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
4973 } 5166 }
4974 } 5167 }
4975 5168
4976 5169
4977 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 5170 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const {
4978 return MakeCallSummary(); 5171 return MakeCallSummary();
4979 } 5172 }
4980 5173
4981 5174
4982 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5175 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4983 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); 5176 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls()));
4984 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); 5177 const ExternalLabel label(cls().ToCString(), stub.EntryPoint());
4985 compiler->GenerateCall(token_pos(), 5178 compiler->GenerateCall(token_pos(),
4986 &label, 5179 &label,
4987 PcDescriptors::kOther, 5180 PcDescriptors::kOther,
4988 locs()); 5181 locs());
4989 __ Drop(ArgumentCount()); // Discard arguments. 5182 __ Drop(ArgumentCount()); // Discard arguments.
4990 } 5183 }
4991 5184
4992 5185
4993 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 5186 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const {
4994 return MakeCallSummary(); 5187 return MakeCallSummary();
4995 } 5188 }
4996 5189
4997 5190
4998 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5191 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4999 const Function& closure_function = function(); 5192 const Function& closure_function = function();
5000 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); 5193 ASSERT(!closure_function.IsImplicitStaticClosureFunction());
5001 const Code& stub = Code::Handle( 5194 const Code& stub = Code::Handle(
5002 StubCode::GetAllocationStubForClosure(closure_function)); 5195 StubCode::GetAllocationStubForClosure(closure_function));
5003 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); 5196 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
5004 compiler->GenerateCall(token_pos(), 5197 compiler->GenerateCall(token_pos(),
5005 &label, 5198 &label,
5006 PcDescriptors::kOther, 5199 PcDescriptors::kOther,
5007 locs()); 5200 locs());
5008 __ Drop(2); // Discard type arguments and receiver. 5201 __ Drop(2); // Discard type arguments and receiver.
5009 } 5202 }
5010 5203
5011 } // namespace dart 5204 } // namespace dart
5012 5205
5013 #undef __ 5206 #undef __
5014 5207
5015 #endif // defined TARGET_ARCH_IA32 5208 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698