OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 // Generic summary for call instructions that have all arguments pushed | 28 // Generic summary for call instructions that have all arguments pushed |
29 // on the stack and return the result in a fixed register V0. | 29 // on the stack and return the result in a fixed register V0. |
30 LocationSummary* Instruction::MakeCallSummary() { | 30 LocationSummary* Instruction::MakeCallSummary() { |
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
32 result->set_out(Location::RegisterLocation(V0)); | 32 result->set_out(Location::RegisterLocation(V0)); |
33 return result; | 33 return result; |
34 } | 34 } |
35 | 35 |
36 | 36 |
37 LocationSummary* PushArgumentInstr::MakeLocationSummary() const { | 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { |
38 const intptr_t kNumInputs = 1; | 38 const intptr_t kNumInputs = 1; |
39 const intptr_t kNumTemps= 0; | 39 const intptr_t kNumTemps= 0; |
40 LocationSummary* locs = | 40 LocationSummary* locs = |
41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
42 locs->set_in(0, Location::AnyOrConstant(value())); | 42 locs->set_in(0, Location::AnyOrConstant(value())); |
43 return locs; | 43 return locs; |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 47 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode | 48 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode |
49 // where PushArgument is handled by BindInstr::EmitNativeCode. | 49 // where PushArgument is handled by BindInstr::EmitNativeCode. |
50 __ TraceSimMsg("PushArgumentInstr"); | 50 __ TraceSimMsg("PushArgumentInstr"); |
51 if (compiler->is_optimizing()) { | 51 if (compiler->is_optimizing()) { |
52 Location value = locs()->in(0); | 52 Location value = locs()->in(0); |
53 if (value.IsRegister()) { | 53 if (value.IsRegister()) { |
54 __ Push(value.reg()); | 54 __ Push(value.reg()); |
55 } else if (value.IsConstant()) { | 55 } else if (value.IsConstant()) { |
56 __ PushObject(value.constant()); | 56 __ PushObject(value.constant()); |
57 } else { | 57 } else { |
58 ASSERT(value.IsStackSlot()); | 58 ASSERT(value.IsStackSlot()); |
59 const intptr_t value_offset = value.ToStackSlotOffset(); | 59 const intptr_t value_offset = value.ToStackSlotOffset(); |
60 __ LoadFromOffset(TMP, FP, value_offset); | 60 __ LoadFromOffset(TMP, FP, value_offset); |
61 __ Push(TMP); | 61 __ Push(TMP); |
62 } | 62 } |
63 } | 63 } |
64 } | 64 } |
65 | 65 |
66 | 66 |
67 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 67 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { |
68 const intptr_t kNumInputs = 1; | 68 const intptr_t kNumInputs = 1; |
69 const intptr_t kNumTemps = 0; | 69 const intptr_t kNumTemps = 0; |
70 LocationSummary* locs = | 70 LocationSummary* locs = |
71 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 71 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
72 locs->set_in(0, Location::RegisterLocation(V0)); | 72 locs->set_in(0, Location::RegisterLocation(V0)); |
73 return locs; | 73 return locs; |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 // Attempt optimized compilation at return instruction instead of at the entry. | 77 // Attempt optimized compilation at return instruction instead of at the entry. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 // Detect pattern when one value is zero and another is a power of 2. | 130 // Detect pattern when one value is zero and another is a power of 2. |
131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 131 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 132 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 133 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 137 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { |
138 return comparison()->MakeLocationSummary(); | 138 comparison()->InitializeLocationSummary(opt); |
| 139 return comparison()->locs(); |
139 } | 140 } |
140 | 141 |
141 | 142 |
142 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 143 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
143 const Register result = locs()->out().reg(); | 144 const Register result = locs()->out().reg(); |
144 | 145 |
145 Location left = locs()->in(0); | 146 Location left = locs()->in(0); |
146 Location right = locs()->in(1); | 147 Location right = locs()->in(1); |
147 ASSERT(!left.IsConstant() || !right.IsConstant()); | 148 ASSERT(!left.IsConstant() || !right.IsConstant()); |
148 | 149 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 const int32_t val = | 209 const int32_t val = |
209 Smi::RawValue(true_value) - Smi::RawValue(false_value); | 210 Smi::RawValue(true_value) - Smi::RawValue(false_value); |
210 __ AndImmediate(result, result, val); | 211 __ AndImmediate(result, result, val); |
211 if (false_value != 0) { | 212 if (false_value != 0) { |
212 __ AddImmediate(result, result, Smi::RawValue(false_value)); | 213 __ AddImmediate(result, result, Smi::RawValue(false_value)); |
213 } | 214 } |
214 } | 215 } |
215 } | 216 } |
216 | 217 |
217 | 218 |
218 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 219 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
219 const intptr_t kNumInputs = 0; | 220 const intptr_t kNumInputs = 0; |
220 const intptr_t kNumTemps = 1; | 221 const intptr_t kNumTemps = 1; |
221 LocationSummary* result = | 222 LocationSummary* result = |
222 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
223 result->set_out(Location::RegisterLocation(V0)); | 224 result->set_out(Location::RegisterLocation(V0)); |
224 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor. | 225 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor. |
225 return result; | 226 return result; |
226 } | 227 } |
227 | 228 |
228 | 229 |
229 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 230 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
230 // The arguments to the stub include the closure, as does the arguments | 231 // The arguments to the stub include the closure, as does the arguments |
231 // descriptor. | 232 // descriptor. |
232 Register temp_reg = locs()->temp(0).reg(); | 233 Register temp_reg = locs()->temp(0).reg(); |
233 int argument_count = ArgumentCount(); | 234 int argument_count = ArgumentCount(); |
234 const Array& arguments_descriptor = | 235 const Array& arguments_descriptor = |
235 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 236 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
236 argument_names())); | 237 argument_names())); |
237 ASSERT(temp_reg == S4); | 238 ASSERT(temp_reg == S4); |
238 __ LoadObject(temp_reg, arguments_descriptor); | 239 __ LoadObject(temp_reg, arguments_descriptor); |
239 compiler->GenerateDartCall(deopt_id(), | 240 compiler->GenerateDartCall(deopt_id(), |
240 token_pos(), | 241 token_pos(), |
241 &StubCode::CallClosureFunctionLabel(), | 242 &StubCode::CallClosureFunctionLabel(), |
242 PcDescriptors::kClosureCall, | 243 PcDescriptors::kClosureCall, |
243 locs()); | 244 locs()); |
244 __ Drop(argument_count); | 245 __ Drop(argument_count); |
245 } | 246 } |
246 | 247 |
247 | 248 |
248 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 249 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
249 return LocationSummary::Make(0, | 250 return LocationSummary::Make(0, |
250 Location::RequiresRegister(), | 251 Location::RequiresRegister(), |
251 LocationSummary::kNoCall); | 252 LocationSummary::kNoCall); |
252 } | 253 } |
253 | 254 |
254 | 255 |
255 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 256 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
256 __ TraceSimMsg("LoadLocalInstr"); | 257 __ TraceSimMsg("LoadLocalInstr"); |
257 Register result = locs()->out().reg(); | 258 Register result = locs()->out().reg(); |
258 __ lw(result, Address(FP, local().index() * kWordSize)); | 259 __ lw(result, Address(FP, local().index() * kWordSize)); |
259 } | 260 } |
260 | 261 |
261 | 262 |
262 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 263 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
263 return LocationSummary::Make(1, | 264 return LocationSummary::Make(1, |
264 Location::SameAsFirstInput(), | 265 Location::SameAsFirstInput(), |
265 LocationSummary::kNoCall); | 266 LocationSummary::kNoCall); |
266 } | 267 } |
267 | 268 |
268 | 269 |
269 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 270 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
270 __ TraceSimMsg("StoreLocalInstr"); | 271 __ TraceSimMsg("StoreLocalInstr"); |
271 Register value = locs()->in(0).reg(); | 272 Register value = locs()->in(0).reg(); |
272 Register result = locs()->out().reg(); | 273 Register result = locs()->out().reg(); |
273 ASSERT(result == value); // Assert that register assignment is correct. | 274 ASSERT(result == value); // Assert that register assignment is correct. |
274 __ sw(value, Address(FP, local().index() * kWordSize)); | 275 __ sw(value, Address(FP, local().index() * kWordSize)); |
275 } | 276 } |
276 | 277 |
277 | 278 |
278 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 279 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
279 return LocationSummary::Make(0, | 280 return LocationSummary::Make(0, |
280 Location::RequiresRegister(), | 281 Location::RequiresRegister(), |
281 LocationSummary::kNoCall); | 282 LocationSummary::kNoCall); |
282 } | 283 } |
283 | 284 |
284 | 285 |
285 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 286 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
286 // The register allocator drops constant definitions that have no uses. | 287 // The register allocator drops constant definitions that have no uses. |
287 if (!locs()->out().IsInvalid()) { | 288 if (!locs()->out().IsInvalid()) { |
288 __ TraceSimMsg("ConstantInstr"); | 289 __ TraceSimMsg("ConstantInstr"); |
289 Register result = locs()->out().reg(); | 290 Register result = locs()->out().reg(); |
290 __ LoadObject(result, value()); | 291 __ LoadObject(result, value()); |
291 } | 292 } |
292 } | 293 } |
293 | 294 |
294 | 295 |
295 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 296 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { |
296 const intptr_t kNumInputs = 3; | 297 const intptr_t kNumInputs = 3; |
297 const intptr_t kNumTemps = 0; | 298 const intptr_t kNumTemps = 0; |
298 LocationSummary* summary = | 299 LocationSummary* summary = |
299 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 300 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
300 summary->set_in(0, Location::RegisterLocation(A0)); // Value. | 301 summary->set_in(0, Location::RegisterLocation(A0)); // Value. |
301 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator. | 302 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator. |
302 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments. | 303 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments. |
303 summary->set_out(Location::RegisterLocation(A0)); | 304 summary->set_out(Location::RegisterLocation(A0)); |
304 return summary; | 305 return summary; |
305 } | 306 } |
306 | 307 |
307 | 308 |
308 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 309 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { |
309 const intptr_t kNumInputs = 1; | 310 const intptr_t kNumInputs = 1; |
310 const intptr_t kNumTemps = 0; | 311 const intptr_t kNumTemps = 0; |
311 LocationSummary* locs = | 312 LocationSummary* locs = |
312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 313 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
313 locs->set_in(0, Location::RegisterLocation(A0)); | 314 locs->set_in(0, Location::RegisterLocation(A0)); |
314 locs->set_out(Location::RegisterLocation(A0)); | 315 locs->set_out(Location::RegisterLocation(A0)); |
315 return locs; | 316 return locs; |
316 } | 317 } |
317 | 318 |
318 | 319 |
(...skipping 24 matching lines...) Expand all Loading... |
343 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 344 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
344 Register obj = locs()->in(0).reg(); | 345 Register obj = locs()->in(0).reg(); |
345 Register result = locs()->out().reg(); | 346 Register result = locs()->out().reg(); |
346 | 347 |
347 __ TraceSimMsg("AssertBooleanInstr"); | 348 __ TraceSimMsg("AssertBooleanInstr"); |
348 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); | 349 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); |
349 ASSERT(obj == result); | 350 ASSERT(obj == result); |
350 } | 351 } |
351 | 352 |
352 | 353 |
353 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 354 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
354 const intptr_t kNumInputs = 2; | 355 const intptr_t kNumInputs = 2; |
355 if (operation_cid() == kMintCid) { | 356 if (operation_cid() == kMintCid) { |
356 const intptr_t kNumTemps = 1; | 357 const intptr_t kNumTemps = 1; |
357 LocationSummary* locs = | 358 LocationSummary* locs = |
358 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 359 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
359 locs->set_in(0, Location::RequiresFpuRegister()); | 360 locs->set_in(0, Location::RequiresFpuRegister()); |
360 locs->set_in(1, Location::RequiresFpuRegister()); | 361 locs->set_in(1, Location::RequiresFpuRegister()); |
361 locs->set_temp(0, Location::RequiresRegister()); | 362 locs->set_temp(0, Location::RequiresRegister()); |
362 locs->set_out(Location::RequiresRegister()); | 363 locs->set_out(Location::RequiresRegister()); |
363 return locs; | 364 return locs; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 __ TraceSimMsg("EqualityCompareInstr"); | 596 __ TraceSimMsg("EqualityCompareInstr"); |
596 __ Comment("EqualityCompareInstr:BranchCode"); | 597 __ Comment("EqualityCompareInstr:BranchCode"); |
597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 598 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
598 | 599 |
599 BranchLabels labels = compiler->CreateBranchLabels(branch); | 600 BranchLabels labels = compiler->CreateBranchLabels(branch); |
600 Condition true_condition = EmitComparisonCode(compiler, labels); | 601 Condition true_condition = EmitComparisonCode(compiler, labels); |
601 EmitBranchOnCondition(compiler, true_condition, labels); | 602 EmitBranchOnCondition(compiler, true_condition, labels); |
602 } | 603 } |
603 | 604 |
604 | 605 |
605 LocationSummary* TestSmiInstr::MakeLocationSummary() const { | 606 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const { |
606 const intptr_t kNumInputs = 2; | 607 const intptr_t kNumInputs = 2; |
607 const intptr_t kNumTemps = 0; | 608 const intptr_t kNumTemps = 0; |
608 LocationSummary* locs = | 609 LocationSummary* locs = |
609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
610 locs->set_in(0, Location::RequiresRegister()); | 611 locs->set_in(0, Location::RequiresRegister()); |
611 // Only one input can be a constant operand. The case of two constant | 612 // Only one input can be a constant operand. The case of two constant |
612 // operands should be handled by constant propagation. | 613 // operands should be handled by constant propagation. |
613 locs->set_in(1, Location::RegisterOrConstant(right())); | 614 locs->set_in(1, Location::RegisterOrConstant(right())); |
614 return locs; | 615 return locs; |
615 } | 616 } |
(...skipping 24 matching lines...) Expand all Loading... |
640 | 641 |
641 | 642 |
642 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 643 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
643 BranchInstr* branch) { | 644 BranchInstr* branch) { |
644 BranchLabels labels = compiler->CreateBranchLabels(branch); | 645 BranchLabels labels = compiler->CreateBranchLabels(branch); |
645 Condition true_condition = EmitComparisonCode(compiler, labels); | 646 Condition true_condition = EmitComparisonCode(compiler, labels); |
646 EmitBranchOnCondition(compiler, true_condition, labels); | 647 EmitBranchOnCondition(compiler, true_condition, labels); |
647 } | 648 } |
648 | 649 |
649 | 650 |
650 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 651 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
651 const intptr_t kNumInputs = 2; | 652 const intptr_t kNumInputs = 2; |
652 const intptr_t kNumTemps = 0; | 653 const intptr_t kNumTemps = 0; |
653 if (operation_cid() == kMintCid) { | 654 if (operation_cid() == kMintCid) { |
654 const intptr_t kNumTemps = 2; | 655 const intptr_t kNumTemps = 2; |
655 LocationSummary* locs = | 656 LocationSummary* locs = |
656 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
657 locs->set_in(0, Location::RequiresFpuRegister()); | 658 locs->set_in(0, Location::RequiresFpuRegister()); |
658 locs->set_in(1, Location::RequiresFpuRegister()); | 659 locs->set_in(1, Location::RequiresFpuRegister()); |
659 locs->set_temp(0, Location::RequiresRegister()); | 660 locs->set_temp(0, Location::RequiresRegister()); |
660 locs->set_temp(1, Location::RequiresRegister()); | 661 locs->set_temp(1, Location::RequiresRegister()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 717 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
717 BranchInstr* branch) { | 718 BranchInstr* branch) { |
718 __ TraceSimMsg("RelationalOpInstr"); | 719 __ TraceSimMsg("RelationalOpInstr"); |
719 | 720 |
720 BranchLabels labels = compiler->CreateBranchLabels(branch); | 721 BranchLabels labels = compiler->CreateBranchLabels(branch); |
721 Condition true_condition = EmitComparisonCode(compiler, labels); | 722 Condition true_condition = EmitComparisonCode(compiler, labels); |
722 EmitBranchOnCondition(compiler, true_condition, labels); | 723 EmitBranchOnCondition(compiler, true_condition, labels); |
723 } | 724 } |
724 | 725 |
725 | 726 |
726 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 727 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
727 const intptr_t kNumInputs = 0; | 728 const intptr_t kNumInputs = 0; |
728 const intptr_t kNumTemps = 3; | 729 const intptr_t kNumTemps = 3; |
729 LocationSummary* locs = | 730 LocationSummary* locs = |
730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 731 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
731 locs->set_temp(0, Location::RegisterLocation(A1)); | 732 locs->set_temp(0, Location::RegisterLocation(A1)); |
732 locs->set_temp(1, Location::RegisterLocation(A2)); | 733 locs->set_temp(1, Location::RegisterLocation(A2)); |
733 locs->set_temp(2, Location::RegisterLocation(T5)); | 734 locs->set_temp(2, Location::RegisterLocation(T5)); |
734 locs->set_out(Location::RegisterLocation(V0)); | 735 locs->set_out(Location::RegisterLocation(V0)); |
735 return locs; | 736 return locs; |
736 } | 737 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 __ LoadImmediate(T5, entry); | 773 __ LoadImmediate(T5, entry); |
773 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function())); | 774 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function())); |
774 compiler->GenerateCall(token_pos(), | 775 compiler->GenerateCall(token_pos(), |
775 stub_entry, | 776 stub_entry, |
776 PcDescriptors::kOther, | 777 PcDescriptors::kOther, |
777 locs()); | 778 locs()); |
778 __ Pop(result); | 779 __ Pop(result); |
779 } | 780 } |
780 | 781 |
781 | 782 |
782 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 783 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { |
783 const intptr_t kNumInputs = 1; | 784 const intptr_t kNumInputs = 1; |
784 // TODO(fschneider): Allow immediate operands for the char code. | 785 // TODO(fschneider): Allow immediate operands for the char code. |
785 return LocationSummary::Make(kNumInputs, | 786 return LocationSummary::Make(kNumInputs, |
786 Location::RequiresRegister(), | 787 Location::RequiresRegister(), |
787 LocationSummary::kNoCall); | 788 LocationSummary::kNoCall); |
788 } | 789 } |
789 | 790 |
790 | 791 |
791 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 792 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
792 Register char_code = locs()->in(0).reg(); | 793 Register char_code = locs()->in(0).reg(); |
793 Register result = locs()->out().reg(); | 794 Register result = locs()->out().reg(); |
794 | 795 |
795 __ TraceSimMsg("StringFromCharCodeInstr"); | 796 __ TraceSimMsg("StringFromCharCodeInstr"); |
796 | 797 |
797 __ LoadImmediate(result, | 798 __ LoadImmediate(result, |
798 reinterpret_cast<uword>(Symbols::PredefinedAddress())); | 799 reinterpret_cast<uword>(Symbols::PredefinedAddress())); |
799 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); | 800 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
800 __ sll(TMP, char_code, 1); // Char code is a smi. | 801 __ sll(TMP, char_code, 1); // Char code is a smi. |
801 __ addu(TMP, TMP, result); | 802 __ addu(TMP, TMP, result); |
802 __ lw(result, Address(TMP)); | 803 __ lw(result, Address(TMP)); |
803 } | 804 } |
804 | 805 |
805 | 806 |
806 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { | 807 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { |
807 const intptr_t kNumInputs = 1; | 808 const intptr_t kNumInputs = 1; |
808 const intptr_t kNumTemps = 0; | 809 const intptr_t kNumTemps = 0; |
809 LocationSummary* summary = | 810 LocationSummary* summary = |
810 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 811 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
811 summary->set_in(0, Location::RegisterLocation(A0)); | 812 summary->set_in(0, Location::RegisterLocation(A0)); |
812 summary->set_out(Location::RegisterLocation(V0)); | 813 summary->set_out(Location::RegisterLocation(V0)); |
813 return summary; | 814 return summary; |
814 } | 815 } |
815 | 816 |
816 | 817 |
817 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 818 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
818 Register array = locs()->in(0).reg(); | 819 Register array = locs()->in(0).reg(); |
819 __ Push(array); | 820 __ Push(array); |
820 const int kNumberOfArguments = 1; | 821 const int kNumberOfArguments = 1; |
821 const Array& kNoArgumentNames = Object::null_array(); | 822 const Array& kNoArgumentNames = Object::null_array(); |
822 compiler->GenerateStaticCall(deopt_id(), | 823 compiler->GenerateStaticCall(deopt_id(), |
823 token_pos(), | 824 token_pos(), |
824 CallFunction(), | 825 CallFunction(), |
825 kNumberOfArguments, | 826 kNumberOfArguments, |
826 kNoArgumentNames, | 827 kNoArgumentNames, |
827 locs()); | 828 locs()); |
828 ASSERT(locs()->out().reg() == V0); | 829 ASSERT(locs()->out().reg() == V0); |
829 } | 830 } |
830 | 831 |
831 | 832 |
832 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 833 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
833 const intptr_t kNumInputs = 1; | 834 const intptr_t kNumInputs = 1; |
834 return LocationSummary::Make(kNumInputs, | 835 return LocationSummary::Make(kNumInputs, |
835 Location::RequiresRegister(), | 836 Location::RequiresRegister(), |
836 LocationSummary::kNoCall); | 837 LocationSummary::kNoCall); |
837 } | 838 } |
838 | 839 |
839 | 840 |
840 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 841 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
841 Register object = locs()->in(0).reg(); | 842 Register object = locs()->in(0).reg(); |
842 Register result = locs()->out().reg(); | 843 Register result = locs()->out().reg(); |
843 __ LoadFromOffset(result, object, offset() - kHeapObjectTag); | 844 __ LoadFromOffset(result, object, offset() - kHeapObjectTag); |
844 } | 845 } |
845 | 846 |
846 | 847 |
847 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { | 848 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { |
848 const intptr_t kNumInputs = 1; | 849 const intptr_t kNumInputs = 1; |
849 return LocationSummary::Make(kNumInputs, | 850 return LocationSummary::Make(kNumInputs, |
850 Location::RequiresRegister(), | 851 Location::RequiresRegister(), |
851 LocationSummary::kNoCall); | 852 LocationSummary::kNoCall); |
852 } | 853 } |
853 | 854 |
854 | 855 |
855 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 856 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
856 Register object = locs()->in(0).reg(); | 857 Register object = locs()->in(0).reg(); |
857 Register result = locs()->out().reg(); | 858 Register result = locs()->out().reg(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 return kUnboxedInt32x4; | 934 return kUnboxedInt32x4; |
934 case kTypedDataFloat32x4ArrayCid: | 935 case kTypedDataFloat32x4ArrayCid: |
935 return kUnboxedFloat32x4; | 936 return kUnboxedFloat32x4; |
936 default: | 937 default: |
937 UNIMPLEMENTED(); | 938 UNIMPLEMENTED(); |
938 return kTagged; | 939 return kTagged; |
939 } | 940 } |
940 } | 941 } |
941 | 942 |
942 | 943 |
943 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 944 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
944 const intptr_t kNumInputs = 2; | 945 const intptr_t kNumInputs = 2; |
945 const intptr_t kNumTemps = 0; | 946 const intptr_t kNumTemps = 0; |
946 LocationSummary* locs = | 947 LocationSummary* locs = |
947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 948 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
948 locs->set_in(0, Location::RequiresRegister()); | 949 locs->set_in(0, Location::RequiresRegister()); |
949 // The smi index is either untagged (element size == 1), or it is left smi | 950 // The smi index is either untagged (element size == 1), or it is left smi |
950 // tagged (for all element sizes > 1). | 951 // tagged (for all element sizes > 1). |
951 // TODO(regis): Revisit and see if the index can be immediate. | 952 // TODO(regis): Revisit and see if the index can be immediate. |
952 locs->set_in(1, Location::WritableRegister()); | 953 locs->set_in(1, Location::WritableRegister()); |
953 if ((representation() == kUnboxedDouble) || | 954 if ((representation() == kUnboxedDouble) || |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 return kUnboxedFloat32x4; | 1117 return kUnboxedFloat32x4; |
1117 case kTypedDataInt32x4ArrayCid: | 1118 case kTypedDataInt32x4ArrayCid: |
1118 return kUnboxedInt32x4; | 1119 return kUnboxedInt32x4; |
1119 default: | 1120 default: |
1120 UNIMPLEMENTED(); | 1121 UNIMPLEMENTED(); |
1121 return kTagged; | 1122 return kTagged; |
1122 } | 1123 } |
1123 } | 1124 } |
1124 | 1125 |
1125 | 1126 |
1126 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1127 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
1127 const intptr_t kNumInputs = 3; | 1128 const intptr_t kNumInputs = 3; |
1128 const intptr_t kNumTemps = 0; | 1129 const intptr_t kNumTemps = 0; |
1129 LocationSummary* locs = | 1130 LocationSummary* locs = |
1130 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1131 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1131 locs->set_in(0, Location::RequiresRegister()); | 1132 locs->set_in(0, Location::RequiresRegister()); |
1132 // The smi index is either untagged (element size == 1), or it is left smi | 1133 // The smi index is either untagged (element size == 1), or it is left smi |
1133 // tagged (for all element sizes > 1). | 1134 // tagged (for all element sizes > 1). |
1134 // TODO(regis): Revisit and see if the index can be immediate. | 1135 // TODO(regis): Revisit and see if the index can be immediate. |
1135 locs->set_in(1, Location::WritableRegister()); | 1136 locs->set_in(1, Location::WritableRegister()); |
1136 switch (class_id()) { | 1137 switch (class_id()) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 case kTypedDataInt32x4ArrayCid: | 1301 case kTypedDataInt32x4ArrayCid: |
1301 case kTypedDataFloat32x4ArrayCid: | 1302 case kTypedDataFloat32x4ArrayCid: |
1302 UNIMPLEMENTED(); | 1303 UNIMPLEMENTED(); |
1303 break; | 1304 break; |
1304 default: | 1305 default: |
1305 UNREACHABLE(); | 1306 UNREACHABLE(); |
1306 } | 1307 } |
1307 } | 1308 } |
1308 | 1309 |
1309 | 1310 |
1310 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1311 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
1311 const intptr_t kNumInputs = 1; | 1312 const intptr_t kNumInputs = 1; |
1312 LocationSummary* summary = | 1313 LocationSummary* summary = |
1313 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1314 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
1314 summary->set_in(0, Location::RequiresRegister()); | 1315 summary->set_in(0, Location::RequiresRegister()); |
1315 const bool field_has_length = field().needs_length_check(); | 1316 const bool field_has_length = field().needs_length_check(); |
1316 const bool need_value_temp_reg = | 1317 const bool need_value_temp_reg = |
1317 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && | 1318 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && |
1318 (field().guarded_cid() != kSmiCid))); | 1319 (field().guarded_cid() != kSmiCid))); |
1319 if (need_value_temp_reg) { | 1320 if (need_value_temp_reg) { |
1320 summary->AddTemp(Location::RequiresRegister()); | 1321 summary->AddTemp(Location::RequiresRegister()); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 __ bne(CMPRES1, ZR, fail); | 1634 __ bne(CMPRES1, ZR, fail); |
1634 } else { | 1635 } else { |
1635 UNREACHABLE(); | 1636 UNREACHABLE(); |
1636 } | 1637 } |
1637 } | 1638 } |
1638 } | 1639 } |
1639 __ Bind(&ok); | 1640 __ Bind(&ok); |
1640 } | 1641 } |
1641 | 1642 |
1642 | 1643 |
1643 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1644 class StoreInstanceFieldSlowPath : public SlowPathCode { |
| 1645 public: |
| 1646 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) |
| 1647 : instruction_(instruction) { } |
| 1648 |
| 1649 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1650 __ Comment("StoreInstanceFieldSlowPath"); |
| 1651 __ Bind(entry_label()); |
| 1652 const Class& double_class = compiler->double_class(); |
| 1653 const Code& stub = |
| 1654 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1655 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1656 |
| 1657 LocationSummary* locs = instruction_->locs(); |
| 1658 locs->live_registers()->Remove(locs->out()); |
| 1659 |
| 1660 compiler->SaveLiveRegisters(locs); |
| 1661 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1662 &label, |
| 1663 PcDescriptors::kOther, |
| 1664 locs); |
| 1665 __ mov(locs->temp(0).reg(), V0); |
| 1666 compiler->RestoreLiveRegisters(locs); |
| 1667 |
| 1668 __ b(exit_label()); |
| 1669 } |
| 1670 |
| 1671 private: |
| 1672 StoreInstanceFieldInstr* instruction_; |
| 1673 }; |
| 1674 |
| 1675 |
| 1676 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { |
1644 const intptr_t kNumInputs = 2; | 1677 const intptr_t kNumInputs = 2; |
1645 const intptr_t kNumTemps = 0; | 1678 const intptr_t kNumTemps = 0; |
1646 LocationSummary* summary = | 1679 LocationSummary* summary = |
1647 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1680 new LocationSummary(kNumInputs, kNumTemps, |
| 1681 (field().guarded_cid() == kIllegalCid) || (is_initialization_) |
| 1682 ? LocationSummary::kCallOnSlowPath |
| 1683 : LocationSummary::kNoCall); |
| 1684 |
1648 summary->set_in(0, Location::RequiresRegister()); | 1685 summary->set_in(0, Location::RequiresRegister()); |
1649 summary->set_in(1, ShouldEmitStoreBarrier() | 1686 if (IsUnboxedStore() && opt) { |
| 1687 summary->set_in(1, Location::RequiresFpuRegister()); |
| 1688 summary->AddTemp(Location::RequiresRegister()); |
| 1689 summary->AddTemp(Location::RequiresRegister()); |
| 1690 } else if (IsPotentialUnboxedStore()) { |
| 1691 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1692 ? Location::WritableRegister() |
| 1693 : Location::RequiresRegister()); |
| 1694 summary->AddTemp(Location::RequiresRegister()); |
| 1695 summary->AddTemp(Location::RequiresRegister()); |
| 1696 summary->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1697 : Location::FpuRegisterLocation(D1)); |
| 1698 } else { |
| 1699 summary->set_in(1, ShouldEmitStoreBarrier() |
1650 ? Location::WritableRegister() | 1700 ? Location::WritableRegister() |
1651 : Location::RegisterOrConstant(value())); | 1701 : Location::RegisterOrConstant(value())); |
| 1702 } |
1652 return summary; | 1703 return summary; |
1653 } | 1704 } |
1654 | 1705 |
1655 | 1706 |
1656 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1707 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1708 Label skip_store; |
| 1709 |
1657 Register instance_reg = locs()->in(0).reg(); | 1710 Register instance_reg = locs()->in(0).reg(); |
| 1711 |
| 1712 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1713 DRegister value = locs()->in(1).fpu_reg(); |
| 1714 Register temp = locs()->temp(0).reg(); |
| 1715 Register temp2 = locs()->temp(1).reg(); |
| 1716 |
| 1717 if (is_initialization_) { |
| 1718 StoreInstanceFieldSlowPath* slow_path = |
| 1719 new StoreInstanceFieldSlowPath(this); |
| 1720 compiler->AddSlowPathCode(slow_path); |
| 1721 __ TryAllocate(compiler->double_class(), |
| 1722 slow_path->entry_label(), |
| 1723 temp); |
| 1724 __ Bind(slow_path->exit_label()); |
| 1725 __ mov(temp2, temp); |
| 1726 __ StoreIntoObject(instance_reg, |
| 1727 FieldAddress(instance_reg, field().Offset()), |
| 1728 temp2); |
| 1729 } else { |
| 1730 __ lw(temp, FieldAddress(instance_reg, field().Offset())); |
| 1731 } |
| 1732 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1733 return; |
| 1734 } |
| 1735 |
| 1736 if (IsPotentialUnboxedStore()) { |
| 1737 Register value_reg = locs()->in(1).reg(); |
| 1738 Register temp = locs()->temp(0).reg(); |
| 1739 Register temp2 = locs()->temp(1).reg(); |
| 1740 DRegister fpu_temp = locs()->temp(2).fpu_reg(); |
| 1741 |
| 1742 Label store_pointer, copy_payload; |
| 1743 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1744 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1745 __ BranchNotEqual(temp2, kDoubleCid, &store_pointer); |
| 1746 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1747 __ BranchEqual(temp2, kNullCid, &store_pointer); |
| 1748 |
| 1749 __ lw(temp, FieldAddress(instance_reg, field().Offset())); |
| 1750 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), |
| 1751 ©_payload); |
| 1752 |
| 1753 StoreInstanceFieldSlowPath* slow_path = |
| 1754 new StoreInstanceFieldSlowPath(this); |
| 1755 compiler->AddSlowPathCode(slow_path); |
| 1756 |
| 1757 if (!compiler->is_optimizing()) { |
| 1758 locs()->live_registers()->Add(locs()->in(0)); |
| 1759 locs()->live_registers()->Add(locs()->in(1)); |
| 1760 } |
| 1761 |
| 1762 __ TryAllocate(compiler->double_class(), |
| 1763 slow_path->entry_label(), |
| 1764 temp); |
| 1765 __ Bind(slow_path->exit_label()); |
| 1766 __ mov(temp2, temp); |
| 1767 __ StoreIntoObject(instance_reg, |
| 1768 FieldAddress(instance_reg, field().Offset()), |
| 1769 temp2); |
| 1770 |
| 1771 __ Bind(©_payload); |
| 1772 __ LoadDFromOffset(fpu_temp, |
| 1773 value_reg, |
| 1774 Double::value_offset() - kHeapObjectTag); |
| 1775 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); |
| 1776 __ b(&skip_store); |
| 1777 __ Bind(&store_pointer); |
| 1778 } |
| 1779 |
1658 if (ShouldEmitStoreBarrier()) { | 1780 if (ShouldEmitStoreBarrier()) { |
1659 Register value_reg = locs()->in(1).reg(); | 1781 Register value_reg = locs()->in(1).reg(); |
1660 __ StoreIntoObject(instance_reg, | 1782 __ StoreIntoObject(instance_reg, |
1661 FieldAddress(instance_reg, field().Offset()), | 1783 FieldAddress(instance_reg, field().Offset()), |
1662 value_reg, | 1784 value_reg, |
1663 CanValueBeSmi()); | 1785 CanValueBeSmi()); |
1664 } else { | 1786 } else { |
1665 if (locs()->in(1).IsConstant()) { | 1787 if (locs()->in(1).IsConstant()) { |
1666 __ StoreIntoObjectNoBarrier( | 1788 __ StoreIntoObjectNoBarrier( |
1667 instance_reg, | 1789 instance_reg, |
1668 FieldAddress(instance_reg, field().Offset()), | 1790 FieldAddress(instance_reg, field().Offset()), |
1669 locs()->in(1).constant()); | 1791 locs()->in(1).constant()); |
1670 } else { | 1792 } else { |
1671 Register value_reg = locs()->in(1).reg(); | 1793 Register value_reg = locs()->in(1).reg(); |
1672 __ StoreIntoObjectNoBarrier(instance_reg, | 1794 __ StoreIntoObjectNoBarrier(instance_reg, |
1673 FieldAddress(instance_reg, field().Offset()), value_reg); | 1795 FieldAddress(instance_reg, field().Offset()), value_reg); |
1674 } | 1796 } |
1675 } | 1797 } |
| 1798 __ Bind(&skip_store); |
1676 } | 1799 } |
1677 | 1800 |
1678 | 1801 |
1679 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 1802 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
1680 const intptr_t kNumInputs = 1; | 1803 const intptr_t kNumInputs = 1; |
1681 const intptr_t kNumTemps = 0; | 1804 const intptr_t kNumTemps = 0; |
1682 LocationSummary* summary = | 1805 LocationSummary* summary = |
1683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1684 summary->set_in(0, Location::RequiresRegister()); | 1807 summary->set_in(0, Location::RequiresRegister()); |
1685 summary->set_out(Location::RequiresRegister()); | 1808 summary->set_out(Location::RequiresRegister()); |
1686 return summary; | 1809 return summary; |
1687 } | 1810 } |
1688 | 1811 |
1689 | 1812 |
1690 // When the parser is building an implicit static getter for optimization, | 1813 // When the parser is building an implicit static getter for optimization, |
1691 // it can generate a function body where deoptimization ids do not line up | 1814 // it can generate a function body where deoptimization ids do not line up |
1692 // with the unoptimized code. | 1815 // with the unoptimized code. |
1693 // | 1816 // |
1694 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. | 1817 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. |
1695 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1818 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1696 __ TraceSimMsg("LoadStaticFieldInstr"); | 1819 __ TraceSimMsg("LoadStaticFieldInstr"); |
1697 Register field = locs()->in(0).reg(); | 1820 Register field = locs()->in(0).reg(); |
1698 Register result = locs()->out().reg(); | 1821 Register result = locs()->out().reg(); |
1699 __ lw(result, FieldAddress(field, Field::value_offset())); | 1822 __ lw(result, FieldAddress(field, Field::value_offset())); |
1700 } | 1823 } |
1701 | 1824 |
1702 | 1825 |
1703 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1826 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { |
1704 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1827 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
1705 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 1828 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
1706 : Location::RequiresRegister()); | 1829 : Location::RequiresRegister()); |
1707 locs->set_temp(0, Location::RequiresRegister()); | 1830 locs->set_temp(0, Location::RequiresRegister()); |
1708 return locs; | 1831 return locs; |
1709 } | 1832 } |
1710 | 1833 |
1711 | 1834 |
1712 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1835 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1713 __ TraceSimMsg("StoreStaticFieldInstr"); | 1836 __ TraceSimMsg("StoreStaticFieldInstr"); |
1714 Register value = locs()->in(0).reg(); | 1837 Register value = locs()->in(0).reg(); |
1715 Register temp = locs()->temp(0).reg(); | 1838 Register temp = locs()->temp(0).reg(); |
1716 | 1839 |
1717 __ LoadObject(temp, field()); | 1840 __ LoadObject(temp, field()); |
1718 if (this->value()->NeedsStoreBuffer()) { | 1841 if (this->value()->NeedsStoreBuffer()) { |
1719 __ StoreIntoObject(temp, | 1842 __ StoreIntoObject(temp, |
1720 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); | 1843 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); |
1721 } else { | 1844 } else { |
1722 __ StoreIntoObjectNoBarrier( | 1845 __ StoreIntoObjectNoBarrier( |
1723 temp, FieldAddress(temp, Field::value_offset()), value); | 1846 temp, FieldAddress(temp, Field::value_offset()), value); |
1724 } | 1847 } |
1725 } | 1848 } |
1726 | 1849 |
1727 | 1850 |
1728 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1851 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { |
1729 const intptr_t kNumInputs = 3; | 1852 const intptr_t kNumInputs = 3; |
1730 const intptr_t kNumTemps = 0; | 1853 const intptr_t kNumTemps = 0; |
1731 LocationSummary* summary = | 1854 LocationSummary* summary = |
1732 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1855 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1733 summary->set_in(0, Location::RegisterLocation(A0)); | 1856 summary->set_in(0, Location::RegisterLocation(A0)); |
1734 summary->set_in(1, Location::RegisterLocation(A2)); | 1857 summary->set_in(1, Location::RegisterLocation(A2)); |
1735 summary->set_in(2, Location::RegisterLocation(A1)); | 1858 summary->set_in(2, Location::RegisterLocation(A1)); |
1736 summary->set_out(Location::RegisterLocation(V0)); | 1859 summary->set_out(Location::RegisterLocation(V0)); |
1737 return summary; | 1860 return summary; |
1738 } | 1861 } |
1739 | 1862 |
1740 | 1863 |
1741 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1864 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1742 ASSERT(locs()->in(0).reg() == A0); // Value. | 1865 ASSERT(locs()->in(0).reg() == A0); // Value. |
1743 ASSERT(locs()->in(1).reg() == A2); // Instantiator. | 1866 ASSERT(locs()->in(1).reg() == A2); // Instantiator. |
1744 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments. | 1867 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments. |
1745 | 1868 |
1746 __ Comment("InstanceOfInstr"); | 1869 __ Comment("InstanceOfInstr"); |
1747 compiler->GenerateInstanceOf(token_pos(), | 1870 compiler->GenerateInstanceOf(token_pos(), |
1748 deopt_id(), | 1871 deopt_id(), |
1749 type(), | 1872 type(), |
1750 negate_result(), | 1873 negate_result(), |
1751 locs()); | 1874 locs()); |
1752 ASSERT(locs()->out().reg() == V0); | 1875 ASSERT(locs()->out().reg() == V0); |
1753 } | 1876 } |
1754 | 1877 |
1755 | 1878 |
1756 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1879 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
1757 const intptr_t kNumInputs = 1; | 1880 const intptr_t kNumInputs = 1; |
1758 const intptr_t kNumTemps = 0; | 1881 const intptr_t kNumTemps = 0; |
1759 LocationSummary* locs = | 1882 LocationSummary* locs = |
1760 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1883 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1761 locs->set_in(0, Location::RegisterLocation(A0)); | 1884 locs->set_in(0, Location::RegisterLocation(A0)); |
1762 locs->set_out(Location::RegisterLocation(V0)); | 1885 locs->set_out(Location::RegisterLocation(V0)); |
1763 return locs; | 1886 return locs; |
1764 } | 1887 } |
1765 | 1888 |
1766 | 1889 |
1767 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1890 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1768 __ TraceSimMsg("CreateArrayInstr"); | 1891 __ TraceSimMsg("CreateArrayInstr"); |
1769 // Allocate the array. A1 = length, A0 = element type. | 1892 // Allocate the array. A1 = length, A0 = element type. |
1770 ASSERT(locs()->in(0).reg() == A0); | 1893 ASSERT(locs()->in(0).reg() == A0); |
1771 __ LoadImmediate(A1, Smi::RawValue(num_elements())); | 1894 __ LoadImmediate(A1, Smi::RawValue(num_elements())); |
1772 compiler->GenerateCall(token_pos(), | 1895 compiler->GenerateCall(token_pos(), |
1773 &StubCode::AllocateArrayLabel(), | 1896 &StubCode::AllocateArrayLabel(), |
1774 PcDescriptors::kOther, | 1897 PcDescriptors::kOther, |
1775 locs()); | 1898 locs()); |
1776 ASSERT(locs()->out().reg() == V0); | 1899 ASSERT(locs()->out().reg() == V0); |
1777 } | 1900 } |
1778 | 1901 |
1779 | 1902 |
1780 LocationSummary* | 1903 LocationSummary* |
1781 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1904 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const { |
1782 return MakeCallSummary(); | 1905 return MakeCallSummary(); |
1783 } | 1906 } |
1784 | 1907 |
1785 | 1908 |
1786 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1909 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
1787 FlowGraphCompiler* compiler) { | 1910 FlowGraphCompiler* compiler) { |
1788 compiler->GenerateRuntimeCall(token_pos(), | 1911 compiler->GenerateRuntimeCall(token_pos(), |
1789 deopt_id(), | 1912 deopt_id(), |
1790 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1913 kAllocateObjectWithBoundsCheckRuntimeEntry, |
1791 3, | 1914 3, |
1792 locs()); | 1915 locs()); |
1793 __ Drop(3); | 1916 __ Drop(3); |
1794 ASSERT(locs()->out().reg() == V0); | 1917 ASSERT(locs()->out().reg() == V0); |
1795 __ Pop(V0); // Pop new instance. | 1918 __ Pop(V0); // Pop new instance. |
1796 } | 1919 } |
1797 | 1920 |
1798 | 1921 |
1799 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 1922 class BoxDoubleSlowPath : public SlowPathCode { |
1800 return LocationSummary::Make(1, | 1923 public: |
1801 Location::RequiresRegister(), | 1924 explicit BoxDoubleSlowPath(Instruction* instruction) |
1802 LocationSummary::kNoCall); | 1925 : instruction_(instruction) { } |
| 1926 |
| 1927 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1928 __ Comment("BoxDoubleSlowPath"); |
| 1929 __ Bind(entry_label()); |
| 1930 const Class& double_class = compiler->double_class(); |
| 1931 const Code& stub = |
| 1932 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1933 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1934 |
| 1935 LocationSummary* locs = instruction_->locs(); |
| 1936 locs->live_registers()->Remove(locs->out()); |
| 1937 |
| 1938 compiler->SaveLiveRegisters(locs); |
| 1939 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1940 &label, |
| 1941 PcDescriptors::kOther, |
| 1942 locs); |
| 1943 if (locs->out().reg() != V0) { |
| 1944 __ mov(locs->out().reg(), V0); |
| 1945 } |
| 1946 compiler->RestoreLiveRegisters(locs); |
| 1947 |
| 1948 __ b(exit_label()); |
| 1949 } |
| 1950 |
| 1951 private: |
| 1952 Instruction* instruction_; |
| 1953 }; |
| 1954 |
| 1955 |
| 1956 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 1957 const intptr_t kNumInputs = 1; |
| 1958 const intptr_t kNumTemps = 0; |
| 1959 LocationSummary* locs = |
| 1960 new LocationSummary( |
| 1961 kNumInputs, kNumTemps, |
| 1962 (opt && !IsPotentialUnboxedLoad()) |
| 1963 ? LocationSummary::kNoCall |
| 1964 : LocationSummary::kCallOnSlowPath); |
| 1965 |
| 1966 locs->set_in(0, Location::RequiresRegister()); |
| 1967 |
| 1968 if (IsUnboxedLoad() && opt) { |
| 1969 locs->AddTemp(Location::RequiresRegister()); |
| 1970 } else if (IsPotentialUnboxedLoad()) { |
| 1971 locs->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1972 : Location::FpuRegisterLocation(D1)); |
| 1973 locs->AddTemp(Location::RequiresRegister()); |
| 1974 } |
| 1975 locs->set_out(Location::RequiresRegister()); |
| 1976 return locs; |
1803 } | 1977 } |
1804 | 1978 |
1805 | 1979 |
1806 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1980 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1807 Register instance_reg = locs()->in(0).reg(); | 1981 Register instance_reg = locs()->in(0).reg(); |
| 1982 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 1983 DRegister result = locs()->out().fpu_reg(); |
| 1984 Register temp = locs()->temp(0).reg(); |
| 1985 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1986 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| 1987 return; |
| 1988 } |
| 1989 |
| 1990 Label done; |
1808 Register result_reg = locs()->out().reg(); | 1991 Register result_reg = locs()->out().reg(); |
| 1992 if (IsPotentialUnboxedLoad()) { |
| 1993 Register temp = locs()->temp(1).reg(); |
| 1994 DRegister value = locs()->temp(0).fpu_reg(); |
1809 | 1995 |
| 1996 Label load_pointer; |
| 1997 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 1998 |
| 1999 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 2000 FieldAddress field_nullability_operand(result_reg, |
| 2001 Field::is_nullable_offset()); |
| 2002 |
| 2003 __ lw(temp, field_cid_operand); |
| 2004 __ BranchNotEqual(temp, kDoubleCid, &load_pointer); |
| 2005 |
| 2006 __ lw(temp, field_nullability_operand); |
| 2007 __ BranchEqual(temp, kNullCid, &load_pointer); |
| 2008 |
| 2009 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 2010 compiler->AddSlowPathCode(slow_path); |
| 2011 |
| 2012 if (!compiler->is_optimizing()) { |
| 2013 locs()->live_registers()->Add(locs()->in(0)); |
| 2014 } |
| 2015 |
| 2016 __ TryAllocate(compiler->double_class(), |
| 2017 slow_path->entry_label(), |
| 2018 result_reg); |
| 2019 __ Bind(slow_path->exit_label()); |
| 2020 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2021 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 2022 __ StoreDToOffset(value, |
| 2023 result_reg, |
| 2024 Double::value_offset() - kHeapObjectTag); |
| 2025 __ b(&done); |
| 2026 __ Bind(&load_pointer); |
| 2027 } |
1810 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); | 2028 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); |
| 2029 __ Bind(&done); |
1811 } | 2030 } |
1812 | 2031 |
1813 | 2032 |
1814 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { | 2033 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
1815 const intptr_t kNumInputs = 1; | 2034 const intptr_t kNumInputs = 1; |
1816 const intptr_t kNumTemps = 0; | 2035 const intptr_t kNumTemps = 0; |
1817 LocationSummary* locs = | 2036 LocationSummary* locs = |
1818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2037 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1819 locs->set_in(0, Location::RegisterLocation(T0)); | 2038 locs->set_in(0, Location::RegisterLocation(T0)); |
1820 locs->set_out(Location::RegisterLocation(T0)); | 2039 locs->set_out(Location::RegisterLocation(T0)); |
1821 return locs; | 2040 return locs; |
1822 } | 2041 } |
1823 | 2042 |
1824 | 2043 |
(...skipping 19 matching lines...) Expand all Loading... |
1844 2, | 2063 2, |
1845 locs()); | 2064 locs()); |
1846 // Pop instantiated type. | 2065 // Pop instantiated type. |
1847 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2066 __ lw(result_reg, Address(SP, 2 * kWordSize)); |
1848 // Drop instantiator and uninstantiated type. | 2067 // Drop instantiator and uninstantiated type. |
1849 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2068 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
1850 ASSERT(instantiator_reg == result_reg); | 2069 ASSERT(instantiator_reg == result_reg); |
1851 } | 2070 } |
1852 | 2071 |
1853 | 2072 |
1854 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 2073 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 2074 bool opt) const { |
1855 const intptr_t kNumInputs = 1; | 2075 const intptr_t kNumInputs = 1; |
1856 const intptr_t kNumTemps = 0; | 2076 const intptr_t kNumTemps = 0; |
1857 LocationSummary* locs = | 2077 LocationSummary* locs = |
1858 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1859 locs->set_in(0, Location::RegisterLocation(T0)); | 2079 locs->set_in(0, Location::RegisterLocation(T0)); |
1860 locs->set_out(Location::RegisterLocation(T0)); | 2080 locs->set_out(Location::RegisterLocation(T0)); |
1861 return locs; | 2081 return locs; |
1862 } | 2082 } |
1863 | 2083 |
1864 | 2084 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 // Pop instantiated type arguments. | 2120 // Pop instantiated type arguments. |
1901 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2121 __ lw(result_reg, Address(SP, 2 * kWordSize)); |
1902 // Drop instantiator and uninstantiated type arguments. | 2122 // Drop instantiator and uninstantiated type arguments. |
1903 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2123 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
1904 __ Bind(&type_arguments_instantiated); | 2124 __ Bind(&type_arguments_instantiated); |
1905 ASSERT(instantiator_reg == result_reg); | 2125 ASSERT(instantiator_reg == result_reg); |
1906 } | 2126 } |
1907 | 2127 |
1908 | 2128 |
1909 LocationSummary* | 2129 LocationSummary* |
1910 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2130 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const { |
1911 const intptr_t kNumInputs = 1; | 2131 const intptr_t kNumInputs = 1; |
1912 const intptr_t kNumTemps = 0; | 2132 const intptr_t kNumTemps = 0; |
1913 LocationSummary* locs = | 2133 LocationSummary* locs = |
1914 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1915 locs->set_in(0, Location::RequiresRegister()); | 2135 locs->set_in(0, Location::RequiresRegister()); |
1916 locs->set_out(Location::SameAsFirstInput()); | 2136 locs->set_out(Location::SameAsFirstInput()); |
1917 return locs; | 2137 return locs; |
1918 } | 2138 } |
1919 | 2139 |
1920 | 2140 |
(...skipping 20 matching lines...) Expand all Loading... |
1941 // instantiate the type arguments. | 2161 // instantiate the type arguments. |
1942 __ LoadObject(result_reg, type_arguments()); | 2162 __ LoadObject(result_reg, type_arguments()); |
1943 // result_reg: uninstantiated type arguments. | 2163 // result_reg: uninstantiated type arguments. |
1944 __ Bind(&type_arguments_instantiated); | 2164 __ Bind(&type_arguments_instantiated); |
1945 | 2165 |
1946 // result_reg: uninstantiated or instantiated type arguments. | 2166 // result_reg: uninstantiated or instantiated type arguments. |
1947 } | 2167 } |
1948 | 2168 |
1949 | 2169 |
1950 LocationSummary* | 2170 LocationSummary* |
1951 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 2171 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const { |
1952 const intptr_t kNumInputs = 1; | 2172 const intptr_t kNumInputs = 1; |
1953 const intptr_t kNumTemps = 0; | 2173 const intptr_t kNumTemps = 0; |
1954 LocationSummary* locs = | 2174 LocationSummary* locs = |
1955 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2175 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1956 locs->set_in(0, Location::RequiresRegister()); | 2176 locs->set_in(0, Location::RequiresRegister()); |
1957 locs->set_out(Location::SameAsFirstInput()); | 2177 locs->set_out(Location::SameAsFirstInput()); |
1958 return locs; | 2178 return locs; |
1959 } | 2179 } |
1960 | 2180 |
1961 | 2181 |
(...skipping 17 matching lines...) Expand all Loading... |
1979 &instantiator_not_null); | 2199 &instantiator_not_null); |
1980 // Null was used in VisitExtractConstructorTypeArguments as the | 2200 // Null was used in VisitExtractConstructorTypeArguments as the |
1981 // instantiated type arguments, no proper instantiator needed. | 2201 // instantiated type arguments, no proper instantiator needed. |
1982 __ LoadImmediate(instantiator_reg, | 2202 __ LoadImmediate(instantiator_reg, |
1983 Smi::RawValue(StubCode::kNoInstantiator)); | 2203 Smi::RawValue(StubCode::kNoInstantiator)); |
1984 __ Bind(&instantiator_not_null); | 2204 __ Bind(&instantiator_not_null); |
1985 // instantiator_reg: instantiator or kNoInstantiator. | 2205 // instantiator_reg: instantiator or kNoInstantiator. |
1986 } | 2206 } |
1987 | 2207 |
1988 | 2208 |
1989 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 2209 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
1990 const intptr_t kNumInputs = 0; | 2210 const intptr_t kNumInputs = 0; |
1991 const intptr_t kNumTemps = 1; | 2211 const intptr_t kNumTemps = 1; |
1992 LocationSummary* locs = | 2212 LocationSummary* locs = |
1993 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2213 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1994 locs->set_temp(0, Location::RegisterLocation(T1)); | 2214 locs->set_temp(0, Location::RegisterLocation(T1)); |
1995 locs->set_out(Location::RegisterLocation(V0)); | 2215 locs->set_out(Location::RegisterLocation(V0)); |
1996 return locs; | 2216 return locs; |
1997 } | 2217 } |
1998 | 2218 |
1999 | 2219 |
2000 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2220 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2001 Register temp = T1; | 2221 Register temp = T1; |
2002 ASSERT(locs()->temp(0).reg() == temp); | 2222 ASSERT(locs()->temp(0).reg() == temp); |
2003 ASSERT(locs()->out().reg() == V0); | 2223 ASSERT(locs()->out().reg() == V0); |
2004 | 2224 |
2005 __ TraceSimMsg("AllocateContextInstr"); | 2225 __ TraceSimMsg("AllocateContextInstr"); |
2006 __ LoadImmediate(temp, num_context_variables()); | 2226 __ LoadImmediate(temp, num_context_variables()); |
2007 const ExternalLabel label("alloc_context", | 2227 const ExternalLabel label("alloc_context", |
2008 StubCode::AllocateContextEntryPoint()); | 2228 StubCode::AllocateContextEntryPoint()); |
2009 compiler->GenerateCall(token_pos(), | 2229 compiler->GenerateCall(token_pos(), |
2010 &label, | 2230 &label, |
2011 PcDescriptors::kOther, | 2231 PcDescriptors::kOther, |
2012 locs()); | 2232 locs()); |
2013 } | 2233 } |
2014 | 2234 |
2015 | 2235 |
2016 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 2236 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { |
2017 const intptr_t kNumInputs = 1; | 2237 const intptr_t kNumInputs = 1; |
2018 const intptr_t kNumTemps = 0; | 2238 const intptr_t kNumTemps = 0; |
2019 LocationSummary* locs = | 2239 LocationSummary* locs = |
2020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2240 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
2021 locs->set_in(0, Location::RegisterLocation(T0)); | 2241 locs->set_in(0, Location::RegisterLocation(T0)); |
2022 locs->set_out(Location::RegisterLocation(T0)); | 2242 locs->set_out(Location::RegisterLocation(T0)); |
2023 return locs; | 2243 return locs; |
2024 } | 2244 } |
2025 | 2245 |
2026 | 2246 |
(...skipping 11 matching lines...) Expand all Loading... |
2038 compiler->GenerateRuntimeCall(token_pos(), | 2258 compiler->GenerateRuntimeCall(token_pos(), |
2039 deopt_id(), | 2259 deopt_id(), |
2040 kCloneContextRuntimeEntry, | 2260 kCloneContextRuntimeEntry, |
2041 1, | 2261 1, |
2042 locs()); | 2262 locs()); |
2043 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context). | 2263 __ lw(result, Address(SP, 1 * kWordSize)); // Get result (cloned context). |
2044 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 2264 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
2045 } | 2265 } |
2046 | 2266 |
2047 | 2267 |
2048 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2268 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const { |
2049 UNREACHABLE(); | 2269 UNREACHABLE(); |
2050 return NULL; | 2270 return NULL; |
2051 } | 2271 } |
2052 | 2272 |
2053 | 2273 |
2054 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2274 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2055 __ Bind(compiler->GetJumpLabel(this)); | 2275 __ Bind(compiler->GetJumpLabel(this)); |
2056 compiler->AddExceptionHandler(catch_try_index(), | 2276 compiler->AddExceptionHandler(catch_try_index(), |
2057 try_index(), | 2277 try_index(), |
2058 compiler->assembler()->CodeSize(), | 2278 compiler->assembler()->CodeSize(), |
(...skipping 19 matching lines...) Expand all Loading... |
2078 | 2298 |
2079 // Restore stack and initialize the two exception variables: | 2299 // Restore stack and initialize the two exception variables: |
2080 // exception and stack trace variables. | 2300 // exception and stack trace variables. |
2081 __ sw(kExceptionObjectReg, | 2301 __ sw(kExceptionObjectReg, |
2082 Address(FP, exception_var().index() * kWordSize)); | 2302 Address(FP, exception_var().index() * kWordSize)); |
2083 __ sw(kStackTraceObjectReg, | 2303 __ sw(kStackTraceObjectReg, |
2084 Address(FP, stacktrace_var().index() * kWordSize)); | 2304 Address(FP, stacktrace_var().index() * kWordSize)); |
2085 } | 2305 } |
2086 | 2306 |
2087 | 2307 |
2088 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2308 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const { |
2089 const intptr_t kNumInputs = 0; | 2309 const intptr_t kNumInputs = 0; |
2090 const intptr_t kNumTemps = 1; | 2310 const intptr_t kNumTemps = 1; |
2091 LocationSummary* summary = | 2311 LocationSummary* summary = |
2092 new LocationSummary(kNumInputs, | 2312 new LocationSummary(kNumInputs, |
2093 kNumTemps, | 2313 kNumTemps, |
2094 LocationSummary::kCallOnSlowPath); | 2314 LocationSummary::kCallOnSlowPath); |
2095 summary->set_temp(0, Location::RequiresRegister()); | 2315 summary->set_temp(0, Location::RequiresRegister()); |
2096 return summary; | 2316 return summary; |
2097 } | 2317 } |
2098 | 2318 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 // Overflow test (preserve left, right, and temp); | 2486 // Overflow test (preserve left, right, and temp); |
2267 __ sllv(CMPRES1, left, temp); | 2487 __ sllv(CMPRES1, left, temp); |
2268 __ srav(CMPRES1, CMPRES1, temp); | 2488 __ srav(CMPRES1, CMPRES1, temp); |
2269 __ bne(CMPRES1, left, deopt); // Overflow. | 2489 __ bne(CMPRES1, left, deopt); // Overflow. |
2270 // Shift for result now we know there is no overflow. | 2490 // Shift for result now we know there is no overflow. |
2271 __ sllv(result, left, temp); | 2491 __ sllv(result, left, temp); |
2272 } | 2492 } |
2273 } | 2493 } |
2274 | 2494 |
2275 | 2495 |
2276 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 2496 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const { |
2277 const intptr_t kNumInputs = 2; | 2497 const intptr_t kNumInputs = 2; |
2278 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0; | 2498 const intptr_t kNumTemps = op_kind() == Token::kADD ? 1 : 0; |
2279 LocationSummary* summary = | 2499 LocationSummary* summary = |
2280 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2500 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2281 if (op_kind() == Token::kTRUNCDIV) { | 2501 if (op_kind() == Token::kTRUNCDIV) { |
2282 summary->set_in(0, Location::RequiresRegister()); | 2502 summary->set_in(0, Location::RequiresRegister()); |
2283 if (RightIsPowerOfTwoConstant()) { | 2503 if (RightIsPowerOfTwoConstant()) { |
2284 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2504 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
2285 summary->set_in(1, Location::Constant(right_constant->value())); | 2505 summary->set_in(1, Location::Constant(right_constant->value())); |
2286 } else { | 2506 } else { |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 UNREACHABLE(); | 2832 UNREACHABLE(); |
2613 break; | 2833 break; |
2614 } | 2834 } |
2615 default: | 2835 default: |
2616 UNREACHABLE(); | 2836 UNREACHABLE(); |
2617 break; | 2837 break; |
2618 } | 2838 } |
2619 } | 2839 } |
2620 | 2840 |
2621 | 2841 |
2622 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 2842 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const { |
2623 intptr_t left_cid = left()->Type()->ToCid(); | 2843 intptr_t left_cid = left()->Type()->ToCid(); |
2624 intptr_t right_cid = right()->Type()->ToCid(); | 2844 intptr_t right_cid = right()->Type()->ToCid(); |
2625 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); | 2845 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); |
2626 const intptr_t kNumInputs = 2; | 2846 const intptr_t kNumInputs = 2; |
2627 const intptr_t kNumTemps = 0; | 2847 const intptr_t kNumTemps = 0; |
2628 LocationSummary* summary = | 2848 LocationSummary* summary = |
2629 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2849 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2630 summary->set_in(0, Location::RequiresRegister()); | 2850 summary->set_in(0, Location::RequiresRegister()); |
2631 summary->set_in(1, Location::RequiresRegister()); | 2851 summary->set_in(1, Location::RequiresRegister()); |
2632 return summary; | 2852 return summary; |
(...skipping 11 matching lines...) Expand all Loading... |
2644 } else if (right_cid == kSmiCid) { | 2864 } else if (right_cid == kSmiCid) { |
2645 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); | 2865 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); |
2646 } else { | 2866 } else { |
2647 __ or_(TMP, left, right); | 2867 __ or_(TMP, left, right); |
2648 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); | 2868 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); |
2649 } | 2869 } |
2650 __ beq(CMPRES1, ZR, deopt); | 2870 __ beq(CMPRES1, ZR, deopt); |
2651 } | 2871 } |
2652 | 2872 |
2653 | 2873 |
2654 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 2874 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { |
2655 const intptr_t kNumInputs = 1; | 2875 const intptr_t kNumInputs = 1; |
2656 const intptr_t kNumTemps = 0; | 2876 const intptr_t kNumTemps = 0; |
2657 LocationSummary* summary = | 2877 LocationSummary* summary = |
2658 new LocationSummary(kNumInputs, | 2878 new LocationSummary(kNumInputs, |
2659 kNumTemps, | 2879 kNumTemps, |
2660 LocationSummary::kCallOnSlowPath); | 2880 LocationSummary::kCallOnSlowPath); |
2661 summary->set_in(0, Location::RequiresFpuRegister()); | 2881 summary->set_in(0, Location::RequiresFpuRegister()); |
2662 summary->set_out(Location::RequiresRegister()); | 2882 summary->set_out(Location::RequiresRegister()); |
2663 return summary; | 2883 return summary; |
2664 } | 2884 } |
2665 | 2885 |
2666 | 2886 |
2667 class BoxDoubleSlowPath : public SlowPathCode { | |
2668 public: | |
2669 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | |
2670 : instruction_(instruction) { } | |
2671 | |
2672 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2673 __ Comment("BoxDoubleSlowPath"); | |
2674 __ Bind(entry_label()); | |
2675 const Class& double_class = compiler->double_class(); | |
2676 const Code& stub = | |
2677 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
2678 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
2679 | |
2680 LocationSummary* locs = instruction_->locs(); | |
2681 locs->live_registers()->Remove(locs->out()); | |
2682 | |
2683 compiler->SaveLiveRegisters(locs); | |
2684 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | |
2685 &label, | |
2686 PcDescriptors::kOther, | |
2687 locs); | |
2688 if (locs->out().reg() != V0) { | |
2689 __ mov(locs->out().reg(), V0); | |
2690 } | |
2691 compiler->RestoreLiveRegisters(locs); | |
2692 | |
2693 __ b(exit_label()); | |
2694 } | |
2695 | |
2696 private: | |
2697 BoxDoubleInstr* instruction_; | |
2698 }; | |
2699 | |
2700 | |
2701 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2887 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2702 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2888 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
2703 compiler->AddSlowPathCode(slow_path); | 2889 compiler->AddSlowPathCode(slow_path); |
2704 | 2890 |
2705 Register out_reg = locs()->out().reg(); | 2891 Register out_reg = locs()->out().reg(); |
2706 DRegister value = locs()->in(0).fpu_reg(); | 2892 DRegister value = locs()->in(0).fpu_reg(); |
2707 | 2893 |
2708 __ TryAllocate(compiler->double_class(), | 2894 __ TryAllocate(compiler->double_class(), |
2709 slow_path->entry_label(), | 2895 slow_path->entry_label(), |
2710 out_reg); | 2896 out_reg); |
2711 __ Bind(slow_path->exit_label()); | 2897 __ Bind(slow_path->exit_label()); |
2712 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 2898 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
2713 } | 2899 } |
2714 | 2900 |
2715 | 2901 |
2716 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2902 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { |
2717 const intptr_t kNumInputs = 1; | 2903 const intptr_t kNumInputs = 1; |
2718 const intptr_t value_cid = value()->Type()->ToCid(); | 2904 const intptr_t value_cid = value()->Type()->ToCid(); |
2719 const bool needs_writable_input = (value_cid == kSmiCid); | 2905 const bool needs_writable_input = (value_cid == kSmiCid); |
2720 const intptr_t kNumTemps = 0; | 2906 const intptr_t kNumTemps = 0; |
2721 LocationSummary* summary = | 2907 LocationSummary* summary = |
2722 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2908 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2723 summary->set_in(0, needs_writable_input | 2909 summary->set_in(0, needs_writable_input |
2724 ? Location::WritableRegister() | 2910 ? Location::WritableRegister() |
2725 : Location::RequiresRegister()); | 2911 : Location::RequiresRegister()); |
2726 summary->set_out(Location::RequiresFpuRegister()); | 2912 summary->set_out(Location::RequiresFpuRegister()); |
(...skipping 25 matching lines...) Expand all Loading... |
2752 __ Bind(&is_smi); | 2938 __ Bind(&is_smi); |
2753 // TODO(regis): Why do we preserve value here but not above? | 2939 // TODO(regis): Why do we preserve value here but not above? |
2754 __ sra(TMP, value, 1); | 2940 __ sra(TMP, value, 1); |
2755 __ mtc1(TMP, STMP1); | 2941 __ mtc1(TMP, STMP1); |
2756 __ cvtdw(result, STMP1); | 2942 __ cvtdw(result, STMP1); |
2757 __ Bind(&done); | 2943 __ Bind(&done); |
2758 } | 2944 } |
2759 } | 2945 } |
2760 | 2946 |
2761 | 2947 |
2762 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | 2948 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
2763 UNIMPLEMENTED(); | 2949 UNIMPLEMENTED(); |
2764 return NULL; | 2950 return NULL; |
2765 } | 2951 } |
2766 | 2952 |
2767 | 2953 |
2768 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2954 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2769 UNIMPLEMENTED(); | 2955 UNIMPLEMENTED(); |
2770 } | 2956 } |
2771 | 2957 |
2772 | 2958 |
2773 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2959 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
2774 UNIMPLEMENTED(); | 2960 UNIMPLEMENTED(); |
2775 return NULL; | 2961 return NULL; |
2776 } | 2962 } |
2777 | 2963 |
2778 | 2964 |
2779 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2965 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2780 UNIMPLEMENTED(); | 2966 UNIMPLEMENTED(); |
2781 } | 2967 } |
2782 | 2968 |
2783 | 2969 |
2784 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { | 2970 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
2785 UNIMPLEMENTED(); | 2971 UNIMPLEMENTED(); |
2786 return NULL; | 2972 return NULL; |
2787 } | 2973 } |
2788 | 2974 |
2789 | 2975 |
2790 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2976 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2791 UNIMPLEMENTED(); | 2977 UNIMPLEMENTED(); |
2792 } | 2978 } |
2793 | 2979 |
2794 | 2980 |
2795 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { | 2981 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
2796 UNIMPLEMENTED(); | 2982 UNIMPLEMENTED(); |
2797 return NULL; | 2983 return NULL; |
2798 } | 2984 } |
2799 | 2985 |
2800 | 2986 |
2801 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2987 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2802 UNIMPLEMENTED(); | 2988 UNIMPLEMENTED(); |
2803 } | 2989 } |
2804 | 2990 |
2805 | 2991 |
2806 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2992 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
2807 const intptr_t kNumInputs = 2; | 2993 const intptr_t kNumInputs = 2; |
2808 const intptr_t kNumTemps = 0; | 2994 const intptr_t kNumTemps = 0; |
2809 LocationSummary* summary = | 2995 LocationSummary* summary = |
2810 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2996 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2811 summary->set_in(0, Location::RequiresFpuRegister()); | 2997 summary->set_in(0, Location::RequiresFpuRegister()); |
2812 summary->set_in(1, Location::RequiresFpuRegister()); | 2998 summary->set_in(1, Location::RequiresFpuRegister()); |
2813 summary->set_out(Location::RequiresFpuRegister()); | 2999 summary->set_out(Location::RequiresFpuRegister()); |
2814 return summary; | 3000 return summary; |
2815 } | 3001 } |
2816 | 3002 |
2817 | 3003 |
2818 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3004 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2819 DRegister left = locs()->in(0).fpu_reg(); | 3005 DRegister left = locs()->in(0).fpu_reg(); |
2820 DRegister right = locs()->in(1).fpu_reg(); | 3006 DRegister right = locs()->in(1).fpu_reg(); |
2821 DRegister result = locs()->out().fpu_reg(); | 3007 DRegister result = locs()->out().fpu_reg(); |
2822 switch (op_kind()) { | 3008 switch (op_kind()) { |
2823 case Token::kADD: __ addd(result, left, right); break; | 3009 case Token::kADD: __ addd(result, left, right); break; |
2824 case Token::kSUB: __ subd(result, left, right); break; | 3010 case Token::kSUB: __ subd(result, left, right); break; |
2825 case Token::kMUL: __ muld(result, left, right); break; | 3011 case Token::kMUL: __ muld(result, left, right); break; |
2826 case Token::kDIV: __ divd(result, left, right); break; | 3012 case Token::kDIV: __ divd(result, left, right); break; |
2827 default: UNREACHABLE(); | 3013 default: UNREACHABLE(); |
2828 } | 3014 } |
2829 } | 3015 } |
2830 | 3016 |
2831 | 3017 |
2832 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { | 3018 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { |
2833 UNIMPLEMENTED(); | 3019 UNIMPLEMENTED(); |
2834 return NULL; | 3020 return NULL; |
2835 } | 3021 } |
2836 | 3022 |
2837 | 3023 |
2838 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3024 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2839 UNIMPLEMENTED(); | 3025 UNIMPLEMENTED(); |
2840 } | 3026 } |
2841 | 3027 |
2842 | 3028 |
2843 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { | 3029 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
2844 UNIMPLEMENTED(); | 3030 UNIMPLEMENTED(); |
2845 return NULL; | 3031 return NULL; |
2846 } | 3032 } |
2847 | 3033 |
2848 | 3034 |
2849 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3035 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2850 UNIMPLEMENTED(); | 3036 UNIMPLEMENTED(); |
2851 } | 3037 } |
2852 | 3038 |
2853 | 3039 |
2854 | 3040 |
2855 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3041 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { |
2856 UNIMPLEMENTED(); | 3042 UNIMPLEMENTED(); |
2857 return NULL; | 3043 return NULL; |
2858 } | 3044 } |
2859 | 3045 |
2860 | 3046 |
2861 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3047 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2862 UNIMPLEMENTED(); | 3048 UNIMPLEMENTED(); |
2863 } | 3049 } |
2864 | 3050 |
2865 | 3051 |
2866 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { | 3052 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 3053 bool opt) const { |
2867 UNIMPLEMENTED(); | 3054 UNIMPLEMENTED(); |
2868 return NULL; | 3055 return NULL; |
2869 } | 3056 } |
2870 | 3057 |
2871 | 3058 |
2872 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3059 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2873 UNIMPLEMENTED(); | 3060 UNIMPLEMENTED(); |
2874 } | 3061 } |
2875 | 3062 |
2876 | 3063 |
2877 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { | 3064 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { |
2878 UNIMPLEMENTED(); | 3065 UNIMPLEMENTED(); |
2879 return NULL; | 3066 return NULL; |
2880 } | 3067 } |
2881 | 3068 |
2882 | 3069 |
2883 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3070 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2884 UNIMPLEMENTED(); | 3071 UNIMPLEMENTED(); |
2885 } | 3072 } |
2886 | 3073 |
2887 | 3074 |
2888 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { | 3075 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { |
2889 UNIMPLEMENTED(); | 3076 UNIMPLEMENTED(); |
2890 return NULL; | 3077 return NULL; |
2891 } | 3078 } |
2892 | 3079 |
2893 | 3080 |
2894 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3081 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2895 UNIMPLEMENTED(); | 3082 UNIMPLEMENTED(); |
2896 } | 3083 } |
2897 | 3084 |
2898 | 3085 |
2899 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { | 3086 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { |
2900 UNIMPLEMENTED(); | 3087 UNIMPLEMENTED(); |
2901 return NULL; | 3088 return NULL; |
2902 } | 3089 } |
2903 | 3090 |
2904 | 3091 |
2905 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3092 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2906 UNIMPLEMENTED(); | 3093 UNIMPLEMENTED(); |
2907 } | 3094 } |
2908 | 3095 |
2909 | 3096 |
2910 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { | 3097 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { |
2911 UNIMPLEMENTED(); | 3098 UNIMPLEMENTED(); |
2912 return NULL; | 3099 return NULL; |
2913 } | 3100 } |
2914 | 3101 |
2915 | 3102 |
2916 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3103 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2917 UNIMPLEMENTED(); | 3104 UNIMPLEMENTED(); |
2918 } | 3105 } |
2919 | 3106 |
2920 | 3107 |
2921 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { | 3108 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { |
2922 UNIMPLEMENTED(); | 3109 UNIMPLEMENTED(); |
2923 return NULL; | 3110 return NULL; |
2924 } | 3111 } |
2925 | 3112 |
2926 | 3113 |
2927 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3114 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2928 UNIMPLEMENTED(); | 3115 UNIMPLEMENTED(); |
2929 } | 3116 } |
2930 | 3117 |
2931 | 3118 |
2932 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { | 3119 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { |
2933 UNIMPLEMENTED(); | 3120 UNIMPLEMENTED(); |
2934 return NULL; | 3121 return NULL; |
2935 } | 3122 } |
2936 | 3123 |
2937 | 3124 |
2938 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3125 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2939 UNIMPLEMENTED(); | 3126 UNIMPLEMENTED(); |
2940 } | 3127 } |
2941 | 3128 |
2942 | 3129 |
2943 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { | 3130 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { |
2944 UNIMPLEMENTED(); | 3131 UNIMPLEMENTED(); |
2945 return NULL; | 3132 return NULL; |
2946 } | 3133 } |
2947 | 3134 |
2948 | 3135 |
2949 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3136 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2950 UNIMPLEMENTED(); | 3137 UNIMPLEMENTED(); |
2951 } | 3138 } |
2952 | 3139 |
2953 | 3140 |
2954 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { | 3141 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { |
2955 UNIMPLEMENTED(); | 3142 UNIMPLEMENTED(); |
2956 return NULL; | 3143 return NULL; |
2957 } | 3144 } |
2958 | 3145 |
2959 | 3146 |
2960 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3147 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2961 UNIMPLEMENTED(); | 3148 UNIMPLEMENTED(); |
2962 } | 3149 } |
2963 | 3150 |
2964 | 3151 |
2965 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { | 3152 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { |
2966 UNIMPLEMENTED(); | 3153 UNIMPLEMENTED(); |
2967 return NULL; | 3154 return NULL; |
2968 } | 3155 } |
2969 | 3156 |
2970 | 3157 |
2971 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3158 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2972 UNIMPLEMENTED(); | 3159 UNIMPLEMENTED(); |
2973 } | 3160 } |
2974 | 3161 |
2975 | 3162 |
2976 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { | 3163 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { |
2977 UNIMPLEMENTED(); | 3164 UNIMPLEMENTED(); |
2978 return NULL; | 3165 return NULL; |
2979 } | 3166 } |
2980 | 3167 |
2981 | 3168 |
2982 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3169 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2983 UNIMPLEMENTED(); | 3170 UNIMPLEMENTED(); |
2984 } | 3171 } |
2985 | 3172 |
2986 | 3173 |
2987 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { | 3174 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
| 3175 bool opt) const { |
2988 UNIMPLEMENTED(); | 3176 UNIMPLEMENTED(); |
2989 return NULL; | 3177 return NULL; |
2990 } | 3178 } |
2991 | 3179 |
2992 | 3180 |
2993 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3181 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2994 UNIMPLEMENTED(); | 3182 UNIMPLEMENTED(); |
2995 } | 3183 } |
2996 | 3184 |
2997 | 3185 |
2998 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { | 3186 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { |
2999 UNIMPLEMENTED(); | 3187 UNIMPLEMENTED(); |
3000 return NULL; | 3188 return NULL; |
3001 } | 3189 } |
3002 | 3190 |
3003 | 3191 |
3004 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3192 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3005 UNIMPLEMENTED(); | 3193 UNIMPLEMENTED(); |
3006 } | 3194 } |
3007 | 3195 |
3008 | 3196 |
3009 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3197 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { |
3010 UNIMPLEMENTED(); | 3198 UNIMPLEMENTED(); |
3011 return NULL; | 3199 return NULL; |
3012 } | 3200 } |
3013 | 3201 |
3014 | 3202 |
3015 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3203 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3016 UNIMPLEMENTED(); | 3204 UNIMPLEMENTED(); |
3017 } | 3205 } |
3018 | 3206 |
3019 | 3207 |
3020 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { | 3208 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { |
3021 UNIMPLEMENTED(); | 3209 UNIMPLEMENTED(); |
3022 return NULL; | 3210 return NULL; |
3023 } | 3211 } |
3024 | 3212 |
3025 | 3213 |
3026 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3214 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3027 UNIMPLEMENTED(); | 3215 UNIMPLEMENTED(); |
3028 } | 3216 } |
3029 | 3217 |
3030 | 3218 |
3031 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { | 3219 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { |
3032 UNIMPLEMENTED(); | 3220 UNIMPLEMENTED(); |
3033 return NULL; | 3221 return NULL; |
3034 } | 3222 } |
3035 | 3223 |
3036 | 3224 |
3037 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3225 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3038 UNIMPLEMENTED(); | 3226 UNIMPLEMENTED(); |
3039 } | 3227 } |
3040 | 3228 |
3041 | 3229 |
3042 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3230 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { |
3043 UNIMPLEMENTED(); | 3231 UNIMPLEMENTED(); |
3044 return NULL; | 3232 return NULL; |
3045 } | 3233 } |
3046 | 3234 |
3047 | 3235 |
3048 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3236 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3049 UNIMPLEMENTED(); | 3237 UNIMPLEMENTED(); |
3050 } | 3238 } |
3051 | 3239 |
3052 | 3240 |
3053 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { | 3241 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { |
3054 UNIMPLEMENTED(); | 3242 UNIMPLEMENTED(); |
3055 return NULL; | 3243 return NULL; |
3056 } | 3244 } |
3057 | 3245 |
3058 | 3246 |
3059 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3247 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3060 UNIMPLEMENTED(); | 3248 UNIMPLEMENTED(); |
3061 } | 3249 } |
3062 | 3250 |
3063 | 3251 |
3064 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { | 3252 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
3065 if ((kind() == MethodRecognizer::kMathSin) || | 3253 if ((kind() == MethodRecognizer::kMathSin) || |
3066 (kind() == MethodRecognizer::kMathCos)) { | 3254 (kind() == MethodRecognizer::kMathCos)) { |
3067 const intptr_t kNumInputs = 1; | 3255 const intptr_t kNumInputs = 1; |
3068 const intptr_t kNumTemps = 0; | 3256 const intptr_t kNumTemps = 0; |
3069 LocationSummary* summary = | 3257 LocationSummary* summary = |
3070 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
3071 summary->set_in(0, Location::FpuRegisterLocation(D6)); | 3259 summary->set_in(0, Location::FpuRegisterLocation(D6)); |
3072 summary->set_out(Location::FpuRegisterLocation(D0)); | 3260 summary->set_out(Location::FpuRegisterLocation(D0)); |
3073 return summary; | 3261 return summary; |
3074 } | 3262 } |
3075 const intptr_t kNumInputs = 1; | 3263 const intptr_t kNumInputs = 1; |
3076 const intptr_t kNumTemps = 0; | 3264 const intptr_t kNumTemps = 0; |
3077 LocationSummary* summary = | 3265 LocationSummary* summary = |
3078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3266 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3079 summary->set_in(0, Location::RequiresFpuRegister()); | 3267 summary->set_in(0, Location::RequiresFpuRegister()); |
3080 summary->set_out(Location::RequiresFpuRegister()); | 3268 summary->set_out(Location::RequiresFpuRegister()); |
3081 return summary; | 3269 return summary; |
3082 } | 3270 } |
3083 | 3271 |
3084 | 3272 |
3085 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3273 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3086 if (kind() == MethodRecognizer::kMathSqrt) { | 3274 if (kind() == MethodRecognizer::kMathSqrt) { |
3087 __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); | 3275 __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); |
3088 } else { | 3276 } else { |
3089 __ CallRuntime(TargetFunction(), InputCount()); | 3277 __ CallRuntime(TargetFunction(), InputCount()); |
3090 } | 3278 } |
3091 } | 3279 } |
3092 | 3280 |
3093 | 3281 |
3094 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3282 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
3095 if (result_cid() == kDoubleCid) { | 3283 if (result_cid() == kDoubleCid) { |
3096 const intptr_t kNumInputs = 2; | 3284 const intptr_t kNumInputs = 2; |
3097 const intptr_t kNumTemps = 1; | 3285 const intptr_t kNumTemps = 1; |
3098 LocationSummary* summary = | 3286 LocationSummary* summary = |
3099 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3287 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3100 summary->set_in(0, Location::RequiresFpuRegister()); | 3288 summary->set_in(0, Location::RequiresFpuRegister()); |
3101 summary->set_in(1, Location::RequiresFpuRegister()); | 3289 summary->set_in(1, Location::RequiresFpuRegister()); |
3102 // Reuse the left register so that code can be made shorter. | 3290 // Reuse the left register so that code can be made shorter. |
3103 summary->set_out(Location::SameAsFirstInput()); | 3291 summary->set_out(Location::SameAsFirstInput()); |
3104 summary->set_temp(0, Location::RequiresRegister()); | 3292 summary->set_temp(0, Location::RequiresRegister()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3175 if (is_min) { | 3363 if (is_min) { |
3176 __ BranchSignedLessEqual(left, right, &done); | 3364 __ BranchSignedLessEqual(left, right, &done); |
3177 } else { | 3365 } else { |
3178 __ BranchSignedGreaterEqual(left, right, &done); | 3366 __ BranchSignedGreaterEqual(left, right, &done); |
3179 } | 3367 } |
3180 __ mov(result, right); | 3368 __ mov(result, right); |
3181 __ Bind(&done); | 3369 __ Bind(&done); |
3182 } | 3370 } |
3183 | 3371 |
3184 | 3372 |
3185 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3373 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { |
3186 const intptr_t kNumInputs = 1; | 3374 const intptr_t kNumInputs = 1; |
3187 const intptr_t kNumTemps = 0; | 3375 const intptr_t kNumTemps = 0; |
3188 LocationSummary* summary = | 3376 LocationSummary* summary = |
3189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3190 summary->set_in(0, Location::RequiresRegister()); | 3378 summary->set_in(0, Location::RequiresRegister()); |
3191 // We make use of 3-operand instructions by not requiring result register | 3379 // We make use of 3-operand instructions by not requiring result register |
3192 // to be identical to first input register as on Intel. | 3380 // to be identical to first input register as on Intel. |
3193 summary->set_out(Location::RequiresRegister()); | 3381 summary->set_out(Location::RequiresRegister()); |
3194 return summary; | 3382 return summary; |
3195 } | 3383 } |
(...skipping 13 matching lines...) Expand all Loading... |
3209 case Token::kBIT_NOT: | 3397 case Token::kBIT_NOT: |
3210 __ nor(result, value, ZR); | 3398 __ nor(result, value, ZR); |
3211 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag. | 3399 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag. |
3212 break; | 3400 break; |
3213 default: | 3401 default: |
3214 UNREACHABLE(); | 3402 UNREACHABLE(); |
3215 } | 3403 } |
3216 } | 3404 } |
3217 | 3405 |
3218 | 3406 |
3219 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { | 3407 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
3220 const intptr_t kNumInputs = 1; | 3408 const intptr_t kNumInputs = 1; |
3221 const intptr_t kNumTemps = 1; | 3409 const intptr_t kNumTemps = 1; |
3222 LocationSummary* summary = | 3410 LocationSummary* summary = |
3223 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3411 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3224 summary->set_in(0, Location::RequiresFpuRegister()); | 3412 summary->set_in(0, Location::RequiresFpuRegister()); |
3225 summary->set_out(Location::RequiresFpuRegister()); | 3413 summary->set_out(Location::RequiresFpuRegister()); |
3226 summary->set_temp(0, Location::RequiresFpuRegister()); | 3414 summary->set_temp(0, Location::RequiresFpuRegister()); |
3227 return summary; | 3415 return summary; |
3228 } | 3416 } |
3229 | 3417 |
3230 | 3418 |
3231 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3419 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3232 // TODO(zra): Implement vneg. | 3420 // TODO(zra): Implement vneg. |
3233 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1)); | 3421 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1)); |
3234 __ LoadObject(TMP, minus_one); | 3422 __ LoadObject(TMP, minus_one); |
3235 FpuRegister result = locs()->out().fpu_reg(); | 3423 FpuRegister result = locs()->out().fpu_reg(); |
3236 FpuRegister value = locs()->in(0).fpu_reg(); | 3424 FpuRegister value = locs()->in(0).fpu_reg(); |
3237 FpuRegister temp_fp = locs()->temp(0).fpu_reg(); | 3425 FpuRegister temp_fp = locs()->temp(0).fpu_reg(); |
3238 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag); | 3426 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag); |
3239 __ muld(result, value, temp_fp); | 3427 __ muld(result, value, temp_fp); |
3240 } | 3428 } |
3241 | 3429 |
3242 | 3430 |
3243 | 3431 |
3244 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 3432 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { |
3245 const intptr_t kNumInputs = 1; | 3433 const intptr_t kNumInputs = 1; |
3246 const intptr_t kNumTemps = 0; | 3434 const intptr_t kNumTemps = 0; |
3247 LocationSummary* result = | 3435 LocationSummary* result = |
3248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3436 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3249 result->set_in(0, Location::WritableRegister()); | 3437 result->set_in(0, Location::WritableRegister()); |
3250 result->set_out(Location::RequiresFpuRegister()); | 3438 result->set_out(Location::RequiresFpuRegister()); |
3251 return result; | 3439 return result; |
3252 } | 3440 } |
3253 | 3441 |
3254 | 3442 |
3255 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3443 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3256 Register value = locs()->in(0).reg(); | 3444 Register value = locs()->in(0).reg(); |
3257 FpuRegister result = locs()->out().fpu_reg(); | 3445 FpuRegister result = locs()->out().fpu_reg(); |
3258 __ SmiUntag(value); | 3446 __ SmiUntag(value); |
3259 __ mtc1(value, STMP1); | 3447 __ mtc1(value, STMP1); |
3260 __ cvtdw(result, STMP1); | 3448 __ cvtdw(result, STMP1); |
3261 } | 3449 } |
3262 | 3450 |
3263 | 3451 |
3264 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 3452 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { |
3265 const intptr_t kNumInputs = 1; | 3453 const intptr_t kNumInputs = 1; |
3266 const intptr_t kNumTemps = 0; | 3454 const intptr_t kNumTemps = 0; |
3267 LocationSummary* result = | 3455 LocationSummary* result = |
3268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
3269 result->set_in(0, Location::RegisterLocation(T1)); | 3457 result->set_in(0, Location::RegisterLocation(T1)); |
3270 result->set_out(Location::RegisterLocation(V0)); | 3458 result->set_out(Location::RegisterLocation(V0)); |
3271 return result; | 3459 return result; |
3272 } | 3460 } |
3273 | 3461 |
3274 | 3462 |
(...skipping 25 matching lines...) Expand all Loading... |
3300 compiler->GenerateStaticCall(deopt_id(), | 3488 compiler->GenerateStaticCall(deopt_id(), |
3301 instance_call()->token_pos(), | 3489 instance_call()->token_pos(), |
3302 target, | 3490 target, |
3303 kNumberOfArguments, | 3491 kNumberOfArguments, |
3304 Object::null_array(), // No argument names., | 3492 Object::null_array(), // No argument names., |
3305 locs()); | 3493 locs()); |
3306 __ Bind(&done); | 3494 __ Bind(&done); |
3307 } | 3495 } |
3308 | 3496 |
3309 | 3497 |
3310 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 3498 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { |
3311 const intptr_t kNumInputs = 1; | 3499 const intptr_t kNumInputs = 1; |
3312 const intptr_t kNumTemps = 0; | 3500 const intptr_t kNumTemps = 0; |
3313 LocationSummary* result = new LocationSummary( | 3501 LocationSummary* result = new LocationSummary( |
3314 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3502 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3315 result->set_in(0, Location::RequiresFpuRegister()); | 3503 result->set_in(0, Location::RequiresFpuRegister()); |
3316 result->set_out(Location::RequiresRegister()); | 3504 result->set_out(Location::RequiresRegister()); |
3317 return result; | 3505 return result; |
3318 } | 3506 } |
3319 | 3507 |
3320 | 3508 |
3321 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3509 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3322 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 3510 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
3323 Register result = locs()->out().reg(); | 3511 Register result = locs()->out().reg(); |
3324 DRegister value = locs()->in(0).fpu_reg(); | 3512 DRegister value = locs()->in(0).fpu_reg(); |
3325 __ cvtwd(STMP1, value); | 3513 __ cvtwd(STMP1, value); |
3326 __ mfc1(result, STMP1); | 3514 __ mfc1(result, STMP1); |
3327 | 3515 |
3328 // Check for overflow and that it fits into Smi. | 3516 // Check for overflow and that it fits into Smi. |
3329 __ LoadImmediate(TMP, 0xC0000000); | 3517 __ LoadImmediate(TMP, 0xC0000000); |
3330 __ subu(CMPRES1, result, TMP); | 3518 __ subu(CMPRES1, result, TMP); |
3331 __ bltz(CMPRES1, deopt); | 3519 __ bltz(CMPRES1, deopt); |
3332 __ SmiTag(result); | 3520 __ SmiTag(result); |
3333 } | 3521 } |
3334 | 3522 |
3335 | 3523 |
3336 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 3524 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { |
3337 UNIMPLEMENTED(); | 3525 UNIMPLEMENTED(); |
3338 return NULL; | 3526 return NULL; |
3339 } | 3527 } |
3340 | 3528 |
3341 | 3529 |
3342 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3530 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3343 UNIMPLEMENTED(); | 3531 UNIMPLEMENTED(); |
3344 } | 3532 } |
3345 | 3533 |
3346 | 3534 |
3347 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 3535 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { |
3348 // Calling convetion on MIPS uses D6 and D7 to pass the first two | 3536 // Calling convetion on MIPS uses D6 and D7 to pass the first two |
3349 // double arguments. | 3537 // double arguments. |
3350 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 3538 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
3351 const intptr_t kNumTemps = 0; | 3539 const intptr_t kNumTemps = 0; |
3352 LocationSummary* result = | 3540 LocationSummary* result = |
3353 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 3541 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
3354 result->set_in(0, Location::FpuRegisterLocation(D6)); | 3542 result->set_in(0, Location::FpuRegisterLocation(D6)); |
3355 if (InputCount() == 2) { | 3543 if (InputCount() == 2) { |
3356 result->set_in(1, Location::FpuRegisterLocation(D7)); | 3544 result->set_in(1, Location::FpuRegisterLocation(D7)); |
3357 } | 3545 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3399 __ movd(result, base); // base is NaN, return NaN. | 3587 __ movd(result, base); // base is NaN, return NaN. |
3400 __ b(&skip_call); | 3588 __ b(&skip_call); |
3401 } | 3589 } |
3402 __ Bind(&do_call); | 3590 __ Bind(&do_call); |
3403 // double values are passed and returned in vfp registers. | 3591 // double values are passed and returned in vfp registers. |
3404 __ CallRuntime(TargetFunction(), InputCount()); | 3592 __ CallRuntime(TargetFunction(), InputCount()); |
3405 __ Bind(&skip_call); | 3593 __ Bind(&skip_call); |
3406 } | 3594 } |
3407 | 3595 |
3408 | 3596 |
3409 LocationSummary* MergedMathInstr::MakeLocationSummary() const { | 3597 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
3410 if (kind() == MergedMathInstr::kTruncDivMod) { | 3598 if (kind() == MergedMathInstr::kTruncDivMod) { |
3411 const intptr_t kNumInputs = 2; | 3599 const intptr_t kNumInputs = 2; |
3412 const intptr_t kNumTemps = 3; | 3600 const intptr_t kNumTemps = 3; |
3413 LocationSummary* summary = | 3601 LocationSummary* summary = |
3414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3602 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3415 summary->set_in(0, Location::RequiresRegister()); | 3603 summary->set_in(0, Location::RequiresRegister()); |
3416 summary->set_in(1, Location::RequiresRegister()); | 3604 summary->set_in(1, Location::RequiresRegister()); |
3417 summary->set_temp(0, Location::RequiresRegister()); | 3605 summary->set_temp(0, Location::RequiresRegister()); |
3418 summary->set_temp(1, Location::RequiresRegister()); // result_div. | 3606 summary->set_temp(1, Location::RequiresRegister()); // result_div. |
3419 summary->set_temp(2, Location::RequiresRegister()); // result_mod. | 3607 summary->set_temp(2, Location::RequiresRegister()); // result_mod. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3487 Address div_result_address(temp, 0); | 3675 Address div_result_address(temp, 0); |
3488 Address mod_result_address(temp, kWordSize); | 3676 Address mod_result_address(temp, kWordSize); |
3489 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div); | 3677 __ StoreIntoObjectNoBarrier(result, div_result_address, result_div); |
3490 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod); | 3678 __ StoreIntoObjectNoBarrier(result, mod_result_address, result_mod); |
3491 return; | 3679 return; |
3492 } | 3680 } |
3493 UNIMPLEMENTED(); | 3681 UNIMPLEMENTED(); |
3494 } | 3682 } |
3495 | 3683 |
3496 | 3684 |
3497 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 3685 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 3686 bool opt) const { |
3498 return MakeCallSummary(); | 3687 return MakeCallSummary(); |
3499 } | 3688 } |
3500 | 3689 |
3501 | 3690 |
3502 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3691 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3503 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3692 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3504 kDeoptPolymorphicInstanceCallTestFail); | 3693 kDeoptPolymorphicInstanceCallTestFail); |
3505 __ TraceSimMsg("PolymorphicInstanceCallInstr"); | 3694 __ TraceSimMsg("PolymorphicInstanceCallInstr"); |
3506 if (ic_data().NumberOfChecks() == 0) { | 3695 if (ic_data().NumberOfChecks() == 0) { |
3507 __ b(deopt); | 3696 __ b(deopt); |
(...skipping 22 matching lines...) Expand all Loading... |
3530 T2, // Class id register. | 3719 T2, // Class id register. |
3531 instance_call()->ArgumentCount(), | 3720 instance_call()->ArgumentCount(), |
3532 instance_call()->argument_names(), | 3721 instance_call()->argument_names(), |
3533 deopt, | 3722 deopt, |
3534 deopt_id(), | 3723 deopt_id(), |
3535 instance_call()->token_pos(), | 3724 instance_call()->token_pos(), |
3536 locs()); | 3725 locs()); |
3537 } | 3726 } |
3538 | 3727 |
3539 | 3728 |
3540 LocationSummary* BranchInstr::MakeLocationSummary() const { | 3729 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
3541 UNREACHABLE(); | 3730 comparison()->InitializeLocationSummary(opt); |
3542 return NULL; | 3731 // Branches don't produce a result. |
| 3732 comparison()->locs()->set_out(Location::NoLocation()); |
| 3733 return comparison()->locs(); |
3543 } | 3734 } |
3544 | 3735 |
3545 | 3736 |
3546 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3737 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3547 __ TraceSimMsg("BranchInstr"); | 3738 __ TraceSimMsg("BranchInstr"); |
3548 comparison()->EmitBranchCode(compiler, this); | 3739 comparison()->EmitBranchCode(compiler, this); |
3549 } | 3740 } |
3550 | 3741 |
3551 | 3742 |
3552 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 3743 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
3553 const intptr_t kNumInputs = 1; | 3744 const intptr_t kNumInputs = 1; |
3554 const intptr_t kNumTemps = 0; | 3745 const intptr_t kNumTemps = 0; |
3555 LocationSummary* summary = | 3746 LocationSummary* summary = |
3556 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3747 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3557 summary->set_in(0, Location::RequiresRegister()); | 3748 summary->set_in(0, Location::RequiresRegister()); |
3558 if (!IsNullCheck()) { | 3749 if (!IsNullCheck()) { |
3559 summary->AddTemp(Location::RequiresRegister()); | 3750 summary->AddTemp(Location::RequiresRegister()); |
3560 } | 3751 } |
3561 return summary; | 3752 return summary; |
3562 } | 3753 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3596 if (i == (num_checks - 1)) { | 3787 if (i == (num_checks - 1)) { |
3597 __ bne(CMPRES1, ZR, deopt); | 3788 __ bne(CMPRES1, ZR, deopt); |
3598 } else { | 3789 } else { |
3599 __ beq(CMPRES1, ZR, &is_ok); | 3790 __ beq(CMPRES1, ZR, &is_ok); |
3600 } | 3791 } |
3601 } | 3792 } |
3602 __ Bind(&is_ok); | 3793 __ Bind(&is_ok); |
3603 } | 3794 } |
3604 | 3795 |
3605 | 3796 |
3606 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 3797 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { |
3607 const intptr_t kNumInputs = 1; | 3798 const intptr_t kNumInputs = 1; |
3608 const intptr_t kNumTemps = 0; | 3799 const intptr_t kNumTemps = 0; |
3609 LocationSummary* summary = | 3800 LocationSummary* summary = |
3610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3801 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3611 summary->set_in(0, Location::RequiresRegister()); | 3802 summary->set_in(0, Location::RequiresRegister()); |
3612 return summary; | 3803 return summary; |
3613 } | 3804 } |
3614 | 3805 |
3615 | 3806 |
3616 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3807 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3617 __ TraceSimMsg("CheckSmiInstr"); | 3808 __ TraceSimMsg("CheckSmiInstr"); |
3618 Register value = locs()->in(0).reg(); | 3809 Register value = locs()->in(0).reg(); |
3619 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3810 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
3620 kDeoptCheckSmi); | 3811 kDeoptCheckSmi); |
3621 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 3812 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
3622 __ bne(CMPRES1, ZR, deopt); | 3813 __ bne(CMPRES1, ZR, deopt); |
3623 } | 3814 } |
3624 | 3815 |
3625 | 3816 |
3626 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 3817 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
3627 const intptr_t kNumInputs = 2; | 3818 const intptr_t kNumInputs = 2; |
3628 const intptr_t kNumTemps = 0; | 3819 const intptr_t kNumTemps = 0; |
3629 LocationSummary* locs = | 3820 LocationSummary* locs = |
3630 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3631 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 3822 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
3632 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 3823 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
3633 return locs; | 3824 return locs; |
3634 } | 3825 } |
3635 | 3826 |
3636 | 3827 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3668 __ BranchUnsignedGreaterEqual( | 3859 __ BranchUnsignedGreaterEqual( |
3669 index, reinterpret_cast<int32_t>(length.raw()), deopt); | 3860 index, reinterpret_cast<int32_t>(length.raw()), deopt); |
3670 } else { | 3861 } else { |
3671 Register length = length_loc.reg(); | 3862 Register length = length_loc.reg(); |
3672 Register index = index_loc.reg(); | 3863 Register index = index_loc.reg(); |
3673 __ BranchUnsignedGreaterEqual(index, length, deopt); | 3864 __ BranchUnsignedGreaterEqual(index, length, deopt); |
3674 } | 3865 } |
3675 } | 3866 } |
3676 | 3867 |
3677 | 3868 |
3678 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 3869 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
3679 UNIMPLEMENTED(); | 3870 UNIMPLEMENTED(); |
3680 return NULL; | 3871 return NULL; |
3681 } | 3872 } |
3682 | 3873 |
3683 | 3874 |
3684 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3875 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3685 UNIMPLEMENTED(); | 3876 UNIMPLEMENTED(); |
3686 } | 3877 } |
3687 | 3878 |
3688 | 3879 |
3689 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { | 3880 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const { |
3690 UNIMPLEMENTED(); | 3881 UNIMPLEMENTED(); |
3691 return NULL; | 3882 return NULL; |
3692 } | 3883 } |
3693 | 3884 |
3694 | 3885 |
3695 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3886 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3696 UNIMPLEMENTED(); | 3887 UNIMPLEMENTED(); |
3697 } | 3888 } |
3698 | 3889 |
3699 | 3890 |
3700 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 3891 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
3701 UNIMPLEMENTED(); | 3892 UNIMPLEMENTED(); |
3702 return NULL; | 3893 return NULL; |
3703 } | 3894 } |
3704 | 3895 |
3705 | 3896 |
3706 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3897 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3707 UNIMPLEMENTED(); | 3898 UNIMPLEMENTED(); |
3708 } | 3899 } |
3709 | 3900 |
3710 | 3901 |
3711 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { | 3902 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
3712 UNIMPLEMENTED(); | 3903 UNIMPLEMENTED(); |
3713 return NULL; | 3904 return NULL; |
3714 } | 3905 } |
3715 | 3906 |
3716 | 3907 |
3717 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3908 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3718 UNIMPLEMENTED(); | 3909 UNIMPLEMENTED(); |
3719 } | 3910 } |
3720 | 3911 |
3721 | 3912 |
3722 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { | 3913 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
3723 UNIMPLEMENTED(); | 3914 UNIMPLEMENTED(); |
3724 return NULL; | 3915 return NULL; |
3725 } | 3916 } |
3726 | 3917 |
3727 | 3918 |
3728 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3919 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3729 UNIMPLEMENTED(); | 3920 UNIMPLEMENTED(); |
3730 } | 3921 } |
3731 | 3922 |
3732 | 3923 |
3733 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 3924 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const { |
3734 return new LocationSummary(0, 0, LocationSummary::kCall); | 3925 return new LocationSummary(0, 0, LocationSummary::kCall); |
3735 } | 3926 } |
3736 | 3927 |
3737 | 3928 |
3738 | 3929 |
3739 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3930 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3740 compiler->GenerateRuntimeCall(token_pos(), | 3931 compiler->GenerateRuntimeCall(token_pos(), |
3741 deopt_id(), | 3932 deopt_id(), |
3742 kThrowRuntimeEntry, | 3933 kThrowRuntimeEntry, |
3743 1, | 3934 1, |
3744 locs()); | 3935 locs()); |
3745 __ break_(0); | 3936 __ break_(0); |
3746 } | 3937 } |
3747 | 3938 |
3748 | 3939 |
3749 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 3940 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const { |
3750 return new LocationSummary(0, 0, LocationSummary::kCall); | 3941 return new LocationSummary(0, 0, LocationSummary::kCall); |
3751 } | 3942 } |
3752 | 3943 |
3753 | 3944 |
3754 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3945 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3755 compiler->SetNeedsStacktrace(catch_try_index()); | 3946 compiler->SetNeedsStacktrace(catch_try_index()); |
3756 compiler->GenerateRuntimeCall(token_pos(), | 3947 compiler->GenerateRuntimeCall(token_pos(), |
3757 deopt_id(), | 3948 deopt_id(), |
3758 kReThrowRuntimeEntry, | 3949 kReThrowRuntimeEntry, |
3759 2, | 3950 2, |
(...skipping 19 matching lines...) Expand all Loading... |
3779 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 3970 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
3780 deopt_id_, | 3971 deopt_id_, |
3781 Scanner::kDummyTokenIndex); | 3972 Scanner::kDummyTokenIndex); |
3782 } | 3973 } |
3783 if (HasParallelMove()) { | 3974 if (HasParallelMove()) { |
3784 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 3975 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
3785 } | 3976 } |
3786 } | 3977 } |
3787 | 3978 |
3788 | 3979 |
3789 LocationSummary* GotoInstr::MakeLocationSummary() const { | 3980 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { |
3790 return new LocationSummary(0, 0, LocationSummary::kNoCall); | 3981 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
3791 } | 3982 } |
3792 | 3983 |
3793 | 3984 |
3794 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3985 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3795 __ TraceSimMsg("GotoInstr"); | 3986 __ TraceSimMsg("GotoInstr"); |
3796 if (!compiler->is_optimizing()) { | 3987 if (!compiler->is_optimizing()) { |
3797 compiler->EmitEdgeCounter(); | 3988 compiler->EmitEdgeCounter(); |
3798 // Add a deoptimization descriptor for deoptimizing instructions that | 3989 // Add a deoptimization descriptor for deoptimizing instructions that |
3799 // may be inserted before this instruction. On MIPS this descriptor | 3990 // may be inserted before this instruction. On MIPS this descriptor |
3800 // points after the edge counter code so that we can reuse the same | 3991 // points after the edge counter code so that we can reuse the same |
3801 // pattern matching code as at call sites, which matches backwards from | 3992 // pattern matching code as at call sites, which matches backwards from |
3802 // the end of the pattern. | 3993 // the end of the pattern. |
3803 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 3994 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
3804 GetDeoptId(), | 3995 GetDeoptId(), |
3805 Scanner::kDummyTokenIndex); | 3996 Scanner::kDummyTokenIndex); |
3806 } | 3997 } |
3807 if (HasParallelMove()) { | 3998 if (HasParallelMove()) { |
3808 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 3999 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
3809 } | 4000 } |
3810 | 4001 |
3811 // We can fall through if the successor is the next block in the list. | 4002 // We can fall through if the successor is the next block in the list. |
3812 // Otherwise, we need a jump. | 4003 // Otherwise, we need a jump. |
3813 if (!compiler->CanFallThroughTo(successor())) { | 4004 if (!compiler->CanFallThroughTo(successor())) { |
3814 __ b(compiler->GetJumpLabel(successor())); | 4005 __ b(compiler->GetJumpLabel(successor())); |
3815 } | 4006 } |
3816 } | 4007 } |
3817 | 4008 |
3818 | 4009 |
3819 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 4010 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
3820 return LocationSummary::Make(0, | 4011 return LocationSummary::Make(0, |
3821 Location::RequiresRegister(), | 4012 Location::RequiresRegister(), |
3822 LocationSummary::kNoCall); | 4013 LocationSummary::kNoCall); |
3823 } | 4014 } |
3824 | 4015 |
3825 | 4016 |
3826 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4017 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3827 __ mov(locs()->out().reg(), CTX); | 4018 __ mov(locs()->out().reg(), CTX); |
3828 } | 4019 } |
3829 | 4020 |
3830 | 4021 |
3831 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { | 4022 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
3832 const intptr_t kNumInputs = 2; | 4023 const intptr_t kNumInputs = 2; |
3833 const intptr_t kNumTemps = 0; | 4024 const intptr_t kNumTemps = 0; |
3834 if (needs_number_check()) { | 4025 if (needs_number_check()) { |
3835 LocationSummary* locs = | 4026 LocationSummary* locs = |
3836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4027 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
3837 locs->set_in(0, Location::RegisterLocation(A0)); | 4028 locs->set_in(0, Location::RegisterLocation(A0)); |
3838 locs->set_in(1, Location::RegisterLocation(A1)); | 4029 locs->set_in(1, Location::RegisterLocation(A1)); |
3839 locs->set_out(Location::RegisterLocation(A0)); | 4030 locs->set_out(Location::RegisterLocation(A0)); |
3840 return locs; | 4031 return locs; |
3841 } | 4032 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3903 BranchInstr* branch) { | 4094 BranchInstr* branch) { |
3904 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); | 4095 __ TraceSimMsg("StrictCompareInstr::EmitBranchCode"); |
3905 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4096 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
3906 | 4097 |
3907 BranchLabels labels = compiler->CreateBranchLabels(branch); | 4098 BranchLabels labels = compiler->CreateBranchLabels(branch); |
3908 Condition true_condition = EmitComparisonCode(compiler, labels); | 4099 Condition true_condition = EmitComparisonCode(compiler, labels); |
3909 EmitBranchOnCondition(compiler, true_condition, labels); | 4100 EmitBranchOnCondition(compiler, true_condition, labels); |
3910 } | 4101 } |
3911 | 4102 |
3912 | 4103 |
3913 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { | 4104 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
3914 return LocationSummary::Make(1, | 4105 return LocationSummary::Make(1, |
3915 Location::RequiresRegister(), | 4106 Location::RequiresRegister(), |
3916 LocationSummary::kNoCall); | 4107 LocationSummary::kNoCall); |
3917 } | 4108 } |
3918 | 4109 |
3919 | 4110 |
3920 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4111 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3921 Register value = locs()->in(0).reg(); | 4112 Register value = locs()->in(0).reg(); |
3922 Register result = locs()->out().reg(); | 4113 Register result = locs()->out().reg(); |
3923 | 4114 |
3924 __ LoadObject(result, Bool::True()); | 4115 __ LoadObject(result, Bool::True()); |
3925 __ LoadObject(TMP, Bool::False()); | 4116 __ LoadObject(TMP, Bool::False()); |
3926 __ subu(CMPRES1, value, result); | 4117 __ subu(CMPRES1, value, result); |
3927 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. | 4118 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. |
3928 } | 4119 } |
3929 | 4120 |
3930 | 4121 |
3931 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 4122 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const { |
3932 const intptr_t kNumInputs = 2; | 4123 const intptr_t kNumInputs = 2; |
3933 const intptr_t kNumTemps = 0; | 4124 const intptr_t kNumTemps = 0; |
3934 LocationSummary* locs = | 4125 LocationSummary* locs = |
3935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3936 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 4127 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
3937 : Location::RequiresRegister()); | 4128 : Location::RequiresRegister()); |
3938 locs->set_in(1, Location::RequiresRegister()); | 4129 locs->set_in(1, Location::RequiresRegister()); |
3939 return locs; | 4130 return locs; |
3940 } | 4131 } |
3941 | 4132 |
3942 | 4133 |
3943 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4134 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3944 Register value_reg = locs()->in(0).reg(); | 4135 Register value_reg = locs()->in(0).reg(); |
3945 Register dest_reg = locs()->in(1).reg(); | 4136 Register dest_reg = locs()->in(1).reg(); |
3946 | 4137 |
3947 if (value()->NeedsStoreBuffer()) { | 4138 if (value()->NeedsStoreBuffer()) { |
3948 __ StoreIntoObject(dest_reg, | 4139 __ StoreIntoObject(dest_reg, |
3949 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4140 FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
3950 } else { | 4141 } else { |
3951 __ StoreIntoObjectNoBarrier(dest_reg, | 4142 __ StoreIntoObjectNoBarrier(dest_reg, |
3952 FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4143 FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
3953 } | 4144 } |
3954 } | 4145 } |
3955 | 4146 |
3956 | 4147 |
3957 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 4148 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
3958 return MakeCallSummary(); | 4149 return MakeCallSummary(); |
3959 } | 4150 } |
3960 | 4151 |
3961 | 4152 |
3962 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4153 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3963 __ TraceSimMsg("AllocateObjectInstr"); | 4154 __ TraceSimMsg("AllocateObjectInstr"); |
3964 __ Comment("AllocateObjectInstr"); | 4155 __ Comment("AllocateObjectInstr"); |
3965 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 4156 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
3966 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 4157 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
3967 compiler->GenerateCall(token_pos(), | 4158 compiler->GenerateCall(token_pos(), |
3968 &label, | 4159 &label, |
3969 PcDescriptors::kOther, | 4160 PcDescriptors::kOther, |
3970 locs()); | 4161 locs()); |
3971 __ Drop(ArgumentCount()); // Discard arguments. | 4162 __ Drop(ArgumentCount()); // Discard arguments. |
3972 } | 4163 } |
3973 | 4164 |
3974 | 4165 |
3975 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { | 4166 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const { |
3976 return MakeCallSummary(); | 4167 return MakeCallSummary(); |
3977 } | 4168 } |
3978 | 4169 |
3979 | 4170 |
3980 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4171 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3981 __ Comment("CreateClosureInstr"); | 4172 __ Comment("CreateClosureInstr"); |
3982 const Function& closure_function = function(); | 4173 const Function& closure_function = function(); |
3983 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); | 4174 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); |
3984 const Code& stub = Code::Handle( | 4175 const Code& stub = Code::Handle( |
3985 StubCode::GetAllocationStubForClosure(closure_function)); | 4176 StubCode::GetAllocationStubForClosure(closure_function)); |
3986 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 4177 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
3987 compiler->GenerateCall(token_pos(), | 4178 compiler->GenerateCall(token_pos(), |
3988 &label, | 4179 &label, |
3989 PcDescriptors::kOther, | 4180 PcDescriptors::kOther, |
3990 locs()); | 4181 locs()); |
3991 __ Drop(2); // Discard type arguments and receiver. | 4182 __ Drop(2); // Discard type arguments and receiver. |
3992 } | 4183 } |
3993 | 4184 |
3994 } // namespace dart | 4185 } // namespace dart |
3995 | 4186 |
3996 #endif // defined TARGET_ARCH_MIPS | 4187 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |