OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |