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

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

Issue 10912094: Reapply "Remove classes Computation and BindInstr." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 #include "vm/symbols.h" 16 #include "vm/symbols.h"
17 17
18 #define __ compiler->assembler()-> 18 #define __ compiler->assembler()->
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DECLARE_FLAG(int, optimization_counter_threshold); 22 DECLARE_FLAG(int, optimization_counter_threshold);
23 DECLARE_FLAG(bool, trace_functions); 23 DECLARE_FLAG(bool, trace_functions);
24 24
25 // Generic summary for call instructions that have all arguments pushed 25 // Generic summary for call instructions that have all arguments pushed
26 // on the stack and return the result in a fixed register EAX. 26 // on the stack and return the result in a fixed register EAX.
27 LocationSummary* Computation::MakeCallSummary() { 27 LocationSummary* Instruction::MakeCallSummary() {
28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
29 result->set_out(Location::RegisterLocation(EAX)); 29 result->set_out(Location::RegisterLocation(EAX));
30 return result; 30 return result;
31 } 31 }
32 32
33 33
34 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
35 computation()->EmitNativeCode(compiler);
36 if (is_used() && !compiler->is_optimizing()) {
37 __ pushl(locs()->out().reg());
38 }
39 }
40
41
42 LocationSummary* ReturnInstr::MakeLocationSummary() const { 34 LocationSummary* ReturnInstr::MakeLocationSummary() const {
43 const intptr_t kNumInputs = 1; 35 const intptr_t kNumInputs = 1;
44 const intptr_t kNumTemps = 1; 36 const intptr_t kNumTemps = 1;
45 LocationSummary* locs = 37 LocationSummary* locs =
46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
47 locs->set_in(0, Location::RegisterLocation(EAX)); 39 locs->set_in(0, Location::RegisterLocation(EAX));
48 locs->set_temp(0, Location::RequiresRegister()); 40 locs->set_temp(0, Location::RequiresRegister());
49 return locs; 41 return locs;
50 } 42 }
51 43
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 103
112 // Generate 1 byte NOP so that the debugger can patch the 104 // Generate 1 byte NOP so that the debugger can patch the
113 // return pattern with a call to the debug stub. 105 // return pattern with a call to the debug stub.
114 __ nop(1); 106 __ nop(1);
115 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
116 deopt_id(), 108 deopt_id(),
117 token_pos()); 109 token_pos());
118 } 110 }
119 111
120 112
121 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 113 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
122 const intptr_t kNumInputs = 0; 114 const intptr_t kNumInputs = 0;
123 const intptr_t kNumTemps = 1; 115 const intptr_t kNumTemps = 1;
124 LocationSummary* result = 116 LocationSummary* result =
125 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 117 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
126 result->set_out(Location::RegisterLocation(EAX)); 118 result->set_out(Location::RegisterLocation(EAX));
127 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 119 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
128 return result; 120 return result;
129 } 121 }
130 122
131 123
132 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 124 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
133 return LocationSummary::Make(0, 125 return LocationSummary::Make(0,
134 Location::RequiresRegister(), 126 Location::RequiresRegister(),
135 LocationSummary::kNoCall); 127 LocationSummary::kNoCall);
136 } 128 }
137 129
138 130
139 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 131 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
140 Register result = locs()->out().reg(); 132 Register result = locs()->out().reg();
141 __ movl(result, Address(EBP, local().index() * kWordSize)); 133 __ movl(result, Address(EBP, local().index() * kWordSize));
142 } 134 }
143 135
144 136
145 LocationSummary* StoreLocalComp::MakeLocationSummary() const { 137 LocationSummary* StoreLocalInstr::MakeLocationSummary() const {
146 return LocationSummary::Make(1, 138 return LocationSummary::Make(1,
147 Location::SameAsFirstInput(), 139 Location::SameAsFirstInput(),
148 LocationSummary::kNoCall); 140 LocationSummary::kNoCall);
149 } 141 }
150 142
151 143
152 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 144 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
153 Register value = locs()->in(0).reg(); 145 Register value = locs()->in(0).reg();
154 Register result = locs()->out().reg(); 146 Register result = locs()->out().reg();
155 ASSERT(result == value); // Assert that register assignment is correct. 147 ASSERT(result == value); // Assert that register assignment is correct.
156 __ movl(Address(EBP, local().index() * kWordSize), value); 148 __ movl(Address(EBP, local().index() * kWordSize), value);
157 } 149 }
158 150
159 151
160 LocationSummary* ConstantComp::MakeLocationSummary() const { 152 LocationSummary* ConstantInstr::MakeLocationSummary() const {
161 return LocationSummary::Make(0, 153 return LocationSummary::Make(0,
162 Location::RequiresRegister(), 154 Location::RequiresRegister(),
163 LocationSummary::kNoCall); 155 LocationSummary::kNoCall);
164 } 156 }
165 157
166 158
167 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { 159 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
168 // Register allocator drops constant definitions that have no uses. 160 // The register allocator drops constant definitions that have no uses.
169 if (!locs()->out().IsInvalid()) { 161 if (!locs()->out().IsInvalid()) {
170 Register result = locs()->out().reg(); 162 Register result = locs()->out().reg();
171 __ LoadObject(result, value()); 163 __ LoadObject(result, value());
172 } 164 }
173 } 165 }
174 166
175 167
176 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { 168 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const {
177 const intptr_t kNumInputs = 3; 169 const intptr_t kNumInputs = 3;
178 const intptr_t kNumTemps = 0; 170 const intptr_t kNumTemps = 0;
179 LocationSummary* summary = 171 LocationSummary* summary =
180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 172 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
181 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. 173 summary->set_in(0, Location::RegisterLocation(EAX)); // Value.
182 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. 174 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator.
183 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. 175 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments.
184 summary->set_out(Location::RegisterLocation(EAX)); 176 summary->set_out(Location::RegisterLocation(EAX));
185 return summary; 177 return summary;
186 } 178 }
187 179
188 180
189 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { 181 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const {
190 const intptr_t kNumInputs = 1; 182 const intptr_t kNumInputs = 1;
191 const intptr_t kNumTemps = 0; 183 const intptr_t kNumTemps = 0;
192 LocationSummary* locs = 184 LocationSummary* locs =
193 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
194 locs->set_in(0, Location::RegisterLocation(EAX)); 186 locs->set_in(0, Location::RegisterLocation(EAX));
195 locs->set_out(Location::RegisterLocation(EAX)); 187 locs->set_out(Location::RegisterLocation(EAX));
196 return locs; 188 return locs;
197 } 189 }
198 190
199 191
200 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { 192 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
201 Register obj = locs()->in(0).reg(); 193 Register obj = locs()->in(0).reg();
202 Register result = locs()->out().reg(); 194 Register result = locs()->out().reg();
203 195
204 if (!is_eliminated()) { 196 if (!is_eliminated()) {
205 // Check that the type of the value is allowed in conditional context. 197 // Check that the type of the value is allowed in conditional context.
206 // Call the runtime if the object is not bool::true or bool::false. 198 // Call the runtime if the object is not bool::true or bool::false.
207 Label done; 199 Label done;
208 __ CompareObject(obj, compiler->bool_true()); 200 __ CompareObject(obj, compiler->bool_true());
209 __ j(EQUAL, &done, Assembler::kNearJump); 201 __ j(EQUAL, &done, Assembler::kNearJump);
210 __ CompareObject(obj, compiler->bool_false()); 202 __ CompareObject(obj, compiler->bool_false());
211 __ j(EQUAL, &done, Assembler::kNearJump); 203 __ j(EQUAL, &done, Assembler::kNearJump);
212 204
213 __ pushl(obj); // Push the source object. 205 __ pushl(obj); // Push the source object.
214 compiler->GenerateCallRuntime(token_pos(), 206 compiler->GenerateCallRuntime(token_pos(),
215 kConditionTypeErrorRuntimeEntry, 207 kConditionTypeErrorRuntimeEntry,
216 locs()); 208 locs());
217 // We should never return here. 209 // We should never return here.
218 __ int3(); 210 __ int3();
219 __ Bind(&done); 211 __ Bind(&done);
220 } 212 }
221 ASSERT(obj == result); 213 ASSERT(obj == result);
222 } 214 }
223 215
224 216
225 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const { 217 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const {
226 const intptr_t kNumInputs = 1; 218 const intptr_t kNumInputs = 1;
227 const intptr_t kNumTemps = 0; 219 const intptr_t kNumTemps = 0;
228 LocationSummary* locs = 220 LocationSummary* locs =
229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 221 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
230 locs->set_in(0, Location::RegisterLocation(EAX)); 222 locs->set_in(0, Location::RegisterLocation(EAX));
231 locs->set_out(Location::RegisterLocation(EAX)); 223 locs->set_out(Location::RegisterLocation(EAX));
232 return locs; 224 return locs;
233 } 225 }
234 226
235 227
236 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) { 228 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
237 Register saved_args_desc = locs()->in(0).reg(); 229 Register saved_args_desc = locs()->in(0).reg();
238 Register result = locs()->out().reg(); 230 Register result = locs()->out().reg();
239 231
240 // Push the result place holder initialized to NULL. 232 // Push the result place holder initialized to NULL.
241 __ PushObject(Object::ZoneHandle()); 233 __ PushObject(Object::ZoneHandle());
242 __ pushl(Immediate(Smi::RawValue(formal_parameter_index()))); 234 __ pushl(Immediate(Smi::RawValue(formal_parameter_index())));
243 __ PushObject(formal_parameter_name()); 235 __ PushObject(formal_parameter_name());
244 __ pushl(saved_args_desc); 236 __ pushl(saved_args_desc);
245 compiler->GenerateCallRuntime(token_pos(), 237 compiler->GenerateCallRuntime(token_pos(),
246 kArgumentDefinitionTestRuntimeEntry, 238 kArgumentDefinitionTestRuntimeEntry,
(...skipping 11 matching lines...) Expand all
258 case Token::kGT: return GREATER; 250 case Token::kGT: return GREATER;
259 case Token::kLTE: return LESS_EQUAL; 251 case Token::kLTE: return LESS_EQUAL;
260 case Token::kGTE: return GREATER_EQUAL; 252 case Token::kGTE: return GREATER_EQUAL;
261 default: 253 default:
262 UNREACHABLE(); 254 UNREACHABLE();
263 return OVERFLOW; 255 return OVERFLOW;
264 } 256 }
265 } 257 }
266 258
267 259
268 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 260 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
269 const intptr_t kNumInputs = 2; 261 const intptr_t kNumInputs = 2;
270 const bool is_checked_strict_equal = 262 const bool is_checked_strict_equal =
271 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 263 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
272 if (receiver_class_id() == kDoubleCid) { 264 if (receiver_class_id() == kDoubleCid) {
273 const intptr_t kNumTemps = 0; 265 const intptr_t kNumTemps = 0;
274 LocationSummary* locs = 266 LocationSummary* locs =
275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 267 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
276 locs->set_in(0, Location::RequiresXmmRegister()); 268 locs->set_in(0, Location::RequiresXmmRegister());
277 locs->set_in(1, Location::RequiresXmmRegister()); 269 locs->set_in(1, Location::RequiresXmmRegister());
278 locs->set_out(Location::RequiresRegister()); 270 locs->set_out(Location::RequiresRegister());
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 if (branch != NULL) { 602 if (branch != NULL) {
611 compiler->EmitDoubleCompareBranch( 603 compiler->EmitDoubleCompareBranch(
612 true_condition, left, right, branch); 604 true_condition, left, right, branch);
613 } else { 605 } else {
614 compiler->EmitDoubleCompareBool( 606 compiler->EmitDoubleCompareBool(
615 true_condition, left, right, locs.out().reg()); 607 true_condition, left, right, locs.out().reg());
616 } 608 }
617 } 609 }
618 610
619 611
620 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 612 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
621 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 613 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
622 BranchInstr* kNoBranch = NULL; 614 BranchInstr* kNoBranch = NULL;
623 if (receiver_class_id() == kSmiCid) { 615 if (receiver_class_id() == kSmiCid) {
624 // Deoptimizes if both arguments not Smi. 616 // Deoptimizes if both arguments not Smi.
625 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 617 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
626 return; 618 return;
627 } 619 }
628 if (receiver_class_id() == kDoubleCid) { 620 if (receiver_class_id() == kDoubleCid) {
629 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 621 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
630 return; 622 return;
(...skipping 12 matching lines...) Expand all
643 } 635 }
644 Register left = locs()->in(0).reg(); 636 Register left = locs()->in(0).reg();
645 Register right = locs()->in(1).reg(); 637 Register right = locs()->in(1).reg();
646 __ pushl(left); 638 __ pushl(left);
647 __ pushl(right); 639 __ pushl(right);
648 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs()); 640 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs());
649 ASSERT(locs()->out().reg() == EAX); 641 ASSERT(locs()->out().reg() == EAX);
650 } 642 }
651 643
652 644
653 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, 645 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
654 BranchInstr* branch) { 646 BranchInstr* branch) {
655 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 647 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
656 if (receiver_class_id() == kSmiCid) { 648 if (receiver_class_id() == kSmiCid) {
657 // Deoptimizes if both arguments not Smi. 649 // Deoptimizes if both arguments not Smi.
658 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 650 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
659 return; 651 return;
660 } 652 }
661 if (receiver_class_id() == kDoubleCid) { 653 if (receiver_class_id() == kDoubleCid) {
662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 654 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
663 return; 655 return;
664 } 656 }
(...skipping 17 matching lines...) Expand all
682 deopt_id(), 674 deopt_id(),
683 token_pos(), 675 token_pos(),
684 Token::kEQ, // kNE reverse occurs at branch. 676 Token::kEQ, // kNE reverse occurs at branch.
685 locs()); 677 locs());
686 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 678 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
687 __ CompareObject(EAX, compiler->bool_true()); 679 __ CompareObject(EAX, compiler->bool_true());
688 branch->EmitBranchOnCondition(compiler, branch_condition); 680 branch->EmitBranchOnCondition(compiler, branch_condition);
689 } 681 }
690 682
691 683
692 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 684 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
693 const intptr_t kNumInputs = 2; 685 const intptr_t kNumInputs = 2;
694 if (operands_class_id() == kDoubleCid) { 686 if (operands_class_id() == kDoubleCid) {
695 const intptr_t kNumTemps = 0; 687 const intptr_t kNumTemps = 0;
696 LocationSummary* summary = 688 LocationSummary* summary =
697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 689 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
698 summary->set_in(0, Location::RequiresXmmRegister()); 690 summary->set_in(0, Location::RequiresXmmRegister());
699 summary->set_in(1, Location::RequiresXmmRegister()); 691 summary->set_in(1, Location::RequiresXmmRegister());
700 summary->set_out(Location::RequiresRegister()); 692 summary->set_out(Location::RequiresRegister());
701 return summary; 693 return summary;
702 } else if (operands_class_id() == kSmiCid) { 694 } else if (operands_class_id() == kSmiCid) {
(...skipping 10 matching lines...) Expand all
713 LocationSummary* locs = 705 LocationSummary* locs =
714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
715 // Pick arbitrary fixed input registers because this is a call. 707 // Pick arbitrary fixed input registers because this is a call.
716 locs->set_in(0, Location::RegisterLocation(EAX)); 708 locs->set_in(0, Location::RegisterLocation(EAX));
717 locs->set_in(1, Location::RegisterLocation(ECX)); 709 locs->set_in(1, Location::RegisterLocation(ECX));
718 locs->set_out(Location::RegisterLocation(EAX)); 710 locs->set_out(Location::RegisterLocation(EAX));
719 return locs; 711 return locs;
720 } 712 }
721 713
722 714
723 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 715 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
724 if (operands_class_id() == kSmiCid) { 716 if (operands_class_id() == kSmiCid) {
725 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 717 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
726 return; 718 return;
727 } 719 }
728 if (operands_class_id() == kDoubleCid) { 720 if (operands_class_id() == kDoubleCid) {
729 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 721 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
730 return; 722 return;
731 } 723 }
732 724
733 // Push arguments for the call. 725 // Push arguments for the call.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 compiler->GenerateInstanceCall(deopt_id(), 761 compiler->GenerateInstanceCall(deopt_id(),
770 token_pos(), 762 token_pos(),
771 function_name, 763 function_name,
772 kNumArguments, 764 kNumArguments,
773 Array::ZoneHandle(), // No optional arguments. 765 Array::ZoneHandle(), // No optional arguments.
774 kNumArgsChecked, 766 kNumArgsChecked,
775 locs()); 767 locs());
776 } 768 }
777 769
778 770
779 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, 771 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
780 BranchInstr* branch) { 772 BranchInstr* branch) {
781 if (operands_class_id() == kSmiCid) { 773 if (operands_class_id() == kSmiCid) {
782 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 774 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
783 return; 775 return;
784 } 776 }
785 if (operands_class_id() == kDoubleCid) { 777 if (operands_class_id() == kDoubleCid) {
786 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 778 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
787 return; 779 return;
788 } 780 }
789 EmitNativeCode(compiler); 781 EmitNativeCode(compiler);
790 __ CompareObject(EAX, compiler->bool_true()); 782 __ CompareObject(EAX, compiler->bool_true());
791 branch->EmitBranchOnCondition(compiler, EQUAL); 783 branch->EmitBranchOnCondition(compiler, EQUAL);
792 } 784 }
793 785
794 786
795 LocationSummary* NativeCallComp::MakeLocationSummary() const { 787 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
796 const intptr_t kNumInputs = 0; 788 const intptr_t kNumInputs = 0;
797 const intptr_t kNumTemps = 3; 789 const intptr_t kNumTemps = 3;
798 LocationSummary* locs = 790 LocationSummary* locs =
799 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
800 locs->set_temp(0, Location::RegisterLocation(EAX)); 792 locs->set_temp(0, Location::RegisterLocation(EAX));
801 locs->set_temp(1, Location::RegisterLocation(ECX)); 793 locs->set_temp(1, Location::RegisterLocation(ECX));
802 locs->set_temp(2, Location::RegisterLocation(EDX)); 794 locs->set_temp(2, Location::RegisterLocation(EDX));
803 locs->set_out(Location::RegisterLocation(EAX)); 795 locs->set_out(Location::RegisterLocation(EAX));
804 return locs; 796 return locs;
805 } 797 }
806 798
807 799
808 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 800 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
809 ASSERT(locs()->temp(0).reg() == EAX); 801 ASSERT(locs()->temp(0).reg() == EAX);
810 ASSERT(locs()->temp(1).reg() == ECX); 802 ASSERT(locs()->temp(1).reg() == ECX);
811 ASSERT(locs()->temp(2).reg() == EDX); 803 ASSERT(locs()->temp(2).reg() == EDX);
812 Register result = locs()->out().reg(); 804 Register result = locs()->out().reg();
813 805
814 // Push the result place holder initialized to NULL. 806 // Push the result place holder initialized to NULL.
815 __ PushObject(Object::ZoneHandle()); 807 __ PushObject(Object::ZoneHandle());
816 // Pass a pointer to the first argument in EAX. 808 // Pass a pointer to the first argument in EAX.
817 intptr_t arg_count = argument_count(); 809 intptr_t arg_count = argument_count();
818 if (is_native_instance_closure()) { 810 if (is_native_instance_closure()) {
819 arg_count += 1; 811 arg_count += 1;
820 } 812 }
821 if (!has_optional_parameters() && !is_native_instance_closure()) { 813 if (!has_optional_parameters() && !is_native_instance_closure()) {
822 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); 814 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize));
823 } else { 815 } else {
824 __ leal(EAX, 816 __ leal(EAX,
825 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 817 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
826 } 818 }
827 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); 819 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
828 __ movl(EDX, Immediate(arg_count)); 820 __ movl(EDX, Immediate(arg_count));
829 compiler->GenerateCall(token_pos(), 821 compiler->GenerateCall(token_pos(),
830 &StubCode::CallNativeCFunctionLabel(), 822 &StubCode::CallNativeCFunctionLabel(),
831 PcDescriptors::kOther, 823 PcDescriptors::kOther,
832 locs()); 824 locs());
833 __ popl(result); 825 __ popl(result);
834 } 826 }
835 827
836 828
837 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 829 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
838 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 830 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
839 (receiver_type() == kArrayCid) || 831 (receiver_type() == kArrayCid) ||
840 (receiver_type() == kImmutableArrayCid)); 832 (receiver_type() == kImmutableArrayCid));
841 const intptr_t kNumInputs = 2; 833 const intptr_t kNumInputs = 2;
842 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; 834 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0;
843 LocationSummary* locs = 835 LocationSummary* locs =
844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
845 locs->set_in(0, Location::RequiresRegister()); 837 locs->set_in(0, Location::RequiresRegister());
846 locs->set_in(1, Location::RequiresRegister()); 838 locs->set_in(1, Location::RequiresRegister());
847 if (receiver_type() == kGrowableObjectArrayCid) { 839 if (receiver_type() == kGrowableObjectArrayCid) {
848 locs->set_temp(0, Location::RequiresRegister()); 840 locs->set_temp(0, Location::RequiresRegister());
849 } 841 }
850 locs->set_out(Location::RequiresRegister()); 842 locs->set_out(Location::RequiresRegister());
851 return locs; 843 return locs;
852 } 844 }
853 845
854 846
855 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 847 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
856 Register receiver = locs()->in(0).reg(); 848 Register receiver = locs()->in(0).reg();
857 Register index = locs()->in(1).reg(); 849 Register index = locs()->in(1).reg();
858 Register result = locs()->out().reg(); 850 Register result = locs()->out().reg();
859 851
860 switch (receiver_type()) { 852 switch (receiver_type()) {
861 case kArrayCid: 853 case kArrayCid:
862 case kImmutableArrayCid: 854 case kImmutableArrayCid:
863 // Note that index is Smi, i.e, times 2. 855 // Note that index is Smi, i.e, times 2.
864 ASSERT(kSmiTagShift == 1); 856 ASSERT(kSmiTagShift == 1);
865 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray))); 857 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)));
866 break; 858 break;
867 859
868 case kGrowableObjectArrayCid: { 860 case kGrowableObjectArrayCid: {
869 Register temp = locs()->temp(0).reg(); 861 Register temp = locs()->temp(0).reg();
870 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 862 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
871 // Note that index is Smi, i.e, times 2. 863 // Note that index is Smi, i.e, times 2.
872 ASSERT(kSmiTagShift == 1); 864 ASSERT(kSmiTagShift == 1);
873 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray))); 865 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray)));
874 break; 866 break;
875 } 867 }
876 868
877 default: 869 default:
878 UNREACHABLE(); 870 UNREACHABLE();
879 break; 871 break;
880 } 872 }
881 } 873 }
882 874
883 875
884 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 876 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
885 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 877 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
886 (receiver_type() == kArrayCid)); 878 (receiver_type() == kArrayCid));
887 const intptr_t kNumInputs = 3; 879 const intptr_t kNumInputs = 3;
888 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; 880 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0;
889 LocationSummary* locs = 881 LocationSummary* locs =
890 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
891 locs->set_in(0, Location::RequiresRegister()); 883 locs->set_in(0, Location::RequiresRegister());
892 locs->set_in(1, Location::RequiresRegister()); 884 locs->set_in(1, Location::RequiresRegister());
893 locs->set_in(2, Location::RequiresRegister()); 885 locs->set_in(2, Location::RequiresRegister());
894 if (receiver_type() == kGrowableObjectArrayCid) { 886 if (receiver_type() == kGrowableObjectArrayCid) {
895 locs->set_temp(0, Location::RequiresRegister()); 887 locs->set_temp(0, Location::RequiresRegister());
896 } 888 }
897 return locs; 889 return locs;
898 } 890 }
899 891
900 892
901 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 893 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
902 Register receiver = locs()->in(0).reg(); 894 Register receiver = locs()->in(0).reg();
903 Register index = locs()->in(1).reg(); 895 Register index = locs()->in(1).reg();
904 Register value = locs()->in(2).reg(); 896 Register value = locs()->in(2).reg();
905 897
906 switch (receiver_type()) { 898 switch (receiver_type()) {
907 case kArrayCid: 899 case kArrayCid:
908 case kImmutableArrayCid: 900 case kImmutableArrayCid:
909 // Note that index is Smi, i.e, times 2. 901 // Note that index is Smi, i.e, times 2.
910 ASSERT(kSmiTagShift == 1); 902 ASSERT(kSmiTagShift == 1);
911 if (this->value()->NeedsStoreBuffer()) { 903 if (this->value()->NeedsStoreBuffer()) {
(...skipping 24 matching lines...) Expand all
936 break; 928 break;
937 } 929 }
938 930
939 default: 931 default:
940 UNREACHABLE(); 932 UNREACHABLE();
941 break; 933 break;
942 } 934 }
943 } 935 }
944 936
945 937
946 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 938 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const {
947 // TODO(fschneider): For this instruction the input register may be 939 // TODO(fschneider): For this instruction the input register may be
948 // reused for the result (but is not required to) because the input 940 // reused for the result (but is not required to) because the input
949 // is not used after the result is defined. We should consider adding 941 // is not used after the result is defined. We should consider adding
950 // this information to the input policy. 942 // this information to the input policy.
951 return LocationSummary::Make(1, 943 return LocationSummary::Make(1,
952 Location::RequiresRegister(), 944 Location::RequiresRegister(),
953 LocationSummary::kNoCall); 945 LocationSummary::kNoCall);
954 } 946 }
955 947
956 948
957 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 949 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
958 Register instance_reg = locs()->in(0).reg(); 950 Register instance_reg = locs()->in(0).reg();
959 Register result_reg = locs()->out().reg(); 951 Register result_reg = locs()->out().reg();
960 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); 952 __ movl(result_reg, FieldAddress(instance_reg, field().Offset()));
961 } 953 }
962 954
963 955
964 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { 956 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const {
965 const intptr_t kNumInputs = 2; 957 const intptr_t kNumInputs = 2;
966 const intptr_t num_temps = 0; 958 const intptr_t num_temps = 0;
967 LocationSummary* summary = 959 LocationSummary* summary =
968 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); 960 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall);
969 summary->set_in(0, Location::RequiresRegister()); 961 summary->set_in(0, Location::RequiresRegister());
970 summary->set_in(1, Location::RequiresRegister()); 962 summary->set_in(1, Location::RequiresRegister());
971 return summary; 963 return summary;
972 } 964 }
973 965
974 966
975 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 967 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
976 Register instance_reg = locs()->in(0).reg(); 968 Register instance_reg = locs()->in(0).reg();
977 Register value_reg = locs()->in(1).reg(); 969 Register value_reg = locs()->in(1).reg();
978 if (this->value()->NeedsStoreBuffer()) { 970 if (this->value()->NeedsStoreBuffer()) {
979 __ StoreIntoObject(instance_reg, 971 __ StoreIntoObject(instance_reg,
980 FieldAddress(instance_reg, field().Offset()), value_reg); 972 FieldAddress(instance_reg, field().Offset()), value_reg);
981 } else { 973 } else {
982 __ StoreIntoObjectNoBarrier(instance_reg, 974 __ StoreIntoObjectNoBarrier(instance_reg,
983 FieldAddress(instance_reg, field().Offset()), value_reg); 975 FieldAddress(instance_reg, field().Offset()), value_reg);
984 } 976 }
985 } 977 }
986 978
987 979
988 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 980 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const {
989 return LocationSummary::Make(0, 981 return LocationSummary::Make(0,
990 Location::RequiresRegister(), 982 Location::RequiresRegister(),
991 LocationSummary::kNoCall); 983 LocationSummary::kNoCall);
992 } 984 }
993 985
994 986
995 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 987 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
996 Register result = locs()->out().reg(); 988 Register result = locs()->out().reg();
997 __ LoadObject(result, field()); 989 __ LoadObject(result, field());
998 __ movl(result, FieldAddress(result, Field::value_offset())); 990 __ movl(result, FieldAddress(result, Field::value_offset()));
999 } 991 }
1000 992
1001 993
1002 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { 994 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const {
1003 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 995 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1004 locs->set_in(0, Location::RequiresRegister()); 996 locs->set_in(0, Location::RequiresRegister());
1005 locs->set_temp(0, Location::RequiresRegister()); 997 locs->set_temp(0, Location::RequiresRegister());
1006 locs->set_out(Location::SameAsFirstInput()); 998 locs->set_out(Location::SameAsFirstInput());
1007 return locs; 999 return locs;
1008 } 1000 }
1009 1001
1010 1002
1011 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1003 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1012 Register value = locs()->in(0).reg(); 1004 Register value = locs()->in(0).reg();
1013 Register temp = locs()->temp(0).reg(); 1005 Register temp = locs()->temp(0).reg();
1014 ASSERT(locs()->out().reg() == value); 1006 ASSERT(locs()->out().reg() == value);
1015 1007
1016 __ LoadObject(temp, field()); 1008 __ LoadObject(temp, field());
1017 if (this->value()->NeedsStoreBuffer()) { 1009 if (this->value()->NeedsStoreBuffer()) {
1018 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); 1010 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
1019 } else { 1011 } else {
1020 __ StoreIntoObjectNoBarrier( 1012 __ StoreIntoObjectNoBarrier(
1021 temp, FieldAddress(temp, Field::value_offset()), value); 1013 temp, FieldAddress(temp, Field::value_offset()), value);
1022 } 1014 }
1023 } 1015 }
1024 1016
1025 1017
1026 LocationSummary* InstanceOfComp::MakeLocationSummary() const { 1018 LocationSummary* InstanceOfInstr::MakeLocationSummary() const {
1027 const intptr_t kNumInputs = 3; 1019 const intptr_t kNumInputs = 3;
1028 const intptr_t kNumTemps = 0; 1020 const intptr_t kNumTemps = 0;
1029 LocationSummary* summary = 1021 LocationSummary* summary =
1030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1022 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1031 summary->set_in(0, Location::RegisterLocation(EAX)); 1023 summary->set_in(0, Location::RegisterLocation(EAX));
1032 summary->set_in(1, Location::RegisterLocation(ECX)); 1024 summary->set_in(1, Location::RegisterLocation(ECX));
1033 summary->set_in(2, Location::RegisterLocation(EDX)); 1025 summary->set_in(2, Location::RegisterLocation(EDX));
1034 summary->set_out(Location::RegisterLocation(EAX)); 1026 summary->set_out(Location::RegisterLocation(EAX));
1035 return summary; 1027 return summary;
1036 } 1028 }
1037 1029
1038 1030
1039 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1031 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1040 ASSERT(locs()->in(0).reg() == EAX); // Value. 1032 ASSERT(locs()->in(0).reg() == EAX); // Value.
1041 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1033 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1042 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1034 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1043 1035
1044 compiler->GenerateInstanceOf(token_pos(), 1036 compiler->GenerateInstanceOf(token_pos(),
1045 type(), 1037 type(),
1046 negate_result(), 1038 negate_result(),
1047 locs()); 1039 locs());
1048 ASSERT(locs()->out().reg() == EAX); 1040 ASSERT(locs()->out().reg() == EAX);
1049 } 1041 }
1050 1042
1051 1043
1052 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1044 LocationSummary* CreateArrayInstr::MakeLocationSummary() const {
1053 const intptr_t kNumInputs = 1; 1045 const intptr_t kNumInputs = 1;
1054 const intptr_t kNumTemps = 0; 1046 const intptr_t kNumTemps = 0;
1055 LocationSummary* locs = 1047 LocationSummary* locs =
1056 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1057 locs->set_in(0, Location::RegisterLocation(ECX)); 1049 locs->set_in(0, Location::RegisterLocation(ECX));
1058 locs->set_out(Location::RegisterLocation(EAX)); 1050 locs->set_out(Location::RegisterLocation(EAX));
1059 return locs; 1051 return locs;
1060 } 1052 }
1061 1053
1062 1054
1063 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1055 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1064 // Allocate the array. EDX = length, ECX = element type. 1056 // Allocate the array. EDX = length, ECX = element type.
1065 ASSERT(locs()->in(0).reg() == ECX); 1057 ASSERT(locs()->in(0).reg() == ECX);
1066 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); 1058 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount())));
1067 compiler->GenerateCall(token_pos(), 1059 compiler->GenerateCall(token_pos(),
1068 &StubCode::AllocateArrayLabel(), 1060 &StubCode::AllocateArrayLabel(),
1069 PcDescriptors::kOther, 1061 PcDescriptors::kOther,
1070 locs()); 1062 locs());
1071 ASSERT(locs()->out().reg() == EAX); 1063 ASSERT(locs()->out().reg() == EAX);
1072 1064
1073 // Pop the element values from the stack into the array. 1065 // Pop the element values from the stack into the array.
1074 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); 1066 __ leal(EDX, FieldAddress(EAX, Array::data_offset()));
1075 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1067 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1076 __ popl(Address(EDX, i * kWordSize)); 1068 __ popl(Address(EDX, i * kWordSize));
1077 } 1069 }
1078 } 1070 }
1079 1071
1080 1072
1081 LocationSummary* 1073 LocationSummary*
1082 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { 1074 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const {
1083 const intptr_t kNumInputs = 2; 1075 const intptr_t kNumInputs = 2;
1084 const intptr_t kNumTemps = 0; 1076 const intptr_t kNumTemps = 0;
1085 LocationSummary* locs = 1077 LocationSummary* locs =
1086 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1087 locs->set_in(0, Location::RegisterLocation(EAX)); 1079 locs->set_in(0, Location::RegisterLocation(EAX));
1088 locs->set_in(1, Location::RegisterLocation(ECX)); 1080 locs->set_in(1, Location::RegisterLocation(ECX));
1089 locs->set_out(Location::RegisterLocation(EAX)); 1081 locs->set_out(Location::RegisterLocation(EAX));
1090 return locs; 1082 return locs;
1091 } 1083 }
1092 1084
1093 1085
1094 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 1086 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
1095 FlowGraphCompiler* compiler) { 1087 FlowGraphCompiler* compiler) {
1096 const Class& cls = Class::ZoneHandle(constructor().Owner()); 1088 const Class& cls = Class::ZoneHandle(constructor().Owner());
1097 Register type_arguments = locs()->in(0).reg(); 1089 Register type_arguments = locs()->in(0).reg();
1098 Register instantiator_type_arguments = locs()->in(1).reg(); 1090 Register instantiator_type_arguments = locs()->in(1).reg();
1099 Register result = locs()->out().reg(); 1091 Register result = locs()->out().reg();
1100 1092
1101 // Push the result place holder initialized to NULL. 1093 // Push the result place holder initialized to NULL.
1102 __ PushObject(Object::ZoneHandle()); 1094 __ PushObject(Object::ZoneHandle());
1103 __ PushObject(cls); 1095 __ PushObject(cls);
1104 __ pushl(type_arguments); 1096 __ pushl(type_arguments);
1105 __ pushl(instantiator_type_arguments); 1097 __ pushl(instantiator_type_arguments);
1106 compiler->GenerateCallRuntime(token_pos(), 1098 compiler->GenerateCallRuntime(token_pos(),
1107 kAllocateObjectWithBoundsCheckRuntimeEntry, 1099 kAllocateObjectWithBoundsCheckRuntimeEntry,
1108 locs()); 1100 locs());
1109 // Pop instantiator type arguments, type arguments, and class. 1101 // Pop instantiator type arguments, type arguments, and class.
1110 // source location. 1102 // source location.
1111 __ Drop(3); 1103 __ Drop(3);
1112 __ popl(result); // Pop new instance. 1104 __ popl(result); // Pop new instance.
1113 } 1105 }
1114 1106
1115 1107
1116 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1108 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const {
1117 return LocationSummary::Make(1, 1109 return LocationSummary::Make(1,
1118 Location::RequiresRegister(), 1110 Location::RequiresRegister(),
1119 LocationSummary::kNoCall); 1111 LocationSummary::kNoCall);
1120 } 1112 }
1121 1113
1122 1114
1123 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1115 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1124 Register instance_reg = locs()->in(0).reg(); 1116 Register instance_reg = locs()->in(0).reg();
1125 Register result_reg = locs()->out().reg(); 1117 Register result_reg = locs()->out().reg();
1126 1118
1127 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1119 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1128 } 1120 }
1129 1121
1130 1122
1131 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 1123 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
1132 const intptr_t kNumInputs = 1; 1124 const intptr_t kNumInputs = 1;
1133 const intptr_t kNumTemps = 1; 1125 const intptr_t kNumTemps = 1;
1134 LocationSummary* locs = 1126 LocationSummary* locs =
1135 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1136 locs->set_in(0, Location::RegisterLocation(EAX)); 1128 locs->set_in(0, Location::RegisterLocation(EAX));
1137 locs->set_temp(0, Location::RegisterLocation(ECX)); 1129 locs->set_temp(0, Location::RegisterLocation(ECX));
1138 locs->set_out(Location::RegisterLocation(EAX)); 1130 locs->set_out(Location::RegisterLocation(EAX));
1139 return locs; 1131 return locs;
1140 } 1132 }
1141 1133
1142 1134
1143 void InstantiateTypeArgumentsComp::EmitNativeCode( 1135 void InstantiateTypeArgumentsInstr::EmitNativeCode(
1144 FlowGraphCompiler* compiler) { 1136 FlowGraphCompiler* compiler) {
1145 Register instantiator_reg = locs()->in(0).reg(); 1137 Register instantiator_reg = locs()->in(0).reg();
1146 Register temp = locs()->temp(0).reg(); 1138 Register temp = locs()->temp(0).reg();
1147 Register result_reg = locs()->out().reg(); 1139 Register result_reg = locs()->out().reg();
1148 1140
1149 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1141 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1150 // (or null). 1142 // (or null).
1151 // If the instantiator is null and if the type argument vector 1143 // If the instantiator is null and if the type argument vector
1152 // instantiated from null becomes a vector of Dynamic, then use null as 1144 // instantiated from null becomes a vector of Dynamic, then use null as
1153 // the type arguments. 1145 // the type arguments.
(...skipping 29 matching lines...) Expand all
1183 locs()); 1175 locs());
1184 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1176 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1185 __ popl(result_reg); // Pop instantiated type arguments. 1177 __ popl(result_reg); // Pop instantiated type arguments.
1186 __ Bind(&type_arguments_instantiated); 1178 __ Bind(&type_arguments_instantiated);
1187 ASSERT(instantiator_reg == result_reg); 1179 ASSERT(instantiator_reg == result_reg);
1188 // 'result_reg': Instantiated type arguments. 1180 // 'result_reg': Instantiated type arguments.
1189 } 1181 }
1190 1182
1191 1183
1192 LocationSummary* 1184 LocationSummary*
1193 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { 1185 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
1194 const intptr_t kNumInputs = 1; 1186 const intptr_t kNumInputs = 1;
1195 const intptr_t kNumTemps = 1; 1187 const intptr_t kNumTemps = 1;
1196 LocationSummary* locs = 1188 LocationSummary* locs =
1197 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1198 locs->set_in(0, Location::RequiresRegister()); 1190 locs->set_in(0, Location::RequiresRegister());
1199 locs->set_out(Location::SameAsFirstInput()); 1191 locs->set_out(Location::SameAsFirstInput());
1200 locs->set_temp(0, Location::RequiresRegister()); 1192 locs->set_temp(0, Location::RequiresRegister());
1201 return locs; 1193 return locs;
1202 } 1194 }
1203 1195
1204 1196
1205 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( 1197 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
1206 FlowGraphCompiler* compiler) { 1198 FlowGraphCompiler* compiler) {
1207 Register instantiator_reg = locs()->in(0).reg(); 1199 Register instantiator_reg = locs()->in(0).reg();
1208 Register result_reg = locs()->out().reg(); 1200 Register result_reg = locs()->out().reg();
1209 ASSERT(instantiator_reg == result_reg); 1201 ASSERT(instantiator_reg == result_reg);
1210 Register temp_reg = locs()->temp(0).reg(); 1202 Register temp_reg = locs()->temp(0).reg();
1211 1203
1212 // instantiator_reg is the instantiator type argument vector, i.e. an 1204 // instantiator_reg is the instantiator type argument vector, i.e. an
1213 // AbstractTypeArguments object (or null). 1205 // AbstractTypeArguments object (or null).
1214 // If the instantiator is null and if the type argument vector 1206 // If the instantiator is null and if the type argument vector
1215 // instantiated from null becomes a vector of Dynamic, then use null as 1207 // instantiated from null becomes a vector of Dynamic, then use null as
(...skipping 25 matching lines...) Expand all
1241 // In the non-factory case, we rely on the allocation stub to 1233 // In the non-factory case, we rely on the allocation stub to
1242 // instantiate the type arguments. 1234 // instantiate the type arguments.
1243 __ LoadObject(result_reg, type_arguments()); 1235 __ LoadObject(result_reg, type_arguments());
1244 // result_reg: uninstantiated type arguments. 1236 // result_reg: uninstantiated type arguments.
1245 __ Bind(&type_arguments_instantiated); 1237 __ Bind(&type_arguments_instantiated);
1246 // result_reg: uninstantiated or instantiated type arguments. 1238 // result_reg: uninstantiated or instantiated type arguments.
1247 } 1239 }
1248 1240
1249 1241
1250 LocationSummary* 1242 LocationSummary*
1251 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { 1243 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
1252 const intptr_t kNumInputs = 1; 1244 const intptr_t kNumInputs = 1;
1253 const intptr_t kNumTemps = 1; 1245 const intptr_t kNumTemps = 1;
1254 LocationSummary* locs = 1246 LocationSummary* locs =
1255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1256 locs->set_in(0, Location::RequiresRegister()); 1248 locs->set_in(0, Location::RequiresRegister());
1257 locs->set_out(Location::SameAsFirstInput()); 1249 locs->set_out(Location::SameAsFirstInput());
1258 locs->set_temp(0, Location::RequiresRegister()); 1250 locs->set_temp(0, Location::RequiresRegister());
1259 return locs; 1251 return locs;
1260 } 1252 }
1261 1253
1262 1254
1263 void ExtractConstructorInstantiatorComp::EmitNativeCode( 1255 void ExtractConstructorInstantiatorInstr::EmitNativeCode(
1264 FlowGraphCompiler* compiler) { 1256 FlowGraphCompiler* compiler) {
1265 Register instantiator_reg = locs()->in(0).reg(); 1257 Register instantiator_reg = locs()->in(0).reg();
1266 ASSERT(locs()->out().reg() == instantiator_reg); 1258 ASSERT(locs()->out().reg() == instantiator_reg);
1267 Register temp_reg = locs()->temp(0).reg(); 1259 Register temp_reg = locs()->temp(0).reg();
1268 1260
1269 // instantiator_reg is the instantiator AbstractTypeArguments object 1261 // instantiator_reg is the instantiator AbstractTypeArguments object
1270 // (or null). If the instantiator is null and if the type argument vector 1262 // (or null). If the instantiator is null and if the type argument vector
1271 // instantiated from null becomes a vector of Dynamic, then use null as 1263 // instantiated from null becomes a vector of Dynamic, then use null as
1272 // the type arguments and do not pass the instantiator. 1264 // the type arguments and do not pass the instantiator.
1273 Label done; 1265 Label done;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1299 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1308 // instantiated type arguments, no proper instantiator needed. 1300 // instantiated type arguments, no proper instantiator needed.
1309 __ movl(instantiator_reg, 1301 __ movl(instantiator_reg,
1310 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1302 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1311 } 1303 }
1312 __ Bind(&done); 1304 __ Bind(&done);
1313 // instantiator_reg: instantiator or kNoInstantiator. 1305 // instantiator_reg: instantiator or kNoInstantiator.
1314 } 1306 }
1315 1307
1316 1308
1317 LocationSummary* AllocateContextComp::MakeLocationSummary() const { 1309 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
1318 const intptr_t kNumInputs = 0; 1310 const intptr_t kNumInputs = 0;
1319 const intptr_t kNumTemps = 1; 1311 const intptr_t kNumTemps = 1;
1320 LocationSummary* locs = 1312 LocationSummary* locs =
1321 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1313 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1322 locs->set_temp(0, Location::RegisterLocation(EDX)); 1314 locs->set_temp(0, Location::RegisterLocation(EDX));
1323 locs->set_out(Location::RegisterLocation(EAX)); 1315 locs->set_out(Location::RegisterLocation(EAX));
1324 return locs; 1316 return locs;
1325 } 1317 }
1326 1318
1327 1319
1328 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1320 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1329 ASSERT(locs()->temp(0).reg() == EDX); 1321 ASSERT(locs()->temp(0).reg() == EDX);
1330 ASSERT(locs()->out().reg() == EAX); 1322 ASSERT(locs()->out().reg() == EAX);
1331 1323
1332 __ movl(EDX, Immediate(num_context_variables())); 1324 __ movl(EDX, Immediate(num_context_variables()));
1333 const ExternalLabel label("alloc_context", 1325 const ExternalLabel label("alloc_context",
1334 StubCode::AllocateContextEntryPoint()); 1326 StubCode::AllocateContextEntryPoint());
1335 compiler->GenerateCall(token_pos(), 1327 compiler->GenerateCall(token_pos(),
1336 &label, 1328 &label,
1337 PcDescriptors::kOther, 1329 PcDescriptors::kOther,
1338 locs()); 1330 locs());
1339 } 1331 }
1340 1332
1341 1333
1342 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1334 LocationSummary* CloneContextInstr::MakeLocationSummary() const {
1343 const intptr_t kNumInputs = 1; 1335 const intptr_t kNumInputs = 1;
1344 const intptr_t kNumTemps = 0; 1336 const intptr_t kNumTemps = 0;
1345 LocationSummary* locs = 1337 LocationSummary* locs =
1346 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1347 locs->set_in(0, Location::RegisterLocation(EAX)); 1339 locs->set_in(0, Location::RegisterLocation(EAX));
1348 locs->set_out(Location::RegisterLocation(EAX)); 1340 locs->set_out(Location::RegisterLocation(EAX));
1349 return locs; 1341 return locs;
1350 } 1342 }
1351 1343
1352 1344
1353 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1345 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1354 Register context_value = locs()->in(0).reg(); 1346 Register context_value = locs()->in(0).reg();
1355 Register result = locs()->out().reg(); 1347 Register result = locs()->out().reg();
1356 1348
1357 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1349 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1358 __ pushl(context_value); 1350 __ pushl(context_value);
1359 compiler->GenerateCallRuntime(token_pos(), 1351 compiler->GenerateCallRuntime(token_pos(),
1360 kCloneContextRuntimeEntry, 1352 kCloneContextRuntimeEntry,
1361 locs()); 1353 locs());
1362 __ popl(result); // Remove argument. 1354 __ popl(result); // Remove argument.
1363 __ popl(result); // Get result (cloned context). 1355 __ popl(result); // Get result (cloned context).
1364 } 1356 }
1365 1357
1366 1358
1367 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1359 LocationSummary* CatchEntryInstr::MakeLocationSummary() const {
1368 return LocationSummary::Make(0, 1360 return LocationSummary::Make(0,
1369 Location::NoLocation(), 1361 Location::NoLocation(),
1370 LocationSummary::kNoCall); 1362 LocationSummary::kNoCall);
1371 } 1363 }
1372 1364
1373 1365
1374 // Restore stack and initialize the two exception variables: 1366 // Restore stack and initialize the two exception variables:
1375 // exception and stack trace variables. 1367 // exception and stack trace variables.
1376 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1368 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1377 // Restore RSP from RBP as we are coming from a throw and the code for 1369 // Restore RSP from RBP as we are coming from a throw and the code for
1378 // popping arguments has not been run. 1370 // popping arguments has not been run.
1379 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; 1371 const intptr_t locals_space_size = compiler->StackSize() * kWordSize;
1380 ASSERT(locals_space_size >= 0); 1372 ASSERT(locals_space_size >= 0);
1381 const intptr_t offset_size = 1373 const intptr_t offset_size =
1382 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; 1374 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP;
1383 __ leal(ESP, Address(EBP, offset_size)); 1375 __ leal(ESP, Address(EBP, offset_size));
1384 1376
1385 ASSERT(!exception_var().is_captured()); 1377 ASSERT(!exception_var().is_captured());
1386 ASSERT(!stacktrace_var().is_captured()); 1378 ASSERT(!stacktrace_var().is_captured());
1387 __ movl(Address(EBP, exception_var().index() * kWordSize), 1379 __ movl(Address(EBP, exception_var().index() * kWordSize),
1388 kExceptionObjectReg); 1380 kExceptionObjectReg);
1389 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 1381 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
1390 kStackTraceObjectReg); 1382 kStackTraceObjectReg);
1391 } 1383 }
1392 1384
1393 1385
1394 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { 1386 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
1395 const intptr_t kNumInputs = 0; 1387 const intptr_t kNumInputs = 0;
1396 const intptr_t kNumTemps = 0; 1388 const intptr_t kNumTemps = 0;
1397 LocationSummary* summary = 1389 LocationSummary* summary =
1398 new LocationSummary(kNumInputs, 1390 new LocationSummary(kNumInputs,
1399 kNumTemps, 1391 kNumTemps,
1400 LocationSummary::kCallOnSlowPath); 1392 LocationSummary::kCallOnSlowPath);
1401 return summary; 1393 return summary;
1402 } 1394 }
1403 1395
1404 1396
1405 class CheckStackOverflowSlowPath : public SlowPathCode { 1397 class CheckStackOverflowSlowPath : public SlowPathCode {
1406 public: 1398 public:
1407 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) 1399 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
1408 : computation_(computation) { } 1400 : instruction_(instruction) { }
1409 1401
1410 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1402 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1411 __ Bind(entry_label()); 1403 __ Bind(entry_label());
1412 compiler->SaveLiveRegisters(computation_->locs()); 1404 compiler->SaveLiveRegisters(instruction_->locs());
1413 compiler->GenerateCallRuntime(computation_->token_pos(), 1405 compiler->GenerateCallRuntime(instruction_->token_pos(),
1414 kStackOverflowRuntimeEntry, 1406 kStackOverflowRuntimeEntry,
1415 computation_->locs()); 1407 instruction_->locs());
1416 compiler->RestoreLiveRegisters(computation_->locs()); 1408 compiler->RestoreLiveRegisters(instruction_->locs());
1417 __ jmp(exit_label()); 1409 __ jmp(exit_label());
1418 } 1410 }
1419 1411
1420 private: 1412 private:
1421 CheckStackOverflowComp* computation_; 1413 CheckStackOverflowInstr* instruction_;
1422 }; 1414 };
1423 1415
1424 1416
1425 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1417 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1426 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); 1418 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
1427 compiler->AddSlowPathCode(slow_path); 1419 compiler->AddSlowPathCode(slow_path);
1428 1420
1429 __ cmpl(ESP, 1421 __ cmpl(ESP,
1430 Address::Absolute(Isolate::Current()->stack_limit_address())); 1422 Address::Absolute(Isolate::Current()->stack_limit_address()));
1431 __ j(BELOW_EQUAL, slow_path->entry_label()); 1423 __ j(BELOW_EQUAL, slow_path->entry_label());
1432 __ Bind(slow_path->exit_label()); 1424 __ Bind(slow_path->exit_label());
1433 } 1425 }
1434 1426
1435 1427
1436 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { 1428 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
1437 const intptr_t kNumInputs = 2; 1429 const intptr_t kNumInputs = 2;
1438 if (op_kind() == Token::kTRUNCDIV) { 1430 if (op_kind() == Token::kTRUNCDIV) {
1439 const intptr_t kNumTemps = 3; 1431 const intptr_t kNumTemps = 3;
1440 LocationSummary* summary = 1432 LocationSummary* summary =
1441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1433 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1442 summary->set_in(0, Location::RegisterLocation(EAX)); 1434 summary->set_in(0, Location::RegisterLocation(EAX));
1443 summary->set_in(1, Location::RegisterLocation(ECX)); 1435 summary->set_in(1, Location::RegisterLocation(ECX));
1444 summary->set_out(Location::SameAsFirstInput()); 1436 summary->set_out(Location::SameAsFirstInput());
1445 summary->set_temp(0, Location::RegisterLocation(EBX)); 1437 summary->set_temp(0, Location::RegisterLocation(EBX));
1446 // Will be used for for sign extension. 1438 // Will be used for for sign extension.
(...skipping 24 matching lines...) Expand all
1471 LocationSummary* summary = 1463 LocationSummary* summary =
1472 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1464 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1473 summary->set_in(0, Location::RequiresRegister()); 1465 summary->set_in(0, Location::RequiresRegister());
1474 summary->set_in(1, Location::RegisterOrConstant(right())); 1466 summary->set_in(1, Location::RegisterOrConstant(right()));
1475 summary->set_out(Location::SameAsFirstInput()); 1467 summary->set_out(Location::SameAsFirstInput());
1476 return summary; 1468 return summary;
1477 } 1469 }
1478 } 1470 }
1479 1471
1480 1472
1481 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1473 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1482 Register left = locs()->in(0).reg(); 1474 Register left = locs()->in(0).reg();
1483 Register result = locs()->out().reg(); 1475 Register result = locs()->out().reg();
1484 ASSERT(left == result); 1476 ASSERT(left == result);
1485 Label* deopt = NULL; 1477 Label* deopt = NULL;
1486 switch (op_kind()) { 1478 switch (op_kind()) {
1487 case Token::kBIT_AND: 1479 case Token::kBIT_AND:
1488 case Token::kBIT_OR: 1480 case Token::kBIT_OR:
1489 case Token::kBIT_XOR: 1481 case Token::kBIT_XOR:
1490 // Can't deoptimize. Arguments are already checked for smi. 1482 // Can't deoptimize. Arguments are already checked for smi.
1491 break; 1483 break;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 UNREACHABLE(); 1684 UNREACHABLE();
1693 break; 1685 break;
1694 } 1686 }
1695 default: 1687 default:
1696 UNREACHABLE(); 1688 UNREACHABLE();
1697 break; 1689 break;
1698 } 1690 }
1699 } 1691 }
1700 1692
1701 1693
1702 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const { 1694 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const {
1703 const intptr_t kNumInputs = 2; 1695 const intptr_t kNumInputs = 2;
1704 ASSERT(op_kind() == Token::kBIT_AND); 1696 ASSERT(op_kind() == Token::kBIT_AND);
1705 const intptr_t kNumTemps = 1; 1697 const intptr_t kNumTemps = 1;
1706 LocationSummary* summary = 1698 LocationSummary* summary =
1707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1708 summary->set_in(0, Location::RegisterLocation(EAX)); 1700 summary->set_in(0, Location::RegisterLocation(EAX));
1709 summary->set_in(1, Location::RegisterLocation(ECX)); 1701 summary->set_in(1, Location::RegisterLocation(ECX));
1710 summary->set_temp(0, Location::RegisterLocation(EDX)); 1702 summary->set_temp(0, Location::RegisterLocation(EDX));
1711 summary->set_out(Location::RegisterLocation(EAX)); 1703 summary->set_out(Location::RegisterLocation(EAX));
1712 return summary; 1704 return summary;
1713 } 1705 }
1714 1706
1715 1707
1716 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1708 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1717 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1709 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1718 // receiver and a Mint or Smi argument. We fall back to the run time call if 1710 // receiver and a Mint or Smi argument. We fall back to the run time call if
1719 // both receiver and argument are Mint or if one of them is Mint and the other 1711 // both receiver and argument are Mint or if one of them is Mint and the other
1720 // is a negative Smi. 1712 // is a negative Smi.
1721 Register left = locs()->in(0).reg(); 1713 Register left = locs()->in(0).reg();
1722 Register right = locs()->in(1).reg(); 1714 Register right = locs()->in(1).reg();
1723 Register result = locs()->out().reg(); 1715 Register result = locs()->out().reg();
1724 Register temp = locs()->temp(0).reg(); 1716 Register temp = locs()->temp(0).reg();
1725 ASSERT(left == result); 1717 ASSERT(left == result);
1726 ASSERT(op_kind() == Token::kBIT_AND); 1718 ASSERT(op_kind() == Token::kBIT_AND);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 instance_call()->ArgumentCount(), 1788 instance_call()->ArgumentCount(),
1797 instance_call()->argument_names(), 1789 instance_call()->argument_names(),
1798 locs()); 1790 locs());
1799 ASSERT(result == EAX); 1791 ASSERT(result == EAX);
1800 } 1792 }
1801 } 1793 }
1802 __ Bind(&done); 1794 __ Bind(&done);
1803 } 1795 }
1804 1796
1805 1797
1806 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { 1798 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const {
1807 ASSERT((left()->ResultCid() != kDoubleCid) && 1799 ASSERT((left()->ResultCid() != kDoubleCid) &&
1808 (right()->ResultCid() != kDoubleCid)); 1800 (right()->ResultCid() != kDoubleCid));
1809 const intptr_t kNumInputs = 2; 1801 const intptr_t kNumInputs = 2;
1810 const intptr_t kNumTemps = 1; 1802 const intptr_t kNumTemps = 1;
1811 LocationSummary* summary = 1803 LocationSummary* summary =
1812 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1804 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1813 summary->set_in(0, Location::RequiresRegister()); 1805 summary->set_in(0, Location::RequiresRegister());
1814 summary->set_in(1, Location::RequiresRegister()); 1806 summary->set_in(1, Location::RequiresRegister());
1815 summary->set_temp(0, Location::RequiresRegister()); 1807 summary->set_temp(0, Location::RequiresRegister());
1816 return summary; 1808 return summary;
1817 } 1809 }
1818 1810
1819 1811
1820 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1812 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1821 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), 1813 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp);
1822 kDeoptBinaryDoubleOp);
1823
1824 Register temp = locs()->temp(0).reg(); 1814 Register temp = locs()->temp(0).reg();
1825 __ movl(temp, locs()->in(0).reg()); 1815 __ movl(temp, locs()->in(0).reg());
1826 __ orl(temp, locs()->in(1).reg()); 1816 __ orl(temp, locs()->in(1).reg());
1827 __ testl(temp, Immediate(kSmiTagMask)); 1817 __ testl(temp, Immediate(kSmiTagMask));
1828 __ j(ZERO, deopt); 1818 __ j(ZERO, deopt);
1829 } 1819 }
1830 1820
1831 1821
1832 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { 1822 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const {
1833 const intptr_t kNumInputs = 1; 1823 const intptr_t kNumInputs = 1;
1834 const intptr_t kNumTemps = 0; 1824 const intptr_t kNumTemps = 0;
1835 LocationSummary* summary = 1825 LocationSummary* summary =
1836 new LocationSummary(kNumInputs, 1826 new LocationSummary(kNumInputs,
1837 kNumTemps, 1827 kNumTemps,
1838 LocationSummary::kCallOnSlowPath); 1828 LocationSummary::kCallOnSlowPath);
1839 summary->set_in(0, Location::RequiresXmmRegister()); 1829 summary->set_in(0, Location::RequiresXmmRegister());
1840 summary->set_out(Location::RequiresRegister()); 1830 summary->set_out(Location::RequiresRegister());
1841 return summary; 1831 return summary;
1842 } 1832 }
1843 1833
1844 1834
1845 class BoxDoubleSlowPath : public SlowPathCode { 1835 class BoxDoubleSlowPath : public SlowPathCode {
1846 public: 1836 public:
1847 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) 1837 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
1848 : computation_(computation) { } 1838 : instruction_(instruction) { }
1849 1839
1850 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1840 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1851 __ Bind(entry_label()); 1841 __ Bind(entry_label());
1852 const Class& double_class = compiler->double_class(); 1842 const Class& double_class = compiler->double_class();
1853 const Code& stub = 1843 const Code& stub =
1854 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1844 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1855 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1845 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1856 1846
1857 LocationSummary* locs = computation_->locs(); 1847 LocationSummary* locs = instruction_->locs();
1858 locs->live_registers()->Remove(locs->out()); 1848 locs->live_registers()->Remove(locs->out());
1859 1849
1860 compiler->SaveLiveRegisters(locs); 1850 compiler->SaveLiveRegisters(locs);
1861 compiler->GenerateCall(computation_->token_pos(), 1851 compiler->GenerateCall(instruction_->token_pos(),
1862 &label, 1852 &label,
1863 PcDescriptors::kOther, 1853 PcDescriptors::kOther,
1864 locs); 1854 locs);
1865 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 1855 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX);
1866 compiler->RestoreLiveRegisters(locs); 1856 compiler->RestoreLiveRegisters(locs);
1867 1857
1868 __ jmp(exit_label()); 1858 __ jmp(exit_label());
1869 } 1859 }
1870 1860
1871 private: 1861 private:
1872 BoxDoubleComp* computation_; 1862 BoxDoubleInstr* instruction_;
1873 }; 1863 };
1874 1864
1875 1865
1876 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1866 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1877 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 1867 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1878 compiler->AddSlowPathCode(slow_path); 1868 compiler->AddSlowPathCode(slow_path);
1879 1869
1880 Register out_reg = locs()->out().reg(); 1870 Register out_reg = locs()->out().reg();
1881 XmmRegister value = locs()->in(0).xmm_reg(); 1871 XmmRegister value = locs()->in(0).xmm_reg();
1882 1872
1883 AssemblerMacros::TryAllocate(compiler->assembler(), 1873 AssemblerMacros::TryAllocate(compiler->assembler(),
1884 compiler->double_class(), 1874 compiler->double_class(),
1885 slow_path->entry_label(), 1875 slow_path->entry_label(),
1886 Assembler::kFarJump, 1876 Assembler::kFarJump,
1887 out_reg); 1877 out_reg);
1888 __ Bind(slow_path->exit_label()); 1878 __ Bind(slow_path->exit_label());
1889 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 1879 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
1890 } 1880 }
1891 1881
1892 1882
1893 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { 1883 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const {
1894 const intptr_t v_cid = value()->ResultCid(); 1884 const intptr_t v_cid = value()->ResultCid();
1895 1885
1896 const intptr_t kNumInputs = 1; 1886 const intptr_t kNumInputs = 1;
1897 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; 1887 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0;
1898 LocationSummary* summary = 1888 LocationSummary* summary =
1899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1889 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1900 summary->set_in(0, Location::RequiresRegister()); 1890 summary->set_in(0, Location::RequiresRegister());
1901 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); 1891 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister());
1902 summary->set_out(Location::RequiresXmmRegister()); 1892 summary->set_out(Location::RequiresXmmRegister());
1903 return summary; 1893 return summary;
1904 } 1894 }
1905 1895
1906 1896
1907 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1897 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1908 const intptr_t v_cid = value()->ResultCid(); 1898 const intptr_t v_cid = value()->ResultCid();
1909 1899
1910 const Register value = locs()->in(0).reg(); 1900 const Register value = locs()->in(0).reg();
1911 const XmmRegister result = locs()->out().xmm_reg(); 1901 const XmmRegister result = locs()->out().xmm_reg();
1912 if (v_cid != kDoubleCid) { 1902 if (v_cid != kDoubleCid) {
1913 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 1903 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
1914 compiler->LoadDoubleOrSmiToXmm(result, 1904 compiler->LoadDoubleOrSmiToXmm(result,
1915 value, 1905 value,
1916 locs()->temp(0).reg(), 1906 locs()->temp(0).reg(),
1917 deopt); 1907 deopt);
1918 } else { 1908 } else {
1919 __ movsd(result, FieldAddress(value, Double::value_offset())); 1909 __ movsd(result, FieldAddress(value, Double::value_offset()));
1920 } 1910 }
1921 } 1911 }
1922 1912
1923 1913
1924 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { 1914 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const {
1925 const intptr_t kNumInputs = 2; 1915 const intptr_t kNumInputs = 2;
1926 const intptr_t kNumTemps = 0; 1916 const intptr_t kNumTemps = 0;
1927 LocationSummary* summary = 1917 LocationSummary* summary =
1928 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1918 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1929 summary->set_in(0, Location::RequiresXmmRegister()); 1919 summary->set_in(0, Location::RequiresXmmRegister());
1930 summary->set_in(1, Location::RequiresXmmRegister()); 1920 summary->set_in(1, Location::RequiresXmmRegister());
1931 summary->set_out(Location::SameAsFirstInput()); 1921 summary->set_out(Location::SameAsFirstInput());
1932 return summary; 1922 return summary;
1933 } 1923 }
1934 1924
1935 1925
1936 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1926 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1937 XmmRegister left = locs()->in(0).xmm_reg(); 1927 XmmRegister left = locs()->in(0).xmm_reg();
1938 XmmRegister right = locs()->in(1).xmm_reg(); 1928 XmmRegister right = locs()->in(1).xmm_reg();
1939 1929
1940 ASSERT(locs()->out().xmm_reg() == left); 1930 ASSERT(locs()->out().xmm_reg() == left);
1941 1931
1942 switch (op_kind()) { 1932 switch (op_kind()) {
1943 case Token::kADD: __ addsd(left, right); break; 1933 case Token::kADD: __ addsd(left, right); break;
1944 case Token::kSUB: __ subsd(left, right); break; 1934 case Token::kSUB: __ subsd(left, right); break;
1945 case Token::kMUL: __ mulsd(left, right); break; 1935 case Token::kMUL: __ mulsd(left, right); break;
1946 case Token::kDIV: __ divsd(left, right); break; 1936 case Token::kDIV: __ divsd(left, right); break;
1947 default: UNREACHABLE(); 1937 default: UNREACHABLE();
1948 } 1938 }
1949 } 1939 }
1950 1940
1951 1941
1952 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { 1942 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
1953 const intptr_t kNumInputs = 1; 1943 const intptr_t kNumInputs = 1;
1954 const intptr_t kNumTemps = 0; 1944 const intptr_t kNumTemps = 0;
1955 LocationSummary* summary = 1945 LocationSummary* summary =
1956 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1946 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1957 summary->set_in(0, Location::RequiresRegister()); 1947 summary->set_in(0, Location::RequiresRegister());
1958 summary->set_out(Location::SameAsFirstInput()); 1948 summary->set_out(Location::SameAsFirstInput());
1959 return summary; 1949 return summary;
1960 } 1950 }
1961 1951
1962 1952
1963 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1953 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1964 Register value = locs()->in(0).reg(); 1954 Register value = locs()->in(0).reg();
1965 ASSERT(value == locs()->out().reg()); 1955 ASSERT(value == locs()->out().reg());
1966 switch (op_kind()) { 1956 switch (op_kind()) {
1967 case Token::kNEGATE: { 1957 case Token::kNEGATE: {
1968 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1958 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1969 kDeoptUnaryOp); 1959 kDeoptUnaryOp);
1970 __ negl(value); 1960 __ negl(value);
1971 __ j(OVERFLOW, deopt); 1961 __ j(OVERFLOW, deopt);
1972 break; 1962 break;
1973 } 1963 }
1974 case Token::kBIT_NOT: 1964 case Token::kBIT_NOT:
1975 __ notl(value); 1965 __ notl(value);
1976 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 1966 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
1977 break; 1967 break;
1978 default: 1968 default:
1979 UNREACHABLE(); 1969 UNREACHABLE();
1980 } 1970 }
1981 } 1971 }
1982 1972
1983 1973
1984 LocationSummary* NumberNegateComp::MakeLocationSummary() const { 1974 LocationSummary* NumberNegateInstr::MakeLocationSummary() const {
1985 const intptr_t kNumInputs = 1; 1975 const intptr_t kNumInputs = 1;
1986 const intptr_t kNumTemps = 1; // Needed for doubles. 1976 const intptr_t kNumTemps = 1; // Needed for doubles.
1987 LocationSummary* summary = 1977 LocationSummary* summary =
1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1989 summary->set_in(0, Location::RegisterLocation(EAX)); 1979 summary->set_in(0, Location::RegisterLocation(EAX));
1990 summary->set_temp(0, Location::RegisterLocation(ECX)); 1980 summary->set_temp(0, Location::RegisterLocation(ECX));
1991 summary->set_out(Location::RegisterLocation(EAX)); 1981 summary->set_out(Location::RegisterLocation(EAX));
1992 return summary; 1982 return summary;
1993 } 1983 }
1994 1984
1995 1985
1996 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1986 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1997 const ICData& ic_data = *instance_call()->ic_data(); 1987 const ICData& ic_data = *instance_call()->ic_data();
1998 ASSERT(!ic_data.IsNull()); 1988 ASSERT(!ic_data.IsNull());
1999 ASSERT(ic_data.num_args_tested() == 1); 1989 ASSERT(ic_data.num_args_tested() == 1);
2000 1990
2001 // TODO(srdjan): Implement for more checks. 1991 // TODO(srdjan): Implement for more checks.
2002 ASSERT(ic_data.NumberOfChecks() == 1); 1992 ASSERT(ic_data.NumberOfChecks() == 1);
2003 intptr_t test_class_id; 1993 intptr_t test_class_id;
2004 Function& target = Function::Handle(); 1994 Function& target = Function::Handle();
2005 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1995 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
2006 1996
(...skipping 25 matching lines...) Expand all
2032 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 2022 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
2033 __ DoubleNegate(XMM0); 2023 __ DoubleNegate(XMM0);
2034 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2024 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2035 } else { 2025 } else {
2036 UNREACHABLE(); 2026 UNREACHABLE();
2037 } 2027 }
2038 ASSERT(ResultCid() == kDoubleCid); 2028 ASSERT(ResultCid() == kDoubleCid);
2039 } 2029 }
2040 2030
2041 2031
2042 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const { 2032 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const {
2043 const intptr_t kNumInputs = 1; 2033 const intptr_t kNumInputs = 1;
2044 const intptr_t kNumTemps = 1; 2034 const intptr_t kNumTemps = 1;
2045 LocationSummary* locs = 2035 LocationSummary* locs =
2046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2036 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2047 locs->set_in(0, Location::RequiresRegister()); 2037 locs->set_in(0, Location::RequiresRegister());
2048 locs->set_temp(0, Location::RequiresRegister()); 2038 locs->set_temp(0, Location::RequiresRegister());
2049 locs->set_out(Location::SameAsFirstInput()); 2039 locs->set_out(Location::SameAsFirstInput());
2050 return locs; 2040 return locs;
2051 } 2041 }
2052 2042
2053 2043
2054 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2044 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2055 Register value = locs()->in(0).reg(); 2045 Register value = locs()->in(0).reg();
2056 Register result = locs()->out().reg(); 2046 Register result = locs()->out().reg();
2057 2047
2058 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2048 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2059 kDeoptDoubleToDouble); 2049 kDeoptDoubleToDouble);
2060 Register temp = locs()->temp(0).reg(); 2050 Register temp = locs()->temp(0).reg();
2061 __ testl(value, Immediate(kSmiTagMask)); 2051 __ testl(value, Immediate(kSmiTagMask));
2062 __ j(ZERO, deopt); // Deoptimize if Smi. 2052 __ j(ZERO, deopt); // Deoptimize if Smi.
2063 __ CompareClassId(value, kDoubleCid, temp); 2053 __ CompareClassId(value, kDoubleCid, temp);
2064 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 2054 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
2065 ASSERT(value == result); 2055 ASSERT(value == result);
2066 } 2056 }
2067 2057
2068 2058
2069 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { 2059 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const {
2070 return MakeCallSummary(); // Calls a stub to allocate result. 2060 return MakeCallSummary(); // Calls a stub to allocate result.
2071 } 2061 }
2072 2062
2073 2063
2074 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2064 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2075 Register result = locs()->out().reg(); 2065 Register result = locs()->out().reg();
2076 2066
2077 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2067 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2078 kDeoptIntegerToDouble); 2068 kDeoptIntegerToDouble);
2079 2069
2080 const Class& double_class = compiler->double_class(); 2070 const Class& double_class = compiler->double_class();
2081 const Code& stub = 2071 const Code& stub =
2082 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2072 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2083 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2073 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2084 2074
2085 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 2075 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
2086 compiler->GenerateCall(instance_call()->token_pos(), 2076 compiler->GenerateCall(instance_call()->token_pos(),
2087 &label, 2077 &label,
2088 PcDescriptors::kOther, 2078 PcDescriptors::kOther,
2089 locs()); 2079 locs());
2090 ASSERT(result == EAX); 2080 ASSERT(result == EAX);
2091 Register value = EBX; 2081 Register value = EBX;
2092 // Preserve argument on the stack until after the deoptimization point. 2082 // Preserve argument on the stack until after the deoptimization point.
2093 __ movl(value, Address(ESP, 0)); 2083 __ movl(value, Address(ESP, 0));
2094 2084
2095 __ testl(value, Immediate(kSmiTagMask)); 2085 __ testl(value, Immediate(kSmiTagMask));
2096 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 2086 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
2097 __ SmiUntag(value); 2087 __ SmiUntag(value);
2098 __ cvtsi2sd(XMM0, value); 2088 __ cvtsi2sd(XMM0, value);
2099 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2089 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2100 __ Drop(1); 2090 __ Drop(1);
2101 } 2091 }
2102 2092
2103 2093
2104 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 2094 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
2105 return MakeCallSummary(); 2095 return MakeCallSummary();
2106 } 2096 }
2107 2097
2108 2098
2109 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2099 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2110 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2100 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2111 kDeoptPolymorphicInstanceCallTestFail); 2101 kDeoptPolymorphicInstanceCallTestFail);
2112 if (ic_data().NumberOfChecks() == 0) { 2102 if (ic_data().NumberOfChecks() == 0) {
2113 __ jmp(deopt); 2103 __ jmp(deopt);
2114 return; 2104 return;
2115 } 2105 }
2116 ASSERT(ic_data().num_args_tested() == 1); 2106 ASSERT(ic_data().num_args_tested() == 1);
2117 if (!with_checks()) { 2107 if (!with_checks()) {
2118 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); 2108 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
2119 compiler->GenerateStaticCall(instance_call()->deopt_id(), 2109 compiler->GenerateStaticCall(instance_call()->deopt_id(),
(...skipping 20 matching lines...) Expand all
2140 EDI, // Class id register. 2130 EDI, // Class id register.
2141 instance_call()->ArgumentCount(), 2131 instance_call()->ArgumentCount(),
2142 instance_call()->argument_names(), 2132 instance_call()->argument_names(),
2143 deopt, 2133 deopt,
2144 instance_call()->deopt_id(), 2134 instance_call()->deopt_id(),
2145 instance_call()->token_pos(), 2135 instance_call()->token_pos(),
2146 locs()); 2136 locs());
2147 } 2137 }
2148 2138
2149 2139
2140 LocationSummary* BranchInstr::MakeLocationSummary() const {
2141 UNREACHABLE();
2142 return NULL;
2143 }
2144
2145
2150 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2146 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2151 computation()->EmitBranchCode(compiler, this); 2147 comparison()->EmitBranchCode(compiler, this);
2152 } 2148 }
2153 2149
2154 2150
2155 LocationSummary* CheckClassComp::MakeLocationSummary() const { 2151 LocationSummary* CheckClassInstr::MakeLocationSummary() const {
2156 const intptr_t kNumInputs = 1; 2152 const intptr_t kNumInputs = 1;
2157 const intptr_t kNumTemps = 1; 2153 const intptr_t kNumTemps = 1;
2158 LocationSummary* summary = 2154 LocationSummary* summary =
2159 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2155 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2160 summary->set_in(0, Location::RequiresRegister()); 2156 summary->set_in(0, Location::RequiresRegister());
2161 summary->set_temp(0, Location::RequiresRegister()); 2157 summary->set_temp(0, Location::RequiresRegister());
2162 return summary; 2158 return summary;
2163 } 2159 }
2164 2160
2165 2161
2166 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2162 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2167 Register value = locs()->in(0).reg(); 2163 Register value = locs()->in(0).reg();
2168 Register temp = locs()->temp(0).reg(); 2164 Register temp = locs()->temp(0).reg();
2169 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2165 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2170 kDeoptCheckClass); 2166 kDeoptCheckClass);
2171 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); 2167 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid);
2172 __ testl(value, Immediate(kSmiTagMask)); 2168 __ testl(value, Immediate(kSmiTagMask));
2173 __ j(ZERO, deopt); 2169 __ j(ZERO, deopt);
2174 __ LoadClassId(temp, value); 2170 __ LoadClassId(temp, value);
2175 Label is_ok; 2171 Label is_ok;
2176 const intptr_t num_checks = unary_checks().NumberOfChecks(); 2172 const intptr_t num_checks = unary_checks().NumberOfChecks();
2177 const bool use_near_jump = num_checks < 5; 2173 const bool use_near_jump = num_checks < 5;
2178 for (intptr_t i = 0; i < num_checks; i++) { 2174 for (intptr_t i = 0; i < num_checks; i++) {
2179 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); 2175 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i)));
2180 if (i == (num_checks - 1)) { 2176 if (i == (num_checks - 1)) {
2181 __ j(NOT_EQUAL, deopt); 2177 __ j(NOT_EQUAL, deopt);
2182 } else { 2178 } else {
2183 if (use_near_jump) { 2179 if (use_near_jump) {
2184 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2180 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2185 } else { 2181 } else {
2186 __ j(EQUAL, &is_ok); 2182 __ j(EQUAL, &is_ok);
2187 } 2183 }
2188 } 2184 }
2189 } 2185 }
2190 __ Bind(&is_ok); 2186 __ Bind(&is_ok);
2191 } 2187 }
2192 2188
2193 2189
2194 LocationSummary* CheckSmiComp::MakeLocationSummary() const { 2190 LocationSummary* CheckSmiInstr::MakeLocationSummary() const {
2195 const intptr_t kNumInputs = 1; 2191 const intptr_t kNumInputs = 1;
2196 const intptr_t kNumTemps = 0; 2192 const intptr_t kNumTemps = 0;
2197 LocationSummary* summary = 2193 LocationSummary* summary =
2198 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2199 summary->set_in(0, Location::RequiresRegister()); 2195 summary->set_in(0, Location::RequiresRegister());
2200 return summary; 2196 return summary;
2201 } 2197 }
2202 2198
2203 2199
2204 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2200 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2205 Register value = locs()->in(0).reg(); 2201 Register value = locs()->in(0).reg();
2206 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2202 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2207 kDeoptCheckSmi); 2203 kDeoptCheckSmi);
2208 __ testl(value, Immediate(kSmiTagMask)); 2204 __ testl(value, Immediate(kSmiTagMask));
2209 __ j(NOT_ZERO, deopt); 2205 __ j(NOT_ZERO, deopt);
2210 } 2206 }
2211 2207
2212 2208
2213 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const { 2209 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
2214 const intptr_t kNumInputs = 2; 2210 const intptr_t kNumInputs = 2;
2215 const intptr_t kNumTemps = 0; 2211 const intptr_t kNumTemps = 0;
2216 LocationSummary* locs = 2212 LocationSummary* locs =
2217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2213 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2218 locs->set_in(0, Location::RequiresRegister()); 2214 locs->set_in(0, Location::RequiresRegister());
2219 locs->set_in(1, Location::RegisterOrConstant(index())); 2215 locs->set_in(1, Location::RegisterOrConstant(index()));
2220 return locs; 2216 return locs;
2221 } 2217 }
2222 2218
2223 2219
2224 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2220 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2225 Register receiver = locs()->in(0).reg(); 2221 Register receiver = locs()->in(0).reg();
2226 2222
2227 const DeoptReasonId deopt_reason = 2223 const DeoptReasonId deopt_reason =
2228 (array_type() == kGrowableObjectArrayCid) ? 2224 (array_type() == kGrowableObjectArrayCid) ?
2229 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 2225 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
2230 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2226 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2231 deopt_reason); 2227 deopt_reason);
2232 ASSERT(array_type() == kArrayCid || 2228 ASSERT(array_type() == kArrayCid ||
2233 array_type() == kImmutableArrayCid || 2229 array_type() == kImmutableArrayCid ||
2234 array_type() == kGrowableObjectArrayCid); 2230 array_type() == kGrowableObjectArrayCid);
(...skipping 14 matching lines...) Expand all
2249 __ j(ABOVE_EQUAL, deopt); 2245 __ j(ABOVE_EQUAL, deopt);
2250 } 2246 }
2251 } 2247 }
2252 2248
2253 2249
2254 } // namespace dart 2250 } // namespace dart
2255 2251
2256 #undef __ 2252 #undef __
2257 2253
2258 #endif // defined TARGET_ARCH_X64 2254 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698