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

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

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

Powered by Google App Engine
This is Rietveld 408576698