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

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

Issue 10917085: Revert "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
« no previous file with comments | « runtime/vm/intermediate_language_test.cc ('k') | runtime/vm/locations.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
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 RAX. 26 // on the stack and return the result in a fixed register RAX.
27 LocationSummary* Instruction::MakeCallSummary() { 27 LocationSummary* Computation::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(RAX)); 29 result->set_out(Location::RegisterLocation(RAX));
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 __ pushq(locs()->out().reg());
38 }
39 }
40
41
34 LocationSummary* ReturnInstr::MakeLocationSummary() const { 42 LocationSummary* ReturnInstr::MakeLocationSummary() const {
35 const intptr_t kNumInputs = 1; 43 const intptr_t kNumInputs = 1;
36 const intptr_t kNumTemps = 1; 44 const intptr_t kNumTemps = 1;
37 LocationSummary* locs = 45 LocationSummary* locs =
38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
39 locs->set_in(0, Location::RegisterLocation(RAX)); 47 locs->set_in(0, Location::RegisterLocation(RAX));
40 locs->set_temp(0, Location::RequiresRegister()); 48 locs->set_temp(0, Location::RequiresRegister());
41 return locs; 49 return locs;
42 } 50 }
43 51
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 __ nop(1); 120 __ nop(1);
113 __ nop(1); 121 __ nop(1);
114 __ nop(1); 122 __ nop(1);
115 __ nop(1); 123 __ nop(1);
116 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 124 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
117 deopt_id(), 125 deopt_id(),
118 token_pos()); 126 token_pos());
119 } 127 }
120 128
121 129
122 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 130 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
123 const intptr_t kNumInputs = 0; 131 const intptr_t kNumInputs = 0;
124 const intptr_t kNumTemps = 1; 132 const intptr_t kNumTemps = 1;
125 LocationSummary* result = 133 LocationSummary* result =
126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
127 result->set_out(Location::RegisterLocation(RAX)); 135 result->set_out(Location::RegisterLocation(RAX));
128 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 136 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
129 return result; 137 return result;
130 } 138 }
131 139
132 140
133 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 141 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
134 return LocationSummary::Make(0, 142 return LocationSummary::Make(0,
135 Location::RequiresRegister(), 143 Location::RequiresRegister(),
136 LocationSummary::kNoCall); 144 LocationSummary::kNoCall);
137 } 145 }
138 146
139 147
140 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 148 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
141 Register result = locs()->out().reg(); 149 Register result = locs()->out().reg();
142 __ movq(result, Address(RBP, local().index() * kWordSize)); 150 __ movq(result, Address(RBP, local().index() * kWordSize));
143 } 151 }
144 152
145 153
146 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { 154 LocationSummary* StoreLocalComp::MakeLocationSummary() const {
147 return LocationSummary::Make(1, 155 return LocationSummary::Make(1,
148 Location::SameAsFirstInput(), 156 Location::SameAsFirstInput(),
149 LocationSummary::kNoCall); 157 LocationSummary::kNoCall);
150 } 158 }
151 159
152 160
153 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 161 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
154 Register value = locs()->in(0).reg(); 162 Register value = locs()->in(0).reg();
155 Register result = locs()->out().reg(); 163 Register result = locs()->out().reg();
156 ASSERT(result == value); // Assert that register assignment is correct. 164 ASSERT(result == value); // Assert that register assignment is correct.
157 __ movq(Address(RBP, local().index() * kWordSize), value); 165 __ movq(Address(RBP, local().index() * kWordSize), value);
158 } 166 }
159 167
160 168
161 LocationSummary* ConstantInstr::MakeLocationSummary() const { 169 LocationSummary* ConstantComp::MakeLocationSummary() const {
162 return LocationSummary::Make(0, 170 return LocationSummary::Make(0,
163 Location::RequiresRegister(), 171 Location::RequiresRegister(),
164 LocationSummary::kNoCall); 172 LocationSummary::kNoCall);
165 } 173 }
166 174
167 175
168 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 176 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) {
169 // The register allocator drops constant definitions that have no uses. 177 // Register allocator drops constant definitions that have no uses.
170 if (!locs()->out().IsInvalid()) { 178 if (!locs()->out().IsInvalid()) {
171 Register result = locs()->out().reg(); 179 Register result = locs()->out().reg();
172 __ LoadObject(result, value()); 180 __ LoadObject(result, value());
173 } 181 }
174 } 182 }
175 183
176 184
177 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 185 LocationSummary* AssertAssignableComp::MakeLocationSummary() const {
178 const intptr_t kNumInputs = 3; 186 const intptr_t kNumInputs = 3;
179 const intptr_t kNumTemps = 0; 187 const intptr_t kNumTemps = 0;
180 LocationSummary* summary = 188 LocationSummary* summary =
181 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
182 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 190 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
183 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. 191 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
184 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. 192 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments.
185 summary->set_out(Location::RegisterLocation(RAX)); 193 summary->set_out(Location::RegisterLocation(RAX));
186 return summary; 194 return summary;
187 } 195 }
188 196
189 197
190 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 198 LocationSummary* AssertBooleanComp::MakeLocationSummary() const {
191 const intptr_t kNumInputs = 1; 199 const intptr_t kNumInputs = 1;
192 const intptr_t kNumTemps = 0; 200 const intptr_t kNumTemps = 0;
193 LocationSummary* locs = 201 LocationSummary* locs =
194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 202 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
195 locs->set_in(0, Location::RegisterLocation(RAX)); 203 locs->set_in(0, Location::RegisterLocation(RAX));
196 locs->set_out(Location::RegisterLocation(RAX)); 204 locs->set_out(Location::RegisterLocation(RAX));
197 return locs; 205 return locs;
198 } 206 }
199 207
200 208
201 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 209 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) {
202 Register obj = locs()->in(0).reg(); 210 Register obj = locs()->in(0).reg();
203 Register result = locs()->out().reg(); 211 Register result = locs()->out().reg();
204 212
205 if (!is_eliminated()) { 213 if (!is_eliminated()) {
206 // Check that the type of the value is allowed in conditional context. 214 // Check that the type of the value is allowed in conditional context.
207 // Call the runtime if the object is not bool::true or bool::false. 215 // Call the runtime if the object is not bool::true or bool::false.
208 Label done; 216 Label done;
209 __ CompareObject(obj, compiler->bool_true()); 217 __ CompareObject(obj, compiler->bool_true());
210 __ j(EQUAL, &done, Assembler::kNearJump); 218 __ j(EQUAL, &done, Assembler::kNearJump);
211 __ CompareObject(obj, compiler->bool_false()); 219 __ CompareObject(obj, compiler->bool_false());
212 __ j(EQUAL, &done, Assembler::kNearJump); 220 __ j(EQUAL, &done, Assembler::kNearJump);
213 221
214 __ pushq(obj); // Push the source object. 222 __ pushq(obj); // Push the source object.
215 compiler->GenerateCallRuntime(token_pos(), 223 compiler->GenerateCallRuntime(token_pos(),
216 kConditionTypeErrorRuntimeEntry, 224 kConditionTypeErrorRuntimeEntry,
217 locs()); 225 locs());
218 // We should never return here. 226 // We should never return here.
219 __ int3(); 227 __ int3();
220 __ Bind(&done); 228 __ Bind(&done);
221 } 229 }
222 ASSERT(obj == result); 230 ASSERT(obj == result);
223 } 231 }
224 232
225 233
226 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 234 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const {
227 const intptr_t kNumInputs = 1; 235 const intptr_t kNumInputs = 1;
228 const intptr_t kNumTemps = 0; 236 const intptr_t kNumTemps = 0;
229 LocationSummary* locs = 237 LocationSummary* locs =
230 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
231 locs->set_in(0, Location::RegisterLocation(RAX)); 239 locs->set_in(0, Location::RegisterLocation(RAX));
232 locs->set_out(Location::RegisterLocation(RAX)); 240 locs->set_out(Location::RegisterLocation(RAX));
233 return locs; 241 return locs;
234 } 242 }
235 243
236 244
237 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 245 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) {
238 Register saved_args_desc = locs()->in(0).reg(); 246 Register saved_args_desc = locs()->in(0).reg();
239 Register result = locs()->out().reg(); 247 Register result = locs()->out().reg();
240 248
241 // Push the result place holder initialized to NULL. 249 // Push the result place holder initialized to NULL.
242 __ PushObject(Object::ZoneHandle()); 250 __ PushObject(Object::ZoneHandle());
243 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); 251 __ pushq(Immediate(Smi::RawValue(formal_parameter_index())));
244 __ PushObject(formal_parameter_name()); 252 __ PushObject(formal_parameter_name());
245 __ pushq(saved_args_desc); 253 __ pushq(saved_args_desc);
246 compiler->GenerateCallRuntime(token_pos(), 254 compiler->GenerateCallRuntime(token_pos(),
247 kArgumentDefinitionTestRuntimeEntry, 255 kArgumentDefinitionTestRuntimeEntry,
(...skipping 11 matching lines...) Expand all
259 case Token::kGT: return GREATER; 267 case Token::kGT: return GREATER;
260 case Token::kLTE: return LESS_EQUAL; 268 case Token::kLTE: return LESS_EQUAL;
261 case Token::kGTE: return GREATER_EQUAL; 269 case Token::kGTE: return GREATER_EQUAL;
262 default: 270 default:
263 UNREACHABLE(); 271 UNREACHABLE();
264 return OVERFLOW; 272 return OVERFLOW;
265 } 273 }
266 } 274 }
267 275
268 276
269 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 277 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
270 const intptr_t kNumInputs = 2; 278 const intptr_t kNumInputs = 2;
271 const bool is_checked_strict_equal = 279 const bool is_checked_strict_equal =
272 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 280 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
273 if (receiver_class_id() == kDoubleCid) { 281 if (receiver_class_id() == kDoubleCid) {
274 const intptr_t kNumTemps = 0; 282 const intptr_t kNumTemps = 0;
275 LocationSummary* locs = 283 LocationSummary* locs =
276 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 284 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
277 locs->set_in(0, Location::RequiresXmmRegister()); 285 locs->set_in(0, Location::RequiresXmmRegister());
278 locs->set_in(1, Location::RequiresXmmRegister()); 286 locs->set_in(1, Location::RequiresXmmRegister());
279 locs->set_out(Location::RequiresRegister()); 287 locs->set_out(Location::RequiresRegister());
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 if (branch != NULL) { 620 if (branch != NULL) {
613 compiler->EmitDoubleCompareBranch( 621 compiler->EmitDoubleCompareBranch(
614 true_condition, left, right, branch); 622 true_condition, left, right, branch);
615 } else { 623 } else {
616 compiler->EmitDoubleCompareBool( 624 compiler->EmitDoubleCompareBool(
617 true_condition, left, right, locs.out().reg()); 625 true_condition, left, right, locs.out().reg());
618 } 626 }
619 } 627 }
620 628
621 629
622 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 630 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
623 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 631 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
624 BranchInstr* kNoBranch = NULL; 632 BranchInstr* kNoBranch = NULL;
625 if (receiver_class_id() == kSmiCid) { 633 if (receiver_class_id() == kSmiCid) {
626 // Deoptimizes if both arguments not Smi. 634 // Deoptimizes if both arguments not Smi.
627 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 635 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
628 return; 636 return;
629 } 637 }
630 if (receiver_class_id() == kDoubleCid) { 638 if (receiver_class_id() == kDoubleCid) {
631 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 639 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
632 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 640 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
(...skipping 17 matching lines...) Expand all
650 __ pushq(right); 658 __ pushq(right);
651 EmitEqualityAsInstanceCall(compiler, 659 EmitEqualityAsInstanceCall(compiler,
652 deopt_id(), 660 deopt_id(),
653 token_pos(), 661 token_pos(),
654 kind(), 662 kind(),
655 locs()); 663 locs());
656 ASSERT(locs()->out().reg() == RAX); 664 ASSERT(locs()->out().reg() == RAX);
657 } 665 }
658 666
659 667
660 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 668 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
661 BranchInstr* branch) { 669 BranchInstr* branch) {
662 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 670 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
663 if (receiver_class_id() == kSmiCid) { 671 if (receiver_class_id() == kSmiCid) {
664 // Deoptimizes if both arguments not Smi. 672 // Deoptimizes if both arguments not Smi.
665 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 673 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
666 return; 674 return;
667 } 675 }
668 if (receiver_class_id() == kDoubleCid) { 676 if (receiver_class_id() == kDoubleCid) {
669 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 677 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
670 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 678 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
671 return; 679 return;
(...skipping 18 matching lines...) Expand all
690 deopt_id(), 698 deopt_id(),
691 token_pos(), 699 token_pos(),
692 Token::kEQ, // kNE reverse occurs at branch. 700 Token::kEQ, // kNE reverse occurs at branch.
693 locs()); 701 locs());
694 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 702 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
695 __ CompareObject(RAX, compiler->bool_true()); 703 __ CompareObject(RAX, compiler->bool_true());
696 branch->EmitBranchOnCondition(compiler, branch_condition); 704 branch->EmitBranchOnCondition(compiler, branch_condition);
697 } 705 }
698 706
699 707
700 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 708 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
701 const intptr_t kNumInputs = 2; 709 const intptr_t kNumInputs = 2;
702 if (operands_class_id() == kDoubleCid) { 710 if (operands_class_id() == kDoubleCid) {
703 const intptr_t kNumTemps = 0; 711 const intptr_t kNumTemps = 0;
704 LocationSummary* summary = 712 LocationSummary* summary =
705 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 713 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
706 summary->set_in(0, Location::RequiresXmmRegister()); 714 summary->set_in(0, Location::RequiresXmmRegister());
707 summary->set_in(1, Location::RequiresXmmRegister()); 715 summary->set_in(1, Location::RequiresXmmRegister());
708 summary->set_out(Location::RequiresRegister()); 716 summary->set_out(Location::RequiresRegister());
709 return summary; 717 return summary;
710 } else if (operands_class_id() == kSmiCid) { 718 } else if (operands_class_id() == kSmiCid) {
(...skipping 10 matching lines...) Expand all
721 LocationSummary* locs = 729 LocationSummary* locs =
722 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
723 // Pick arbitrary fixed input registers because this is a call. 731 // Pick arbitrary fixed input registers because this is a call.
724 locs->set_in(0, Location::RegisterLocation(RAX)); 732 locs->set_in(0, Location::RegisterLocation(RAX));
725 locs->set_in(1, Location::RegisterLocation(RCX)); 733 locs->set_in(1, Location::RegisterLocation(RCX));
726 locs->set_out(Location::RegisterLocation(RAX)); 734 locs->set_out(Location::RegisterLocation(RAX));
727 return locs; 735 return locs;
728 } 736 }
729 737
730 738
731 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 739 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
732 if (operands_class_id() == kSmiCid) { 740 if (operands_class_id() == kSmiCid) {
733 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 741 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
734 return; 742 return;
735 } 743 }
736 if (operands_class_id() == kDoubleCid) { 744 if (operands_class_id() == kDoubleCid) {
737 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 745 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
738 return; 746 return;
739 } 747 }
740 748
741 // Push arguments for the call. 749 // Push arguments for the call.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 compiler->GenerateInstanceCall(deopt_id(), 786 compiler->GenerateInstanceCall(deopt_id(),
779 token_pos(), 787 token_pos(),
780 function_name, 788 function_name,
781 kNumArguments, 789 kNumArguments,
782 Array::ZoneHandle(), // No optional arguments. 790 Array::ZoneHandle(), // No optional arguments.
783 kNumArgsChecked, 791 kNumArgsChecked,
784 locs()); 792 locs());
785 } 793 }
786 794
787 795
788 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 796 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
789 BranchInstr* branch) { 797 BranchInstr* branch) {
790 if (operands_class_id() == kSmiCid) { 798 if (operands_class_id() == kSmiCid) {
791 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 799 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
792 return; 800 return;
793 } 801 }
794 if (operands_class_id() == kDoubleCid) { 802 if (operands_class_id() == kDoubleCid) {
795 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 803 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
796 return; 804 return;
797 } 805 }
798 EmitNativeCode(compiler); 806 EmitNativeCode(compiler);
799 __ CompareObject(RAX, compiler->bool_true()); 807 __ CompareObject(RAX, compiler->bool_true());
800 branch->EmitBranchOnCondition(compiler, EQUAL); 808 branch->EmitBranchOnCondition(compiler, EQUAL);
801 } 809 }
802 810
803 811
804 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 812 LocationSummary* NativeCallComp::MakeLocationSummary() const {
805 const intptr_t kNumInputs = 0; 813 const intptr_t kNumInputs = 0;
806 const intptr_t kNumTemps = 3; 814 const intptr_t kNumTemps = 3;
807 LocationSummary* locs = 815 LocationSummary* locs =
808 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
809 locs->set_temp(0, Location::RegisterLocation(RAX)); 817 locs->set_temp(0, Location::RegisterLocation(RAX));
810 locs->set_temp(1, Location::RegisterLocation(RBX)); 818 locs->set_temp(1, Location::RegisterLocation(RBX));
811 locs->set_temp(2, Location::RegisterLocation(R10)); 819 locs->set_temp(2, Location::RegisterLocation(R10));
812 locs->set_out(Location::RegisterLocation(RAX)); 820 locs->set_out(Location::RegisterLocation(RAX));
813 return locs; 821 return locs;
814 } 822 }
815 823
816 824
817 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 825 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
818 ASSERT(locs()->temp(0).reg() == RAX); 826 ASSERT(locs()->temp(0).reg() == RAX);
819 ASSERT(locs()->temp(1).reg() == RBX); 827 ASSERT(locs()->temp(1).reg() == RBX);
820 ASSERT(locs()->temp(2).reg() == R10); 828 ASSERT(locs()->temp(2).reg() == R10);
821 Register result = locs()->out().reg(); 829 Register result = locs()->out().reg();
822 830
823 // Push the result place holder initialized to NULL. 831 // Push the result place holder initialized to NULL.
824 __ PushObject(Object::ZoneHandle()); 832 __ PushObject(Object::ZoneHandle());
825 // Pass a pointer to the first argument in RAX. 833 // Pass a pointer to the first argument in RAX.
826 intptr_t arg_count = argument_count(); 834 intptr_t arg_count = argument_count();
827 if (is_native_instance_closure()) { 835 if (is_native_instance_closure()) {
828 arg_count += 1; 836 arg_count += 1;
829 } 837 }
830 if (!has_optional_parameters() && !is_native_instance_closure()) { 838 if (!has_optional_parameters() && !is_native_instance_closure()) {
831 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); 839 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize));
832 } else { 840 } else {
833 __ leaq(RAX, 841 __ leaq(RAX,
834 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 842 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
835 } 843 }
836 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); 844 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
837 __ movq(R10, Immediate(arg_count)); 845 __ movq(R10, Immediate(arg_count));
838 compiler->GenerateCall(token_pos(), 846 compiler->GenerateCall(token_pos(),
839 &StubCode::CallNativeCFunctionLabel(), 847 &StubCode::CallNativeCFunctionLabel(),
840 PcDescriptors::kOther, 848 PcDescriptors::kOther,
841 locs()); 849 locs());
842 __ popq(result); 850 __ popq(result);
843 } 851 }
844 852
845 853
846 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 854 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
847 const intptr_t kNumInputs = 2; 855 const intptr_t kNumInputs = 2;
848 if (receiver_type() == kGrowableObjectArrayCid) { 856 if (receiver_type() == kGrowableObjectArrayCid) {
849 const intptr_t kNumTemps = 1; 857 const intptr_t kNumTemps = 1;
850 LocationSummary* locs = 858 LocationSummary* locs =
851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 859 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
852 locs->set_in(0, Location::RequiresRegister()); 860 locs->set_in(0, Location::RequiresRegister());
853 locs->set_in(1, Location::RequiresRegister()); 861 locs->set_in(1, Location::RequiresRegister());
854 locs->set_temp(0, Location::RequiresRegister()); 862 locs->set_temp(0, Location::RequiresRegister());
855 locs->set_out(Location::RequiresRegister()); 863 locs->set_out(Location::RequiresRegister());
856 return locs; 864 return locs;
857 } else { 865 } else {
858 ASSERT((receiver_type() == kArrayCid) || 866 ASSERT((receiver_type() == kArrayCid) ||
859 (receiver_type() == kImmutableArrayCid)); 867 (receiver_type() == kImmutableArrayCid));
860 return LocationSummary::Make(kNumInputs, 868 return LocationSummary::Make(kNumInputs,
861 Location::RequiresRegister(), 869 Location::RequiresRegister(),
862 LocationSummary::kNoCall); 870 LocationSummary::kNoCall);
863 } 871 }
864 } 872 }
865 873
866 874
867 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 875 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
868 Register receiver = locs()->in(0).reg(); 876 Register receiver = locs()->in(0).reg();
869 Register index = locs()->in(1).reg(); 877 Register index = locs()->in(1).reg();
870 Register result = locs()->out().reg(); 878 Register result = locs()->out().reg();
871 879
872 switch (receiver_type()) { 880 switch (receiver_type()) {
873 case kArrayCid: 881 case kArrayCid:
874 case kImmutableArrayCid: 882 case kImmutableArrayCid:
875 // Note that index is Smi, i.e, times 4. 883 // Note that index is Smi, i.e, times 4.
876 ASSERT(kSmiTagShift == 1); 884 ASSERT(kSmiTagShift == 1);
877 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); 885 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)));
878 break; 886 break;
879 887
880 case kGrowableObjectArrayCid: { 888 case kGrowableObjectArrayCid: {
881 Register temp = locs()->temp(0).reg(); 889 Register temp = locs()->temp(0).reg();
882 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 890 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
883 // Note that index is Smi, i.e, times 4. 891 // Note that index is Smi, i.e, times 4.
884 ASSERT(kSmiTagShift == 1); 892 ASSERT(kSmiTagShift == 1);
885 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); 893 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray)));
886 break; 894 break;
887 } 895 }
888 896
889 default: 897 default:
890 UNREACHABLE(); 898 UNREACHABLE();
891 break; 899 break;
892 } 900 }
893 } 901 }
894 902
895 903
896 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 904 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
897 const intptr_t kNumInputs = 3; 905 const intptr_t kNumInputs = 3;
898 if (receiver_type() == kGrowableObjectArrayCid) { 906 if (receiver_type() == kGrowableObjectArrayCid) {
899 const intptr_t kNumTemps = 1; 907 const intptr_t kNumTemps = 1;
900 LocationSummary* locs = 908 LocationSummary* locs =
901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
902 locs->set_in(0, Location::RequiresRegister()); 910 locs->set_in(0, Location::RequiresRegister());
903 locs->set_in(1, Location::RequiresRegister()); 911 locs->set_in(1, Location::RequiresRegister());
904 locs->set_in(2, Location::RequiresRegister()); 912 locs->set_in(2, Location::RequiresRegister());
905 locs->set_temp(0, Location::RequiresRegister()); 913 locs->set_temp(0, Location::RequiresRegister());
906 return locs; 914 return locs;
907 } else { 915 } else {
908 ASSERT(receiver_type() == kArrayCid); 916 ASSERT(receiver_type() == kArrayCid);
909 return LocationSummary::Make(kNumInputs, 917 return LocationSummary::Make(kNumInputs,
910 Location::NoLocation(), 918 Location::NoLocation(),
911 LocationSummary::kNoCall); 919 LocationSummary::kNoCall);
912 } 920 }
913 } 921 }
914 922
915 923
916 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 924 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
917 Register receiver = locs()->in(0).reg(); 925 Register receiver = locs()->in(0).reg();
918 Register index = locs()->in(1).reg(); 926 Register index = locs()->in(1).reg();
919 Register value = locs()->in(2).reg(); 927 Register value = locs()->in(2).reg();
920 928
921 switch (receiver_type()) { 929 switch (receiver_type()) {
922 case kArrayCid: 930 case kArrayCid:
923 case kImmutableArrayCid: 931 case kImmutableArrayCid:
924 // Note that index is Smi, i.e, times 4. 932 // Note that index is Smi, i.e, times 4.
925 ASSERT(kSmiTagShift == 1); 933 ASSERT(kSmiTagShift == 1);
926 if (this->value()->NeedsStoreBuffer()) { 934 if (this->value()->NeedsStoreBuffer()) {
(...skipping 24 matching lines...) Expand all
951 break; 959 break;
952 } 960 }
953 961
954 default: 962 default:
955 UNREACHABLE(); 963 UNREACHABLE();
956 break; 964 break;
957 } 965 }
958 } 966 }
959 967
960 968
961 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { 969 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
962 // TODO(fschneider): For this instruction the input register may be 970 // TODO(fschneider): For this instruction the input register may be
963 // reused for the result (but is not required to) because the input 971 // reused for the result (but is not required to) because the input
964 // is not used after the result is defined. We should consider adding 972 // is not used after the result is defined. We should consider adding
965 // this information to the input policy. 973 // this information to the input policy.
966 return LocationSummary::Make(1, 974 return LocationSummary::Make(1,
967 Location::RequiresRegister(), 975 Location::RequiresRegister(),
968 LocationSummary::kNoCall); 976 LocationSummary::kNoCall);
969 } 977 }
970 978
971 979
972 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 980 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
973 Register instance_reg = locs()->in(0).reg(); 981 Register instance_reg = locs()->in(0).reg();
974 Register result_reg = locs()->out().reg(); 982 Register result_reg = locs()->out().reg();
975 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); 983 __ movq(result_reg, FieldAddress(instance_reg, field().Offset()));
976 } 984 }
977 985
978 986
979 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 987 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const {
980 const intptr_t kNumInputs = 2; 988 const intptr_t kNumInputs = 2;
981 const intptr_t num_temps = 0; 989 const intptr_t num_temps = 0;
982 LocationSummary* summary = 990 LocationSummary* summary =
983 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); 991 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall);
984 summary->set_in(0, Location::RequiresRegister()); 992 summary->set_in(0, Location::RequiresRegister());
985 summary->set_in(1, Location::RequiresRegister()); 993 summary->set_in(1, Location::RequiresRegister());
986 return summary; 994 return summary;
987 } 995 }
988 996
989 997
990 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 998 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
991 Register instance_reg = locs()->in(0).reg(); 999 Register instance_reg = locs()->in(0).reg();
992 Register value_reg = locs()->in(1).reg(); 1000 Register value_reg = locs()->in(1).reg();
993 if (this->value()->NeedsStoreBuffer()) { 1001 if (this->value()->NeedsStoreBuffer()) {
994 __ StoreIntoObject(instance_reg, 1002 __ StoreIntoObject(instance_reg,
995 FieldAddress(instance_reg, field().Offset()), value_reg); 1003 FieldAddress(instance_reg, field().Offset()), value_reg);
996 } else { 1004 } else {
997 __ StoreIntoObjectNoBarrier(instance_reg, 1005 __ StoreIntoObjectNoBarrier(instance_reg,
998 FieldAddress(instance_reg, field().Offset()), value_reg); 1006 FieldAddress(instance_reg, field().Offset()), value_reg);
999 } 1007 }
1000 } 1008 }
1001 1009
1002 1010
1003 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { 1011 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
1004 return LocationSummary::Make(0, 1012 return LocationSummary::Make(0,
1005 Location::RequiresRegister(), 1013 Location::RequiresRegister(),
1006 LocationSummary::kNoCall); 1014 LocationSummary::kNoCall);
1007 } 1015 }
1008 1016
1009 1017
1010 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1018 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1011 Register result = locs()->out().reg(); 1019 Register result = locs()->out().reg();
1012 __ LoadObject(result, field()); 1020 __ LoadObject(result, field());
1013 __ movq(result, FieldAddress(result, Field::value_offset())); 1021 __ movq(result, FieldAddress(result, Field::value_offset()));
1014 } 1022 }
1015 1023
1016 1024
1017 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { 1025 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
1018 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1026 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1019 locs->set_in(0, Location::RequiresRegister()); 1027 locs->set_in(0, Location::RequiresRegister());
1020 locs->set_temp(0, Location::RequiresRegister()); 1028 locs->set_temp(0, Location::RequiresRegister());
1021 locs->set_out(Location::SameAsFirstInput()); 1029 locs->set_out(Location::SameAsFirstInput());
1022 return locs; 1030 return locs;
1023 } 1031 }
1024 1032
1025 1033
1026 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1034 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1027 Register value = locs()->in(0).reg(); 1035 Register value = locs()->in(0).reg();
1028 Register temp = locs()->temp(0).reg(); 1036 Register temp = locs()->temp(0).reg();
1029 ASSERT(locs()->out().reg() == value); 1037 ASSERT(locs()->out().reg() == value);
1030 1038
1031 __ LoadObject(temp, field()); 1039 __ LoadObject(temp, field());
1032 if (this->value()->NeedsStoreBuffer()) { 1040 if (this->value()->NeedsStoreBuffer()) {
1033 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); 1041 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
1034 } else { 1042 } else {
1035 __ StoreIntoObjectNoBarrier( 1043 __ StoreIntoObjectNoBarrier(
1036 temp, FieldAddress(temp, Field::value_offset()), value); 1044 temp, FieldAddress(temp, Field::value_offset()), value);
1037 } 1045 }
1038 } 1046 }
1039 1047
1040 1048
1041 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { 1049 LocationSummary* InstanceOfComp::MakeLocationSummary() const {
1042 const intptr_t kNumInputs = 3; 1050 const intptr_t kNumInputs = 3;
1043 const intptr_t kNumTemps = 0; 1051 const intptr_t kNumTemps = 0;
1044 LocationSummary* summary = 1052 LocationSummary* summary =
1045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1046 summary->set_in(0, Location::RegisterLocation(RAX)); 1054 summary->set_in(0, Location::RegisterLocation(RAX));
1047 summary->set_in(1, Location::RegisterLocation(RCX)); 1055 summary->set_in(1, Location::RegisterLocation(RCX));
1048 summary->set_in(2, Location::RegisterLocation(RDX)); 1056 summary->set_in(2, Location::RegisterLocation(RDX));
1049 summary->set_out(Location::RegisterLocation(RAX)); 1057 summary->set_out(Location::RegisterLocation(RAX));
1050 return summary; 1058 return summary;
1051 } 1059 }
1052 1060
1053 1061
1054 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1062 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1055 ASSERT(locs()->in(0).reg() == RAX); // Value. 1063 ASSERT(locs()->in(0).reg() == RAX); // Value.
1056 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1064 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1057 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1065 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1058 1066
1059 compiler->GenerateInstanceOf(token_pos(), 1067 compiler->GenerateInstanceOf(token_pos(),
1060 type(), 1068 type(),
1061 negate_result(), 1069 negate_result(),
1062 locs()); 1070 locs());
1063 ASSERT(locs()->out().reg() == RAX); 1071 ASSERT(locs()->out().reg() == RAX);
1064 } 1072 }
1065 1073
1066 1074
1067 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { 1075 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1068 const intptr_t kNumInputs = 1; 1076 const intptr_t kNumInputs = 1;
1069 const intptr_t kNumTemps = 0; 1077 const intptr_t kNumTemps = 0;
1070 LocationSummary* locs = 1078 LocationSummary* locs =
1071 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1079 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1072 locs->set_in(0, Location::RegisterLocation(RBX)); 1080 locs->set_in(0, Location::RegisterLocation(RBX));
1073 locs->set_out(Location::RegisterLocation(RAX)); 1081 locs->set_out(Location::RegisterLocation(RAX));
1074 return locs; 1082 return locs;
1075 } 1083 }
1076 1084
1077 1085
1078 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1086 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1079 // Allocate the array. R10 = length, RBX = element type. 1087 // Allocate the array. R10 = length, RBX = element type.
1080 ASSERT(locs()->in(0).reg() == RBX); 1088 ASSERT(locs()->in(0).reg() == RBX);
1081 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); 1089 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount())));
1082 compiler->GenerateCall(token_pos(), 1090 compiler->GenerateCall(token_pos(),
1083 &StubCode::AllocateArrayLabel(), 1091 &StubCode::AllocateArrayLabel(),
1084 PcDescriptors::kOther, 1092 PcDescriptors::kOther,
1085 locs()); 1093 locs());
1086 ASSERT(locs()->out().reg() == RAX); 1094 ASSERT(locs()->out().reg() == RAX);
1087 1095
1088 // Pop the element values from the stack into the array. 1096 // Pop the element values from the stack into the array.
1089 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); 1097 __ leaq(R10, FieldAddress(RAX, Array::data_offset()));
1090 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1098 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1091 __ popq(Address(R10, i * kWordSize)); 1099 __ popq(Address(R10, i * kWordSize));
1092 } 1100 }
1093 } 1101 }
1094 1102
1095 1103
1096 LocationSummary* 1104 LocationSummary*
1097 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { 1105 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const {
1098 const intptr_t kNumInputs = 2; 1106 const intptr_t kNumInputs = 2;
1099 const intptr_t kNumTemps = 0; 1107 const intptr_t kNumTemps = 0;
1100 LocationSummary* locs = 1108 LocationSummary* locs =
1101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1109 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1102 locs->set_in(0, Location::RegisterLocation(RAX)); 1110 locs->set_in(0, Location::RegisterLocation(RAX));
1103 locs->set_in(1, Location::RegisterLocation(RCX)); 1111 locs->set_in(1, Location::RegisterLocation(RCX));
1104 locs->set_out(Location::RegisterLocation(RAX)); 1112 locs->set_out(Location::RegisterLocation(RAX));
1105 return locs; 1113 return locs;
1106 } 1114 }
1107 1115
1108 1116
1109 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( 1117 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
1110 FlowGraphCompiler* compiler) { 1118 FlowGraphCompiler* compiler) {
1111 const Class& cls = Class::ZoneHandle(constructor().Owner()); 1119 const Class& cls = Class::ZoneHandle(constructor().Owner());
1112 Register type_arguments = locs()->in(0).reg(); 1120 Register type_arguments = locs()->in(0).reg();
1113 Register instantiator_type_arguments = locs()->in(1).reg(); 1121 Register instantiator_type_arguments = locs()->in(1).reg();
1114 Register result = locs()->out().reg(); 1122 Register result = locs()->out().reg();
1115 1123
1116 // Push the result place holder initialized to NULL. 1124 // Push the result place holder initialized to NULL.
1117 __ PushObject(Object::ZoneHandle()); 1125 __ PushObject(Object::ZoneHandle());
1118 __ PushObject(cls); 1126 __ PushObject(cls);
1119 __ pushq(type_arguments); 1127 __ pushq(type_arguments);
1120 __ pushq(instantiator_type_arguments); 1128 __ pushq(instantiator_type_arguments);
1121 compiler->GenerateCallRuntime(token_pos(), 1129 compiler->GenerateCallRuntime(token_pos(),
1122 kAllocateObjectWithBoundsCheckRuntimeEntry, 1130 kAllocateObjectWithBoundsCheckRuntimeEntry,
1123 locs()); 1131 locs());
1124 // Pop instantiator type arguments, type arguments, and class. 1132 // Pop instantiator type arguments, type arguments, and class.
1125 __ Drop(3); 1133 __ Drop(3);
1126 __ popq(result); // Pop new instance. 1134 __ popq(result); // Pop new instance.
1127 } 1135 }
1128 1136
1129 1137
1130 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const { 1138 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1131 return LocationSummary::Make(1, 1139 return LocationSummary::Make(1,
1132 Location::RequiresRegister(), 1140 Location::RequiresRegister(),
1133 LocationSummary::kNoCall); 1141 LocationSummary::kNoCall);
1134 } 1142 }
1135 1143
1136 1144
1137 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1145 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1138 Register instance_reg = locs()->in(0).reg(); 1146 Register instance_reg = locs()->in(0).reg();
1139 Register result_reg = locs()->out().reg(); 1147 Register result_reg = locs()->out().reg();
1140 1148
1141 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1149 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1142 } 1150 }
1143 1151
1144 1152
1145 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1153 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
1146 const intptr_t kNumInputs = 1; 1154 const intptr_t kNumInputs = 1;
1147 const intptr_t kNumTemps = 0; 1155 const intptr_t kNumTemps = 0;
1148 LocationSummary* locs = 1156 LocationSummary* locs =
1149 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1157 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1150 locs->set_in(0, Location::RegisterLocation(RAX)); 1158 locs->set_in(0, Location::RegisterLocation(RAX));
1151 locs->set_out(Location::RegisterLocation(RAX)); 1159 locs->set_out(Location::RegisterLocation(RAX));
1152 return locs; 1160 return locs;
1153 } 1161 }
1154 1162
1155 1163
1156 void InstantiateTypeArgumentsInstr::EmitNativeCode( 1164 void InstantiateTypeArgumentsComp::EmitNativeCode(
1157 FlowGraphCompiler* compiler) { 1165 FlowGraphCompiler* compiler) {
1158 Register instantiator_reg = locs()->in(0).reg(); 1166 Register instantiator_reg = locs()->in(0).reg();
1159 Register result_reg = locs()->out().reg(); 1167 Register result_reg = locs()->out().reg();
1160 1168
1161 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1169 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1162 // (or null). 1170 // (or null).
1163 // If the instantiator is null and if the type argument vector 1171 // If the instantiator is null and if the type argument vector
1164 // instantiated from null becomes a vector of Dynamic, then use null as 1172 // instantiated from null becomes a vector of Dynamic, then use null as
1165 // the type arguments. 1173 // the type arguments.
1166 Label type_arguments_instantiated; 1174 Label type_arguments_instantiated;
(...skipping 28 matching lines...) Expand all
1195 locs()); 1203 locs());
1196 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1204 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1197 __ popq(result_reg); // Pop instantiated type arguments. 1205 __ popq(result_reg); // Pop instantiated type arguments.
1198 __ Bind(&type_arguments_instantiated); 1206 __ Bind(&type_arguments_instantiated);
1199 ASSERT(instantiator_reg == result_reg); 1207 ASSERT(instantiator_reg == result_reg);
1200 // 'result_reg': Instantiated type arguments. 1208 // 'result_reg': Instantiated type arguments.
1201 } 1209 }
1202 1210
1203 1211
1204 LocationSummary* 1212 LocationSummary*
1205 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1213 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
1206 const intptr_t kNumInputs = 1; 1214 const intptr_t kNumInputs = 1;
1207 const intptr_t kNumTemps = 0; 1215 const intptr_t kNumTemps = 0;
1208 LocationSummary* locs = 1216 LocationSummary* locs =
1209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1210 locs->set_in(0, Location::RequiresRegister()); 1218 locs->set_in(0, Location::RequiresRegister());
1211 locs->set_out(Location::SameAsFirstInput()); 1219 locs->set_out(Location::SameAsFirstInput());
1212 return locs; 1220 return locs;
1213 } 1221 }
1214 1222
1215 1223
1216 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( 1224 void ExtractConstructorTypeArgumentsComp::EmitNativeCode(
1217 FlowGraphCompiler* compiler) { 1225 FlowGraphCompiler* compiler) {
1218 Register instantiator_reg = locs()->in(0).reg(); 1226 Register instantiator_reg = locs()->in(0).reg();
1219 Register result_reg = locs()->out().reg(); 1227 Register result_reg = locs()->out().reg();
1220 ASSERT(instantiator_reg == result_reg); 1228 ASSERT(instantiator_reg == result_reg);
1221 1229
1222 // instantiator_reg is the instantiator type argument vector, i.e. an 1230 // instantiator_reg is the instantiator type argument vector, i.e. an
1223 // AbstractTypeArguments object (or null). 1231 // AbstractTypeArguments object (or null).
1224 // If the instantiator is null and if the type argument vector 1232 // If the instantiator is null and if the type argument vector
1225 // instantiated from null becomes a vector of Dynamic, then use null as 1233 // instantiated from null becomes a vector of Dynamic, then use null as
1226 // the type arguments. 1234 // the type arguments.
(...skipping 24 matching lines...) Expand all
1251 // In the non-factory case, we rely on the allocation stub to 1259 // In the non-factory case, we rely on the allocation stub to
1252 // instantiate the type arguments. 1260 // instantiate the type arguments.
1253 __ LoadObject(result_reg, type_arguments()); 1261 __ LoadObject(result_reg, type_arguments());
1254 // result_reg: uninstantiated type arguments. 1262 // result_reg: uninstantiated type arguments.
1255 __ Bind(&type_arguments_instantiated); 1263 __ Bind(&type_arguments_instantiated);
1256 // result_reg: uninstantiated or instantiated type arguments. 1264 // result_reg: uninstantiated or instantiated type arguments.
1257 } 1265 }
1258 1266
1259 1267
1260 LocationSummary* 1268 LocationSummary*
1261 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1269 ExtractConstructorInstantiatorComp::MakeLocationSummary() const {
1262 const intptr_t kNumInputs = 1; 1270 const intptr_t kNumInputs = 1;
1263 const intptr_t kNumTemps = 0; 1271 const intptr_t kNumTemps = 0;
1264 LocationSummary* locs = 1272 LocationSummary* locs =
1265 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1273 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1266 locs->set_in(0, Location::RequiresRegister()); 1274 locs->set_in(0, Location::RequiresRegister());
1267 locs->set_out(Location::SameAsFirstInput()); 1275 locs->set_out(Location::SameAsFirstInput());
1268 return locs; 1276 return locs;
1269 } 1277 }
1270 1278
1271 1279
1272 void ExtractConstructorInstantiatorInstr::EmitNativeCode( 1280 void ExtractConstructorInstantiatorComp::EmitNativeCode(
1273 FlowGraphCompiler* compiler) { 1281 FlowGraphCompiler* compiler) {
1274 Register instantiator_reg = locs()->in(0).reg(); 1282 Register instantiator_reg = locs()->in(0).reg();
1275 ASSERT(locs()->out().reg() == instantiator_reg); 1283 ASSERT(locs()->out().reg() == instantiator_reg);
1276 1284
1277 // instantiator_reg is the instantiator AbstractTypeArguments object 1285 // instantiator_reg is the instantiator AbstractTypeArguments object
1278 // (or null). If the instantiator is null and if the type argument vector 1286 // (or null). If the instantiator is null and if the type argument vector
1279 // instantiated from null becomes a vector of Dynamic, then use null as 1287 // instantiated from null becomes a vector of Dynamic, then use null as
1280 // the type arguments and do not pass the instantiator. 1288 // the type arguments and do not pass the instantiator.
1281 Label done; 1289 Label done;
1282 const intptr_t len = type_arguments().Length(); 1290 const intptr_t len = type_arguments().Length();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1323 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1316 // instantiated type arguments, no proper instantiator needed. 1324 // instantiated type arguments, no proper instantiator needed.
1317 __ movq(instantiator_reg, 1325 __ movq(instantiator_reg,
1318 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1326 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1319 } 1327 }
1320 __ Bind(&done); 1328 __ Bind(&done);
1321 // instantiator_reg: instantiator or kNoInstantiator. 1329 // instantiator_reg: instantiator or kNoInstantiator.
1322 } 1330 }
1323 1331
1324 1332
1325 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1333 LocationSummary* AllocateContextComp::MakeLocationSummary() const {
1326 const intptr_t kNumInputs = 0; 1334 const intptr_t kNumInputs = 0;
1327 const intptr_t kNumTemps = 1; 1335 const intptr_t kNumTemps = 1;
1328 LocationSummary* locs = 1336 LocationSummary* locs =
1329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1330 locs->set_temp(0, Location::RegisterLocation(R10)); 1338 locs->set_temp(0, Location::RegisterLocation(R10));
1331 locs->set_out(Location::RegisterLocation(RAX)); 1339 locs->set_out(Location::RegisterLocation(RAX));
1332 return locs; 1340 return locs;
1333 } 1341 }
1334 1342
1335 1343
1336 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1344 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1337 ASSERT(locs()->temp(0).reg() == R10); 1345 ASSERT(locs()->temp(0).reg() == R10);
1338 ASSERT(locs()->out().reg() == RAX); 1346 ASSERT(locs()->out().reg() == RAX);
1339 1347
1340 __ movq(R10, Immediate(num_context_variables())); 1348 __ movq(R10, Immediate(num_context_variables()));
1341 const ExternalLabel label("alloc_context", 1349 const ExternalLabel label("alloc_context",
1342 StubCode::AllocateContextEntryPoint()); 1350 StubCode::AllocateContextEntryPoint());
1343 compiler->GenerateCall(token_pos(), 1351 compiler->GenerateCall(token_pos(),
1344 &label, 1352 &label,
1345 PcDescriptors::kOther, 1353 PcDescriptors::kOther,
1346 locs()); 1354 locs());
1347 } 1355 }
1348 1356
1349 1357
1350 LocationSummary* CloneContextInstr::MakeLocationSummary() const { 1358 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1351 const intptr_t kNumInputs = 1; 1359 const intptr_t kNumInputs = 1;
1352 const intptr_t kNumTemps = 0; 1360 const intptr_t kNumTemps = 0;
1353 LocationSummary* locs = 1361 LocationSummary* locs =
1354 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1362 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1355 locs->set_in(0, Location::RegisterLocation(RAX)); 1363 locs->set_in(0, Location::RegisterLocation(RAX));
1356 locs->set_out(Location::RegisterLocation(RAX)); 1364 locs->set_out(Location::RegisterLocation(RAX));
1357 return locs; 1365 return locs;
1358 } 1366 }
1359 1367
1360 1368
1361 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1369 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1362 Register context_value = locs()->in(0).reg(); 1370 Register context_value = locs()->in(0).reg();
1363 Register result = locs()->out().reg(); 1371 Register result = locs()->out().reg();
1364 1372
1365 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1373 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1366 __ pushq(context_value); 1374 __ pushq(context_value);
1367 compiler->GenerateCallRuntime(token_pos(), 1375 compiler->GenerateCallRuntime(token_pos(),
1368 kCloneContextRuntimeEntry, 1376 kCloneContextRuntimeEntry,
1369 locs()); 1377 locs());
1370 __ popq(result); // Remove argument. 1378 __ popq(result); // Remove argument.
1371 __ popq(result); // Get result (cloned context). 1379 __ popq(result); // Get result (cloned context).
1372 } 1380 }
1373 1381
1374 1382
1375 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { 1383 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1376 return LocationSummary::Make(0, 1384 return LocationSummary::Make(0,
1377 Location::NoLocation(), 1385 Location::NoLocation(),
1378 LocationSummary::kNoCall); 1386 LocationSummary::kNoCall);
1379 } 1387 }
1380 1388
1381 1389
1382 // Restore stack and initialize the two exception variables: 1390 // Restore stack and initialize the two exception variables:
1383 // exception and stack trace variables. 1391 // exception and stack trace variables.
1384 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1392 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1385 // Restore RSP from RBP as we are coming from a throw and the code for 1393 // Restore RSP from RBP as we are coming from a throw and the code for
1386 // popping arguments has not been run. 1394 // popping arguments has not been run.
1387 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; 1395 const intptr_t locals_space_size = compiler->StackSize() * kWordSize;
1388 ASSERT(locals_space_size >= 0); 1396 ASSERT(locals_space_size >= 0);
1389 const intptr_t offset_size = 1397 const intptr_t offset_size =
1390 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; 1398 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP;
1391 __ leaq(RSP, Address(RBP, offset_size)); 1399 __ leaq(RSP, Address(RBP, offset_size));
1392 1400
1393 ASSERT(!exception_var().is_captured()); 1401 ASSERT(!exception_var().is_captured());
1394 ASSERT(!stacktrace_var().is_captured()); 1402 ASSERT(!stacktrace_var().is_captured());
1395 __ movq(Address(RBP, exception_var().index() * kWordSize), 1403 __ movq(Address(RBP, exception_var().index() * kWordSize),
1396 kExceptionObjectReg); 1404 kExceptionObjectReg);
1397 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), 1405 __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
1398 kStackTraceObjectReg); 1406 kStackTraceObjectReg);
1399 } 1407 }
1400 1408
1401 1409
1402 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 1410 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
1403 const intptr_t kNumInputs = 0; 1411 const intptr_t kNumInputs = 0;
1404 const intptr_t kNumTemps = 1; 1412 const intptr_t kNumTemps = 1;
1405 LocationSummary* summary = 1413 LocationSummary* summary =
1406 new LocationSummary(kNumInputs, 1414 new LocationSummary(kNumInputs,
1407 kNumTemps, 1415 kNumTemps,
1408 LocationSummary::kCallOnSlowPath); 1416 LocationSummary::kCallOnSlowPath);
1409 summary->set_temp(0, Location::RequiresRegister()); 1417 summary->set_temp(0, Location::RequiresRegister());
1410 return summary; 1418 return summary;
1411 } 1419 }
1412 1420
1413 1421
1414 class CheckStackOverflowSlowPath : public SlowPathCode { 1422 class CheckStackOverflowSlowPath : public SlowPathCode {
1415 public: 1423 public:
1416 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) 1424 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1417 : instruction_(instruction) { } 1425 : computation_(computation) { }
1418 1426
1419 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1427 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1420 __ Bind(entry_label()); 1428 __ Bind(entry_label());
1421 compiler->SaveLiveRegisters(instruction_->locs()); 1429 compiler->SaveLiveRegisters(computation_->locs());
1422 compiler->GenerateCallRuntime(instruction_->token_pos(), 1430 compiler->GenerateCallRuntime(computation_->token_pos(),
1423 kStackOverflowRuntimeEntry, 1431 kStackOverflowRuntimeEntry,
1424 instruction_->locs()); 1432 computation_->locs());
1425 compiler->RestoreLiveRegisters(instruction_->locs()); 1433 compiler->RestoreLiveRegisters(computation_->locs());
1426 __ jmp(exit_label()); 1434 __ jmp(exit_label());
1427 } 1435 }
1428 1436
1429 private: 1437 private:
1430 CheckStackOverflowInstr* instruction_; 1438 CheckStackOverflowComp* computation_;
1431 }; 1439 };
1432 1440
1433 1441
1434 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1442 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1435 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); 1443 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
1436 compiler->AddSlowPathCode(slow_path); 1444 compiler->AddSlowPathCode(slow_path);
1437 1445
1438 Register temp = locs()->temp(0).reg(); 1446 Register temp = locs()->temp(0).reg();
1439 // Generate stack overflow check. 1447 // Generate stack overflow check.
1440 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); 1448 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
1441 __ cmpq(RSP, Address(temp, 0)); 1449 __ cmpq(RSP, Address(temp, 0));
1442 __ j(BELOW_EQUAL, slow_path->entry_label()); 1450 __ j(BELOW_EQUAL, slow_path->entry_label());
1443 __ Bind(slow_path->exit_label()); 1451 __ Bind(slow_path->exit_label());
1444 } 1452 }
1445 1453
1446 1454
1447 static bool CanBeImmediate(const Object& constant) { 1455 static bool CanBeImmediate(const Object& constant) {
1448 return constant.IsSmi() && 1456 return constant.IsSmi() &&
1449 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); 1457 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32();
1450 } 1458 }
1451 1459
1452 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 1460 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const {
1453 const intptr_t kNumInputs = 2; 1461 const intptr_t kNumInputs = 2;
1454 1462
1455 ConstantInstr* right_constant = right()->definition()->AsConstant(); 1463 ConstantComp* right_constant = right()->definition()->AsConstant();
1456 if ((right_constant != NULL) && 1464 if ((right_constant != NULL) &&
1457 (op_kind() != Token::kTRUNCDIV) && 1465 (op_kind() != Token::kTRUNCDIV) &&
1458 (op_kind() != Token::kSHL) && 1466 (op_kind() != Token::kSHL) &&
1459 (op_kind() != Token::kMUL) && 1467 (op_kind() != Token::kMUL) &&
1460 CanBeImmediate(right_constant->value())) { 1468 CanBeImmediate(right_constant->value())) {
1461 const intptr_t kNumTemps = 0; 1469 const intptr_t kNumTemps = 0;
1462 LocationSummary* summary = 1470 LocationSummary* summary =
1463 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1471 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1464 summary->set_in(0, Location::RequiresRegister()); 1472 summary->set_in(0, Location::RequiresRegister());
1465 summary->set_in(1, Location::Constant(right_constant->value())); 1473 summary->set_in(1, Location::Constant(right_constant->value()));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 LocationSummary* summary = 1511 LocationSummary* summary =
1504 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1512 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1505 summary->set_in(0, Location::RequiresRegister()); 1513 summary->set_in(0, Location::RequiresRegister());
1506 summary->set_in(1, Location::RequiresRegister()); 1514 summary->set_in(1, Location::RequiresRegister());
1507 summary->set_out(Location::SameAsFirstInput()); 1515 summary->set_out(Location::SameAsFirstInput());
1508 return summary; 1516 return summary;
1509 } 1517 }
1510 } 1518 }
1511 1519
1512 1520
1513 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1521 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1514 Register left = locs()->in(0).reg(); 1522 Register left = locs()->in(0).reg();
1515 Register result = locs()->out().reg(); 1523 Register result = locs()->out().reg();
1516 ASSERT(left == result); 1524 ASSERT(left == result);
1517 Label* deopt = NULL; 1525 Label* deopt = NULL;
1518 switch (op_kind()) { 1526 switch (op_kind()) {
1519 case Token::kBIT_AND: 1527 case Token::kBIT_AND:
1520 case Token::kBIT_OR: 1528 case Token::kBIT_OR:
1521 case Token::kBIT_XOR: 1529 case Token::kBIT_XOR:
1522 // Can't deoptimize. Arguments are already checked for smi. 1530 // Can't deoptimize. Arguments are already checked for smi.
1523 break; 1531 break;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 UNREACHABLE(); 1726 UNREACHABLE();
1719 break; 1727 break;
1720 } 1728 }
1721 default: 1729 default:
1722 UNREACHABLE(); 1730 UNREACHABLE();
1723 break; 1731 break;
1724 } 1732 }
1725 } 1733 }
1726 1734
1727 1735
1728 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 1736 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const {
1729 ASSERT(op_kind() == Token::kBIT_AND); 1737 ASSERT(op_kind() == Token::kBIT_AND);
1730 const intptr_t kNumInputs = 2; 1738 const intptr_t kNumInputs = 2;
1731 const intptr_t kNumTemps = 0; 1739 const intptr_t kNumTemps = 0;
1732 LocationSummary* summary = 1740 LocationSummary* summary =
1733 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1741 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1734 summary->set_in(0, Location::RegisterLocation(RAX)); 1742 summary->set_in(0, Location::RegisterLocation(RAX));
1735 summary->set_in(1, Location::RegisterLocation(RCX)); 1743 summary->set_in(1, Location::RegisterLocation(RCX));
1736 summary->set_out(Location::RegisterLocation(RAX)); 1744 summary->set_out(Location::RegisterLocation(RAX));
1737 return summary; 1745 return summary;
1738 } 1746 }
1739 1747
1740 1748
1741 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1749 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1742 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1750 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1743 // receiver and a Mint or Smi argument. We fall back to the run time call if 1751 // receiver and a Mint or Smi argument. We fall back to the run time call if
1744 // both receiver and argument are Mint or if one of them is Mint and the other 1752 // both receiver and argument are Mint or if one of them is Mint and the other
1745 // is a negative Smi. 1753 // is a negative Smi.
1746 Register left = locs()->in(0).reg(); 1754 Register left = locs()->in(0).reg();
1747 Register right = locs()->in(1).reg(); 1755 Register right = locs()->in(1).reg();
1748 Register result = locs()->out().reg(); 1756 Register result = locs()->out().reg();
1749 ASSERT(left == result); 1757 ASSERT(left == result);
1750 ASSERT(op_kind() == Token::kBIT_AND); 1758 ASSERT(op_kind() == Token::kBIT_AND);
1751 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1759 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 instance_call()->ArgumentCount(), 1828 instance_call()->ArgumentCount(),
1821 instance_call()->argument_names(), 1829 instance_call()->argument_names(),
1822 locs()); 1830 locs());
1823 ASSERT(result == RAX); 1831 ASSERT(result == RAX);
1824 } 1832 }
1825 } 1833 }
1826 __ Bind(&done); 1834 __ Bind(&done);
1827 } 1835 }
1828 1836
1829 1837
1830 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { 1838 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const {
1831 ASSERT((left()->ResultCid() != kDoubleCid) && 1839 ASSERT((left()->ResultCid() != kDoubleCid) &&
1832 (right()->ResultCid() != kDoubleCid)); 1840 (right()->ResultCid() != kDoubleCid));
1833 const intptr_t kNumInputs = 2; 1841 const intptr_t kNumInputs = 2;
1834 const intptr_t kNumTemps = 1; 1842 const intptr_t kNumTemps = 1;
1835 LocationSummary* summary = 1843 LocationSummary* summary =
1836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1837 summary->set_in(0, Location::RequiresRegister()); 1845 summary->set_in(0, Location::RequiresRegister());
1838 summary->set_in(1, Location::RequiresRegister()); 1846 summary->set_in(1, Location::RequiresRegister());
1839 summary->set_temp(0, Location::RequiresRegister()); 1847 summary->set_temp(0, Location::RequiresRegister());
1840 return summary; 1848 return summary;
1841 } 1849 }
1842 1850
1843 1851
1844 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1852 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1845 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); 1853 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(),
1854 kDeoptBinaryDoubleOp);
1855
1846 Register temp = locs()->temp(0).reg(); 1856 Register temp = locs()->temp(0).reg();
1847 __ movq(temp, locs()->in(0).reg()); 1857 __ movq(temp, locs()->in(0).reg());
1848 __ orq(temp, locs()->in(1).reg()); 1858 __ orq(temp, locs()->in(1).reg());
1849 __ testl(temp, Immediate(kSmiTagMask)); 1859 __ testl(temp, Immediate(kSmiTagMask));
1850 __ j(ZERO, deopt); 1860 __ j(ZERO, deopt);
1851 } 1861 }
1852 1862
1853 1863
1854 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { 1864 LocationSummary* BoxDoubleComp::MakeLocationSummary() const {
1855 const intptr_t kNumInputs = 1; 1865 const intptr_t kNumInputs = 1;
1856 const intptr_t kNumTemps = 0; 1866 const intptr_t kNumTemps = 0;
1857 LocationSummary* summary = 1867 LocationSummary* summary =
1858 new LocationSummary(kNumInputs, 1868 new LocationSummary(kNumInputs,
1859 kNumTemps, 1869 kNumTemps,
1860 LocationSummary::kCallOnSlowPath); 1870 LocationSummary::kCallOnSlowPath);
1861 summary->set_in(0, Location::RequiresXmmRegister()); 1871 summary->set_in(0, Location::RequiresXmmRegister());
1862 summary->set_out(Location::RequiresRegister()); 1872 summary->set_out(Location::RequiresRegister());
1863 return summary; 1873 return summary;
1864 } 1874 }
1865 1875
1866 1876
1867 class BoxDoubleSlowPath : public SlowPathCode { 1877 class BoxDoubleSlowPath : public SlowPathCode {
1868 public: 1878 public:
1869 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) 1879 explicit BoxDoubleSlowPath(BoxDoubleComp* computation)
1870 : instruction_(instruction) { } 1880 : computation_(computation) { }
1871 1881
1872 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1882 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1873 __ Bind(entry_label()); 1883 __ Bind(entry_label());
1874 const Class& double_class = compiler->double_class(); 1884 const Class& double_class = compiler->double_class();
1875 const Code& stub = 1885 const Code& stub =
1876 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1886 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1877 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1887 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1878 1888
1879 LocationSummary* locs = instruction_->locs(); 1889 LocationSummary* locs = computation_->locs();
1880 locs->live_registers()->Remove(locs->out()); 1890 locs->live_registers()->Remove(locs->out());
1881 1891
1882 compiler->SaveLiveRegisters(locs); 1892 compiler->SaveLiveRegisters(locs);
1883 compiler->GenerateCall(instruction_->token_pos(), 1893 compiler->GenerateCall(computation_->token_pos(),
1884 &label, 1894 &label,
1885 PcDescriptors::kOther, 1895 PcDescriptors::kOther,
1886 locs); 1896 locs);
1887 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); 1897 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX);
1888 compiler->RestoreLiveRegisters(locs); 1898 compiler->RestoreLiveRegisters(locs);
1889 1899
1890 __ jmp(exit_label()); 1900 __ jmp(exit_label());
1891 } 1901 }
1892 1902
1893 private: 1903 private:
1894 BoxDoubleInstr* instruction_; 1904 BoxDoubleComp* computation_;
1895 }; 1905 };
1896 1906
1897 1907
1898 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1908 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1899 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 1909 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1900 compiler->AddSlowPathCode(slow_path); 1910 compiler->AddSlowPathCode(slow_path);
1901 1911
1902 Register out_reg = locs()->out().reg(); 1912 Register out_reg = locs()->out().reg();
1903 XmmRegister value = locs()->in(0).xmm_reg(); 1913 XmmRegister value = locs()->in(0).xmm_reg();
1904 1914
1905 AssemblerMacros::TryAllocate(compiler->assembler(), 1915 AssemblerMacros::TryAllocate(compiler->assembler(),
1906 compiler->double_class(), 1916 compiler->double_class(),
1907 slow_path->entry_label(), 1917 slow_path->entry_label(),
1908 Assembler::kFarJump, 1918 Assembler::kFarJump,
1909 out_reg); 1919 out_reg);
1910 __ Bind(slow_path->exit_label()); 1920 __ Bind(slow_path->exit_label());
1911 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 1921 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
1912 } 1922 }
1913 1923
1914 1924
1915 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 1925 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const {
1916 const intptr_t v_cid = value()->ResultCid(); 1926 const intptr_t v_cid = value()->ResultCid();
1917 1927
1918 const intptr_t kNumInputs = 1; 1928 const intptr_t kNumInputs = 1;
1919 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; 1929 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0;
1920 LocationSummary* summary = 1930 LocationSummary* summary =
1921 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1931 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1922 summary->set_in(0, Location::RequiresRegister()); 1932 summary->set_in(0, Location::RequiresRegister());
1923 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); 1933 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister());
1924 summary->set_out(Location::RequiresXmmRegister()); 1934 summary->set_out(Location::RequiresXmmRegister());
1925 return summary; 1935 return summary;
1926 } 1936 }
1927 1937
1928 1938
1929 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1939 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1930 const intptr_t v_cid = value()->ResultCid(); 1940 const intptr_t v_cid = value()->ResultCid();
1931 1941
1932 const Register value = locs()->in(0).reg(); 1942 const Register value = locs()->in(0).reg();
1933 const XmmRegister result = locs()->out().xmm_reg(); 1943 const XmmRegister result = locs()->out().xmm_reg();
1934 if (v_cid != kDoubleCid) { 1944 if (v_cid != kDoubleCid) {
1935 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 1945 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
1936 compiler->LoadDoubleOrSmiToXmm(result, 1946 compiler->LoadDoubleOrSmiToXmm(result,
1937 value, 1947 value,
1938 locs()->temp(0).reg(), 1948 locs()->temp(0).reg(),
1939 deopt); 1949 deopt);
1940 } else { 1950 } else {
1941 __ movsd(result, FieldAddress(value, Double::value_offset())); 1951 __ movsd(result, FieldAddress(value, Double::value_offset()));
1942 } 1952 }
1943 } 1953 }
1944 1954
1945 1955
1946 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const { 1956 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const {
1947 const intptr_t kNumInputs = 2; 1957 const intptr_t kNumInputs = 2;
1948 const intptr_t kNumTemps = 0; 1958 const intptr_t kNumTemps = 0;
1949 LocationSummary* summary = 1959 LocationSummary* summary =
1950 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1960 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1951 summary->set_in(0, Location::RequiresXmmRegister()); 1961 summary->set_in(0, Location::RequiresXmmRegister());
1952 summary->set_in(1, Location::RequiresXmmRegister()); 1962 summary->set_in(1, Location::RequiresXmmRegister());
1953 summary->set_out(Location::SameAsFirstInput()); 1963 summary->set_out(Location::SameAsFirstInput());
1954 return summary; 1964 return summary;
1955 } 1965 }
1956 1966
1957 1967
1958 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1968 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1959 XmmRegister left = locs()->in(0).xmm_reg(); 1969 XmmRegister left = locs()->in(0).xmm_reg();
1960 XmmRegister right = locs()->in(1).xmm_reg(); 1970 XmmRegister right = locs()->in(1).xmm_reg();
1961 1971
1962 ASSERT(locs()->out().xmm_reg() == left); 1972 ASSERT(locs()->out().xmm_reg() == left);
1963 1973
1964 switch (op_kind()) { 1974 switch (op_kind()) {
1965 case Token::kADD: __ addsd(left, right); break; 1975 case Token::kADD: __ addsd(left, right); break;
1966 case Token::kSUB: __ subsd(left, right); break; 1976 case Token::kSUB: __ subsd(left, right); break;
1967 case Token::kMUL: __ mulsd(left, right); break; 1977 case Token::kMUL: __ mulsd(left, right); break;
1968 case Token::kDIV: __ divsd(left, right); break; 1978 case Token::kDIV: __ divsd(left, right); break;
1969 default: UNREACHABLE(); 1979 default: UNREACHABLE();
1970 } 1980 }
1971 } 1981 }
1972 1982
1973 1983
1974 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 1984 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const {
1975 const intptr_t kNumInputs = 1; 1985 const intptr_t kNumInputs = 1;
1976 const intptr_t kNumTemps = 0; 1986 const intptr_t kNumTemps = 0;
1977 LocationSummary* summary = 1987 LocationSummary* summary =
1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1979 summary->set_in(0, Location::RequiresRegister()); 1989 summary->set_in(0, Location::RequiresRegister());
1980 summary->set_out(Location::SameAsFirstInput()); 1990 summary->set_out(Location::SameAsFirstInput());
1981 return summary; 1991 return summary;
1982 } 1992 }
1983 1993
1984 1994
1985 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1995 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1986 Register value = locs()->in(0).reg(); 1996 Register value = locs()->in(0).reg();
1987 ASSERT(value == locs()->out().reg()); 1997 ASSERT(value == locs()->out().reg());
1988 switch (op_kind()) { 1998 switch (op_kind()) {
1989 case Token::kNEGATE: { 1999 case Token::kNEGATE: {
1990 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2000 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1991 kDeoptUnaryOp); 2001 kDeoptUnaryOp);
1992 __ negq(value); 2002 __ negq(value);
1993 __ j(OVERFLOW, deopt); 2003 __ j(OVERFLOW, deopt);
1994 break; 2004 break;
1995 } 2005 }
1996 case Token::kBIT_NOT: 2006 case Token::kBIT_NOT:
1997 __ notq(value); 2007 __ notq(value);
1998 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 2008 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
1999 break; 2009 break;
2000 default: 2010 default:
2001 UNREACHABLE(); 2011 UNREACHABLE();
2002 } 2012 }
2003 } 2013 }
2004 2014
2005 2015
2006 LocationSummary* NumberNegateInstr::MakeLocationSummary() const { 2016 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
2007 const intptr_t kNumInputs = 1; 2017 const intptr_t kNumInputs = 1;
2008 const intptr_t kNumTemps = 1; // Needed for doubles. 2018 const intptr_t kNumTemps = 1; // Needed for doubles.
2009 LocationSummary* summary = 2019 LocationSummary* summary =
2010 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2011 summary->set_in(0, Location::RegisterLocation(RAX)); 2021 summary->set_in(0, Location::RegisterLocation(RAX));
2012 summary->set_out(Location::RegisterLocation(RAX)); 2022 summary->set_out(Location::RegisterLocation(RAX));
2013 summary->set_temp(0, Location::RegisterLocation(RCX)); 2023 summary->set_temp(0, Location::RegisterLocation(RCX));
2014 return summary; 2024 return summary;
2015 } 2025 }
2016 2026
2017 2027
2018 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2028 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2019 const ICData& ic_data = *instance_call()->ic_data(); 2029 const ICData& ic_data = *instance_call()->ic_data();
2020 ASSERT(!ic_data.IsNull()); 2030 ASSERT(!ic_data.IsNull());
2021 ASSERT(ic_data.num_args_tested() == 1); 2031 ASSERT(ic_data.num_args_tested() == 1);
2022 2032
2023 // TODO(srdjan): Implement for more checks. 2033 // TODO(srdjan): Implement for more checks.
2024 ASSERT(ic_data.NumberOfChecks() == 1); 2034 ASSERT(ic_data.NumberOfChecks() == 1);
2025 intptr_t test_class_id; 2035 intptr_t test_class_id;
2026 Function& target = Function::Handle(); 2036 Function& target = Function::Handle();
2027 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 2037 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
2028 2038
(...skipping 25 matching lines...) Expand all
2054 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 2064 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
2055 __ DoubleNegate(XMM0); 2065 __ DoubleNegate(XMM0);
2056 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2066 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2057 } else { 2067 } else {
2058 UNREACHABLE(); 2068 UNREACHABLE();
2059 } 2069 }
2060 ASSERT(ResultCid() == kDoubleCid); 2070 ASSERT(ResultCid() == kDoubleCid);
2061 } 2071 }
2062 2072
2063 2073
2064 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 2074 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const {
2065 const intptr_t kNumInputs = 1; 2075 const intptr_t kNumInputs = 1;
2066 const intptr_t kNumTemps = 0; 2076 const intptr_t kNumTemps = 0;
2067 LocationSummary* locs = 2077 LocationSummary* locs =
2068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2069 locs->set_in(0, Location::RequiresRegister()); 2079 locs->set_in(0, Location::RequiresRegister());
2070 locs->set_out(Location::SameAsFirstInput()); 2080 locs->set_out(Location::SameAsFirstInput());
2071 return locs; 2081 return locs;
2072 } 2082 }
2073 2083
2074 2084
2075 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2085 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2076 Register value = locs()->in(0).reg(); 2086 Register value = locs()->in(0).reg();
2077 Register result = locs()->out().reg(); 2087 Register result = locs()->out().reg();
2078 2088
2079 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2089 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2080 kDeoptDoubleToDouble); 2090 kDeoptDoubleToDouble);
2081 2091
2082 __ testq(value, Immediate(kSmiTagMask)); 2092 __ testq(value, Immediate(kSmiTagMask));
2083 __ j(ZERO, deopt); // Deoptimize if Smi. 2093 __ j(ZERO, deopt); // Deoptimize if Smi.
2084 __ CompareClassId(value, kDoubleCid); 2094 __ CompareClassId(value, kDoubleCid);
2085 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 2095 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
2086 ASSERT(value == result); 2096 ASSERT(value == result);
2087 } 2097 }
2088 2098
2089 2099
2090 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { 2100 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const {
2091 return MakeCallSummary(); // Calls a stub to allocate result. 2101 return MakeCallSummary(); // Calls a stub to allocate result.
2092 } 2102 }
2093 2103
2094 2104
2095 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2105 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2096 Register result = locs()->out().reg(); 2106 Register result = locs()->out().reg();
2097 2107
2098 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2108 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2099 kDeoptIntegerToDouble); 2109 kDeoptIntegerToDouble);
2100 2110
2101 const Class& double_class = compiler->double_class(); 2111 const Class& double_class = compiler->double_class();
2102 const Code& stub = 2112 const Code& stub =
2103 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2113 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2104 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2114 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2105 2115
(...skipping 10 matching lines...) Expand all
2116 2126
2117 __ testq(value, Immediate(kSmiTagMask)); 2127 __ testq(value, Immediate(kSmiTagMask));
2118 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 2128 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
2119 __ SmiUntag(value); 2129 __ SmiUntag(value);
2120 __ cvtsi2sd(XMM0, value); 2130 __ cvtsi2sd(XMM0, value);
2121 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2131 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2122 __ Drop(1); 2132 __ Drop(1);
2123 } 2133 }
2124 2134
2125 2135
2126 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 2136 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
2127 return MakeCallSummary(); 2137 return MakeCallSummary();
2128 } 2138 }
2129 2139
2130 2140
2131 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2141 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2132 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2142 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2133 kDeoptPolymorphicInstanceCallTestFail); 2143 kDeoptPolymorphicInstanceCallTestFail);
2134 if (ic_data().NumberOfChecks() == 0) { 2144 if (ic_data().NumberOfChecks() == 0) {
2135 __ jmp(deopt); 2145 __ jmp(deopt);
2136 return; 2146 return;
2137 } 2147 }
2138 ASSERT(ic_data().num_args_tested() == 1); 2148 ASSERT(ic_data().num_args_tested() == 1);
2139 if (!with_checks()) { 2149 if (!with_checks()) {
2140 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); 2150 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
2141 compiler->GenerateStaticCall(instance_call()->deopt_id(), 2151 compiler->GenerateStaticCall(instance_call()->deopt_id(),
(...skipping 18 matching lines...) Expand all
2160 RDI, // Class id register. 2170 RDI, // Class id register.
2161 instance_call()->ArgumentCount(), 2171 instance_call()->ArgumentCount(),
2162 instance_call()->argument_names(), 2172 instance_call()->argument_names(),
2163 deopt, 2173 deopt,
2164 instance_call()->deopt_id(), 2174 instance_call()->deopt_id(),
2165 instance_call()->token_pos(), 2175 instance_call()->token_pos(),
2166 locs()); 2176 locs());
2167 } 2177 }
2168 2178
2169 2179
2170 LocationSummary* BranchInstr::MakeLocationSummary() const {
2171 UNREACHABLE();
2172 return NULL;
2173 }
2174
2175
2176 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2180 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2177 comparison()->EmitBranchCode(compiler, this); 2181 computation()->EmitBranchCode(compiler, this);
2178 } 2182 }
2179 2183
2180 2184
2181 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 2185 LocationSummary* CheckClassComp::MakeLocationSummary() const {
2182 const intptr_t kNumInputs = 1; 2186 const intptr_t kNumInputs = 1;
2183 const intptr_t kNumTemps = 1; 2187 const intptr_t kNumTemps = 1;
2184 LocationSummary* summary = 2188 LocationSummary* summary =
2185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2186 summary->set_in(0, Location::RequiresRegister()); 2190 summary->set_in(0, Location::RequiresRegister());
2187 summary->set_temp(0, Location::RequiresRegister()); 2191 summary->set_temp(0, Location::RequiresRegister());
2188 return summary; 2192 return summary;
2189 } 2193 }
2190 2194
2191 2195
2192 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2196 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2193 Register value = locs()->in(0).reg(); 2197 Register value = locs()->in(0).reg();
2194 Register temp = locs()->temp(0).reg(); 2198 Register temp = locs()->temp(0).reg();
2195 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2199 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2196 kDeoptCheckClass); 2200 kDeoptCheckClass);
2197 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); 2201 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid);
2198 __ testq(value, Immediate(kSmiTagMask)); 2202 __ testq(value, Immediate(kSmiTagMask));
2199 __ j(ZERO, deopt); 2203 __ j(ZERO, deopt);
2200 __ LoadClassId(temp, value); 2204 __ LoadClassId(temp, value);
2201 Label is_ok; 2205 Label is_ok;
2202 const intptr_t num_checks = unary_checks().NumberOfChecks(); 2206 const intptr_t num_checks = unary_checks().NumberOfChecks();
2203 const bool use_near_jump = num_checks < 5; 2207 const bool use_near_jump = num_checks < 5;
2204 for (intptr_t i = 0; i < num_checks; i++) { 2208 for (intptr_t i = 0; i < num_checks; i++) {
2205 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); 2209 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i)));
2206 if (i == (num_checks - 1)) { 2210 if (i == (num_checks - 1)) {
2207 __ j(NOT_EQUAL, deopt); 2211 __ j(NOT_EQUAL, deopt);
2208 } else { 2212 } else {
2209 if (use_near_jump) { 2213 if (use_near_jump) {
2210 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2214 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2211 } else { 2215 } else {
2212 __ j(EQUAL, &is_ok); 2216 __ j(EQUAL, &is_ok);
2213 } 2217 }
2214 } 2218 }
2215 } 2219 }
2216 __ Bind(&is_ok); 2220 __ Bind(&is_ok);
2217 } 2221 }
2218 2222
2219 2223
2220 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { 2224 LocationSummary* CheckSmiComp::MakeLocationSummary() const {
2221 const intptr_t kNumInputs = 1; 2225 const intptr_t kNumInputs = 1;
2222 const intptr_t kNumTemps = 0; 2226 const intptr_t kNumTemps = 0;
2223 LocationSummary* summary = 2227 LocationSummary* summary =
2224 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2225 summary->set_in(0, Location::RequiresRegister()); 2229 summary->set_in(0, Location::RequiresRegister());
2226 return summary; 2230 return summary;
2227 } 2231 }
2228 2232
2229 2233
2230 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2234 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2231 Register value = locs()->in(0).reg(); 2235 Register value = locs()->in(0).reg();
2232 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2236 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2233 kDeoptCheckSmi); 2237 kDeoptCheckSmi);
2234 __ testq(value, Immediate(kSmiTagMask)); 2238 __ testq(value, Immediate(kSmiTagMask));
2235 __ j(NOT_ZERO, deopt); 2239 __ j(NOT_ZERO, deopt);
2236 } 2240 }
2237 2241
2238 2242
2239 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 2243 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const {
2240 const intptr_t kNumInputs = 2; 2244 const intptr_t kNumInputs = 2;
2241 const intptr_t kNumTemps = 0; 2245 const intptr_t kNumTemps = 0;
2242 LocationSummary* locs = 2246 LocationSummary* locs =
2243 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2244 locs->set_in(0, Location::RequiresRegister()); 2248 locs->set_in(0, Location::RequiresRegister());
2245 locs->set_in(1, Location::RegisterOrConstant(index())); 2249 locs->set_in(1, Location::RegisterOrConstant(index()));
2246 return locs; 2250 return locs;
2247 } 2251 }
2248 2252
2249 2253
2250 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2254 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2251 Register receiver = locs()->in(0).reg(); 2255 Register receiver = locs()->in(0).reg();
2252 2256
2253 const DeoptReasonId deopt_reason = 2257 const DeoptReasonId deopt_reason =
2254 (array_type() == kGrowableObjectArrayCid) ? 2258 (array_type() == kGrowableObjectArrayCid) ?
2255 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 2259 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
2256 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2260 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2257 deopt_reason); 2261 deopt_reason);
2258 ASSERT(array_type() == kArrayCid || 2262 ASSERT(array_type() == kArrayCid ||
2259 array_type() == kImmutableArrayCid || 2263 array_type() == kImmutableArrayCid ||
2260 array_type() == kGrowableObjectArrayCid); 2264 array_type() == kGrowableObjectArrayCid);
(...skipping 14 matching lines...) Expand all
2275 __ j(ABOVE_EQUAL, deopt); 2279 __ j(ABOVE_EQUAL, deopt);
2276 } 2280 }
2277 } 2281 }
2278 2282
2279 2283
2280 } // namespace dart 2284 } // namespace dart
2281 2285
2282 #undef __ 2286 #undef __
2283 2287
2284 #endif // defined TARGET_ARCH_X64 2288 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_test.cc ('k') | runtime/vm/locations.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698