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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 R0. | 29 // on the stack and return the result in a fixed register R0. |
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(R0)); | 32 result->set_out(Location::RegisterLocation(R0)); |
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 if (compiler->is_optimizing()) { | 50 if (compiler->is_optimizing()) { |
51 Location value = locs()->in(0); | 51 Location value = locs()->in(0); |
52 if (value.IsRegister()) { | 52 if (value.IsRegister()) { |
53 __ Push(value.reg()); | 53 __ Push(value.reg()); |
54 } else if (value.IsConstant()) { | 54 } else if (value.IsConstant()) { |
55 __ PushObject(value.constant()); | 55 __ PushObject(value.constant()); |
56 } else { | 56 } else { |
57 ASSERT(value.IsStackSlot()); | 57 ASSERT(value.IsStackSlot()); |
58 const intptr_t value_offset = value.ToStackSlotOffset(); | 58 const intptr_t value_offset = value.ToStackSlotOffset(); |
59 __ LoadFromOffset(kWord, IP, FP, value_offset); | 59 __ LoadFromOffset(kWord, IP, FP, value_offset); |
60 __ Push(IP); | 60 __ Push(IP); |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 | 65 |
66 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 66 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { |
67 const intptr_t kNumInputs = 1; | 67 const intptr_t kNumInputs = 1; |
68 const intptr_t kNumTemps = 0; | 68 const intptr_t kNumTemps = 0; |
69 LocationSummary* locs = | 69 LocationSummary* locs = |
70 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 70 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
71 locs->set_in(0, Location::RegisterLocation(R0)); | 71 locs->set_in(0, Location::RegisterLocation(R0)); |
72 return locs; | 72 return locs; |
73 } | 73 } |
74 | 74 |
75 | 75 |
76 // Attempt optimized compilation at return instruction instead of at the entry. | 76 // Attempt optimized compilation at return instruction instead of at the entry. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 // Detect pattern when one value is zero and another is a power of 2. | 131 // Detect pattern when one value is zero and another is a power of 2. |
132 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 132 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
133 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 133 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
134 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 134 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
135 } | 135 } |
136 | 136 |
137 | 137 |
138 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 138 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { |
139 return comparison()->MakeLocationSummary(); | 139 comparison()->InitializeLocationSummary(opt); |
| 140 return comparison()->locs(); |
140 } | 141 } |
141 | 142 |
142 | 143 |
143 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 144 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
144 const Register result = locs()->out().reg(); | 145 const Register result = locs()->out().reg(); |
145 | 146 |
146 Location left = locs()->in(0); | 147 Location left = locs()->in(0); |
147 Location right = locs()->in(1); | 148 Location right = locs()->in(1); |
148 ASSERT(!left.IsConstant() || !right.IsConstant()); | 149 ASSERT(!left.IsConstant() || !right.IsConstant()); |
149 | 150 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 const int32_t val = | 187 const int32_t val = |
187 Smi::RawValue(true_value) - Smi::RawValue(false_value); | 188 Smi::RawValue(true_value) - Smi::RawValue(false_value); |
188 __ AndImmediate(result, result, val); | 189 __ AndImmediate(result, result, val); |
189 if (false_value != 0) { | 190 if (false_value != 0) { |
190 __ AddImmediate(result, Smi::RawValue(false_value)); | 191 __ AddImmediate(result, Smi::RawValue(false_value)); |
191 } | 192 } |
192 } | 193 } |
193 } | 194 } |
194 | 195 |
195 | 196 |
196 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 197 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
197 const intptr_t kNumInputs = 0; | 198 const intptr_t kNumInputs = 0; |
198 const intptr_t kNumTemps = 1; | 199 const intptr_t kNumTemps = 1; |
199 LocationSummary* result = | 200 LocationSummary* result = |
200 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 201 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
201 result->set_out(Location::RegisterLocation(R0)); | 202 result->set_out(Location::RegisterLocation(R0)); |
202 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. | 203 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. |
203 return result; | 204 return result; |
204 } | 205 } |
205 | 206 |
206 | 207 |
207 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 208 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
208 // The arguments to the stub include the closure, as does the arguments | 209 // The arguments to the stub include the closure, as does the arguments |
209 // descriptor. | 210 // descriptor. |
210 Register temp_reg = locs()->temp(0).reg(); | 211 Register temp_reg = locs()->temp(0).reg(); |
211 int argument_count = ArgumentCount(); | 212 int argument_count = ArgumentCount(); |
212 const Array& arguments_descriptor = | 213 const Array& arguments_descriptor = |
213 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 214 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
214 argument_names())); | 215 argument_names())); |
215 __ LoadObject(temp_reg, arguments_descriptor); | 216 __ LoadObject(temp_reg, arguments_descriptor); |
216 ASSERT(temp_reg == R4); | 217 ASSERT(temp_reg == R4); |
217 compiler->GenerateDartCall(deopt_id(), | 218 compiler->GenerateDartCall(deopt_id(), |
218 token_pos(), | 219 token_pos(), |
219 &StubCode::CallClosureFunctionLabel(), | 220 &StubCode::CallClosureFunctionLabel(), |
220 PcDescriptors::kClosureCall, | 221 PcDescriptors::kClosureCall, |
221 locs()); | 222 locs()); |
222 __ Drop(argument_count); | 223 __ Drop(argument_count); |
223 } | 224 } |
224 | 225 |
225 | 226 |
226 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 227 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
227 return LocationSummary::Make(0, | 228 return LocationSummary::Make(0, |
228 Location::RequiresRegister(), | 229 Location::RequiresRegister(), |
229 LocationSummary::kNoCall); | 230 LocationSummary::kNoCall); |
230 } | 231 } |
231 | 232 |
232 | 233 |
233 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 234 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
234 Register result = locs()->out().reg(); | 235 Register result = locs()->out().reg(); |
235 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); | 236 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); |
236 } | 237 } |
237 | 238 |
238 | 239 |
239 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 240 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { |
240 return LocationSummary::Make(1, | 241 return LocationSummary::Make(1, |
241 Location::SameAsFirstInput(), | 242 Location::SameAsFirstInput(), |
242 LocationSummary::kNoCall); | 243 LocationSummary::kNoCall); |
243 } | 244 } |
244 | 245 |
245 | 246 |
246 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 247 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
247 Register value = locs()->in(0).reg(); | 248 Register value = locs()->in(0).reg(); |
248 Register result = locs()->out().reg(); | 249 Register result = locs()->out().reg(); |
249 ASSERT(result == value); // Assert that register assignment is correct. | 250 ASSERT(result == value); // Assert that register assignment is correct. |
250 __ str(value, Address(FP, local().index() * kWordSize)); | 251 __ str(value, Address(FP, local().index() * kWordSize)); |
251 } | 252 } |
252 | 253 |
253 | 254 |
254 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 255 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { |
255 return LocationSummary::Make(0, | 256 return LocationSummary::Make(0, |
256 Location::RequiresRegister(), | 257 Location::RequiresRegister(), |
257 LocationSummary::kNoCall); | 258 LocationSummary::kNoCall); |
258 } | 259 } |
259 | 260 |
260 | 261 |
261 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 262 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
262 // The register allocator drops constant definitions that have no uses. | 263 // The register allocator drops constant definitions that have no uses. |
263 if (!locs()->out().IsInvalid()) { | 264 if (!locs()->out().IsInvalid()) { |
264 Register result = locs()->out().reg(); | 265 Register result = locs()->out().reg(); |
265 __ LoadObject(result, value()); | 266 __ LoadObject(result, value()); |
266 } | 267 } |
267 } | 268 } |
268 | 269 |
269 | 270 |
270 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 271 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { |
271 const intptr_t kNumInputs = 3; | 272 const intptr_t kNumInputs = 3; |
272 const intptr_t kNumTemps = 0; | 273 const intptr_t kNumTemps = 0; |
273 LocationSummary* summary = | 274 LocationSummary* summary = |
274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
275 summary->set_in(0, Location::RegisterLocation(R0)); // Value. | 276 summary->set_in(0, Location::RegisterLocation(R0)); // Value. |
276 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. | 277 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. |
277 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. | 278 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. |
278 summary->set_out(Location::RegisterLocation(R0)); | 279 summary->set_out(Location::RegisterLocation(R0)); |
279 return summary; | 280 return summary; |
280 } | 281 } |
281 | 282 |
282 | 283 |
283 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 284 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { |
284 const intptr_t kNumInputs = 1; | 285 const intptr_t kNumInputs = 1; |
285 const intptr_t kNumTemps = 0; | 286 const intptr_t kNumTemps = 0; |
286 LocationSummary* locs = | 287 LocationSummary* locs = |
287 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
288 locs->set_in(0, Location::RegisterLocation(R0)); | 289 locs->set_in(0, Location::RegisterLocation(R0)); |
289 locs->set_out(Location::RegisterLocation(R0)); | 290 locs->set_out(Location::RegisterLocation(R0)); |
290 return locs; | 291 return locs; |
291 } | 292 } |
292 | 293 |
293 | 294 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 case Token::kGT: return GT; | 335 case Token::kGT: return GT; |
335 case Token::kLTE: return LE; | 336 case Token::kLTE: return LE; |
336 case Token::kGTE: return GE; | 337 case Token::kGTE: return GE; |
337 default: | 338 default: |
338 UNREACHABLE(); | 339 UNREACHABLE(); |
339 return VS; | 340 return VS; |
340 } | 341 } |
341 } | 342 } |
342 | 343 |
343 | 344 |
344 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 345 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
345 const intptr_t kNumInputs = 2; | 346 const intptr_t kNumInputs = 2; |
346 if (operation_cid() == kMintCid) { | 347 if (operation_cid() == kMintCid) { |
347 const intptr_t kNumTemps = 1; | 348 const intptr_t kNumTemps = 1; |
348 LocationSummary* locs = | 349 LocationSummary* locs = |
349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
350 locs->set_in(0, Location::RequiresFpuRegister()); | 351 locs->set_in(0, Location::RequiresFpuRegister()); |
351 locs->set_in(1, Location::RequiresFpuRegister()); | 352 locs->set_in(1, Location::RequiresFpuRegister()); |
352 locs->set_temp(0, Location::RequiresRegister()); | 353 locs->set_temp(0, Location::RequiresRegister()); |
353 locs->set_out(Location::RequiresRegister()); | 354 locs->set_out(Location::RequiresRegister()); |
354 return locs; | 355 return locs; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 | 532 |
532 if (operation_cid() == kDoubleCid) { | 533 if (operation_cid() == kDoubleCid) { |
533 Label* nan_result = (true_condition == NE) ? | 534 Label* nan_result = (true_condition == NE) ? |
534 labels.true_label : labels.false_label; | 535 labels.true_label : labels.false_label; |
535 __ b(nan_result, VS); | 536 __ b(nan_result, VS); |
536 } | 537 } |
537 EmitBranchOnCondition(compiler, true_condition, labels); | 538 EmitBranchOnCondition(compiler, true_condition, labels); |
538 } | 539 } |
539 | 540 |
540 | 541 |
541 LocationSummary* TestSmiInstr::MakeLocationSummary() const { | 542 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const { |
542 const intptr_t kNumInputs = 2; | 543 const intptr_t kNumInputs = 2; |
543 const intptr_t kNumTemps = 0; | 544 const intptr_t kNumTemps = 0; |
544 LocationSummary* locs = | 545 LocationSummary* locs = |
545 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 546 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
546 locs->set_in(0, Location::RequiresRegister()); | 547 locs->set_in(0, Location::RequiresRegister()); |
547 // Only one input can be a constant operand. The case of two constant | 548 // Only one input can be a constant operand. The case of two constant |
548 // operands should be handled by constant propagation. | 549 // operands should be handled by constant propagation. |
549 locs->set_in(1, Location::RegisterOrConstant(right())); | 550 locs->set_in(1, Location::RegisterOrConstant(right())); |
550 return locs; | 551 return locs; |
551 } | 552 } |
(...skipping 22 matching lines...) Expand all Loading... |
574 | 575 |
575 | 576 |
576 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 577 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
577 BranchInstr* branch) { | 578 BranchInstr* branch) { |
578 BranchLabels labels = compiler->CreateBranchLabels(branch); | 579 BranchLabels labels = compiler->CreateBranchLabels(branch); |
579 Condition true_condition = EmitComparisonCode(compiler, labels); | 580 Condition true_condition = EmitComparisonCode(compiler, labels); |
580 EmitBranchOnCondition(compiler, true_condition, labels); | 581 EmitBranchOnCondition(compiler, true_condition, labels); |
581 } | 582 } |
582 | 583 |
583 | 584 |
584 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 585 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
585 const intptr_t kNumInputs = 2; | 586 const intptr_t kNumInputs = 2; |
586 const intptr_t kNumTemps = 0; | 587 const intptr_t kNumTemps = 0; |
587 if (operation_cid() == kMintCid) { | 588 if (operation_cid() == kMintCid) { |
588 const intptr_t kNumTemps = 2; | 589 const intptr_t kNumTemps = 2; |
589 LocationSummary* locs = | 590 LocationSummary* locs = |
590 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 591 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
591 locs->set_in(0, Location::RequiresFpuRegister()); | 592 locs->set_in(0, Location::RequiresFpuRegister()); |
592 locs->set_in(1, Location::RequiresFpuRegister()); | 593 locs->set_in(1, Location::RequiresFpuRegister()); |
593 locs->set_temp(0, Location::RequiresRegister()); | 594 locs->set_temp(0, Location::RequiresRegister()); |
594 locs->set_temp(1, Location::RequiresRegister()); | 595 locs->set_temp(1, Location::RequiresRegister()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 | 658 |
658 if (operation_cid() == kDoubleCid) { | 659 if (operation_cid() == kDoubleCid) { |
659 Label* nan_result = (true_condition == NE) ? | 660 Label* nan_result = (true_condition == NE) ? |
660 labels.true_label : labels.false_label; | 661 labels.true_label : labels.false_label; |
661 __ b(nan_result, VS); | 662 __ b(nan_result, VS); |
662 } | 663 } |
663 EmitBranchOnCondition(compiler, true_condition, labels); | 664 EmitBranchOnCondition(compiler, true_condition, labels); |
664 } | 665 } |
665 | 666 |
666 | 667 |
667 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 668 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { |
668 const intptr_t kNumInputs = 0; | 669 const intptr_t kNumInputs = 0; |
669 const intptr_t kNumTemps = 3; | 670 const intptr_t kNumTemps = 3; |
670 LocationSummary* locs = | 671 LocationSummary* locs = |
671 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 672 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
672 locs->set_temp(0, Location::RegisterLocation(R1)); | 673 locs->set_temp(0, Location::RegisterLocation(R1)); |
673 locs->set_temp(1, Location::RegisterLocation(R2)); | 674 locs->set_temp(1, Location::RegisterLocation(R2)); |
674 locs->set_temp(2, Location::RegisterLocation(R5)); | 675 locs->set_temp(2, Location::RegisterLocation(R5)); |
675 locs->set_out(Location::RegisterLocation(R0)); | 676 locs->set_out(Location::RegisterLocation(R0)); |
676 return locs; | 677 return locs; |
677 } | 678 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 __ LoadImmediate(R5, entry); | 713 __ LoadImmediate(R5, entry); |
713 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function())); | 714 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function())); |
714 compiler->GenerateCall(token_pos(), | 715 compiler->GenerateCall(token_pos(), |
715 stub_entry, | 716 stub_entry, |
716 PcDescriptors::kOther, | 717 PcDescriptors::kOther, |
717 locs()); | 718 locs()); |
718 __ Pop(result); | 719 __ Pop(result); |
719 } | 720 } |
720 | 721 |
721 | 722 |
722 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { | 723 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { |
723 const intptr_t kNumInputs = 1; | 724 const intptr_t kNumInputs = 1; |
724 // TODO(fschneider): Allow immediate operands for the char code. | 725 // TODO(fschneider): Allow immediate operands for the char code. |
725 return LocationSummary::Make(kNumInputs, | 726 return LocationSummary::Make(kNumInputs, |
726 Location::RequiresRegister(), | 727 Location::RequiresRegister(), |
727 LocationSummary::kNoCall); | 728 LocationSummary::kNoCall); |
728 } | 729 } |
729 | 730 |
730 | 731 |
731 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 732 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
732 Register char_code = locs()->in(0).reg(); | 733 Register char_code = locs()->in(0).reg(); |
733 Register result = locs()->out().reg(); | 734 Register result = locs()->out().reg(); |
734 __ LoadImmediate(result, | 735 __ LoadImmediate(result, |
735 reinterpret_cast<uword>(Symbols::PredefinedAddress())); | 736 reinterpret_cast<uword>(Symbols::PredefinedAddress())); |
736 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); | 737 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); |
737 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. | 738 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. |
738 } | 739 } |
739 | 740 |
740 | 741 |
741 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { | 742 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { |
742 const intptr_t kNumInputs = 1; | 743 const intptr_t kNumInputs = 1; |
743 const intptr_t kNumTemps = 0; | 744 const intptr_t kNumTemps = 0; |
744 LocationSummary* summary = | 745 LocationSummary* summary = |
745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 746 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
746 summary->set_in(0, Location::RegisterLocation(R0)); | 747 summary->set_in(0, Location::RegisterLocation(R0)); |
747 summary->set_out(Location::RegisterLocation(R0)); | 748 summary->set_out(Location::RegisterLocation(R0)); |
748 return summary; | 749 return summary; |
749 } | 750 } |
750 | 751 |
751 | 752 |
752 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 753 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
753 Register array = locs()->in(0).reg(); | 754 Register array = locs()->in(0).reg(); |
754 __ Push(array); | 755 __ Push(array); |
755 const int kNumberOfArguments = 1; | 756 const int kNumberOfArguments = 1; |
756 const Array& kNoArgumentNames = Object::null_array(); | 757 const Array& kNoArgumentNames = Object::null_array(); |
757 compiler->GenerateStaticCall(deopt_id(), | 758 compiler->GenerateStaticCall(deopt_id(), |
758 token_pos(), | 759 token_pos(), |
759 CallFunction(), | 760 CallFunction(), |
760 kNumberOfArguments, | 761 kNumberOfArguments, |
761 kNoArgumentNames, | 762 kNoArgumentNames, |
762 locs()); | 763 locs()); |
763 ASSERT(locs()->out().reg() == R0); | 764 ASSERT(locs()->out().reg() == R0); |
764 } | 765 } |
765 | 766 |
766 | 767 |
767 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { | 768 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
768 const intptr_t kNumInputs = 1; | 769 const intptr_t kNumInputs = 1; |
769 return LocationSummary::Make(kNumInputs, | 770 return LocationSummary::Make(kNumInputs, |
770 Location::RequiresRegister(), | 771 Location::RequiresRegister(), |
771 LocationSummary::kNoCall); | 772 LocationSummary::kNoCall); |
772 } | 773 } |
773 | 774 |
774 | 775 |
775 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 776 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
776 Register object = locs()->in(0).reg(); | 777 Register object = locs()->in(0).reg(); |
777 Register result = locs()->out().reg(); | 778 Register result = locs()->out().reg(); |
778 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); | 779 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); |
779 } | 780 } |
780 | 781 |
781 | 782 |
782 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { | 783 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { |
783 const intptr_t kNumInputs = 1; | 784 const intptr_t kNumInputs = 1; |
784 return LocationSummary::Make(kNumInputs, | 785 return LocationSummary::Make(kNumInputs, |
785 Location::RequiresRegister(), | 786 Location::RequiresRegister(), |
786 LocationSummary::kNoCall); | 787 LocationSummary::kNoCall); |
787 } | 788 } |
788 | 789 |
789 | 790 |
790 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 791 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
791 Register object = locs()->in(0).reg(); | 792 Register object = locs()->in(0).reg(); |
792 Register result = locs()->out().reg(); | 793 Register result = locs()->out().reg(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 return kUnboxedInt32x4; | 869 return kUnboxedInt32x4; |
869 case kTypedDataFloat32x4ArrayCid: | 870 case kTypedDataFloat32x4ArrayCid: |
870 return kUnboxedFloat32x4; | 871 return kUnboxedFloat32x4; |
871 default: | 872 default: |
872 UNREACHABLE(); | 873 UNREACHABLE(); |
873 return kTagged; | 874 return kTagged; |
874 } | 875 } |
875 } | 876 } |
876 | 877 |
877 | 878 |
878 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 879 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
879 const intptr_t kNumInputs = 2; | 880 const intptr_t kNumInputs = 2; |
880 const intptr_t kNumTemps = 0; | 881 const intptr_t kNumTemps = 0; |
881 LocationSummary* locs = | 882 LocationSummary* locs = |
882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 883 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
883 locs->set_in(0, Location::RequiresRegister()); | 884 locs->set_in(0, Location::RequiresRegister()); |
884 // The smi index is either untagged (element size == 1), or it is left smi | 885 // The smi index is either untagged (element size == 1), or it is left smi |
885 // tagged (for all element sizes > 1). | 886 // tagged (for all element sizes > 1). |
886 // TODO(regis): Revisit and see if the index can be immediate. | 887 // TODO(regis): Revisit and see if the index can be immediate. |
887 locs->set_in(1, Location::WritableRegister()); | 888 locs->set_in(1, Location::WritableRegister()); |
888 if ((representation() == kUnboxedDouble) || | 889 if ((representation() == kUnboxedDouble) || |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 return kUnboxedFloat32x4; | 1054 return kUnboxedFloat32x4; |
1054 case kTypedDataInt32x4ArrayCid: | 1055 case kTypedDataInt32x4ArrayCid: |
1055 return kUnboxedInt32x4; | 1056 return kUnboxedInt32x4; |
1056 default: | 1057 default: |
1057 UNREACHABLE(); | 1058 UNREACHABLE(); |
1058 return kTagged; | 1059 return kTagged; |
1059 } | 1060 } |
1060 } | 1061 } |
1061 | 1062 |
1062 | 1063 |
1063 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1064 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
1064 const intptr_t kNumInputs = 3; | 1065 const intptr_t kNumInputs = 3; |
1065 const intptr_t kNumTemps = 0; | 1066 const intptr_t kNumTemps = 0; |
1066 LocationSummary* locs = | 1067 LocationSummary* locs = |
1067 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1068 locs->set_in(0, Location::RequiresRegister()); | 1069 locs->set_in(0, Location::RequiresRegister()); |
1069 // The smi index is either untagged (element size == 1), or it is left smi | 1070 // The smi index is either untagged (element size == 1), or it is left smi |
1070 // tagged (for all element sizes > 1). | 1071 // tagged (for all element sizes > 1). |
1071 // TODO(regis): Revisit and see if the index can be immediate. | 1072 // TODO(regis): Revisit and see if the index can be immediate. |
1072 locs->set_in(1, Location::WritableRegister()); | 1073 locs->set_in(1, Location::WritableRegister()); |
1073 switch (class_id()) { | 1074 switch (class_id()) { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 __ StoreDToOffset(din0, index.reg(), 0); | 1241 __ StoreDToOffset(din0, index.reg(), 0); |
1241 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1242 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); |
1242 break; | 1243 break; |
1243 } | 1244 } |
1244 default: | 1245 default: |
1245 UNREACHABLE(); | 1246 UNREACHABLE(); |
1246 } | 1247 } |
1247 } | 1248 } |
1248 | 1249 |
1249 | 1250 |
1250 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1251 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
1251 const intptr_t kNumInputs = 1; | 1252 const intptr_t kNumInputs = 1; |
1252 LocationSummary* summary = | 1253 LocationSummary* summary = |
1253 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1254 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
1254 summary->set_in(0, Location::RequiresRegister()); | 1255 summary->set_in(0, Location::RequiresRegister()); |
1255 const bool field_has_length = field().needs_length_check(); | 1256 const bool field_has_length = field().needs_length_check(); |
1256 summary->AddTemp(Location::RequiresRegister()); | 1257 summary->AddTemp(Location::RequiresRegister()); |
1257 summary->AddTemp(Location::RequiresRegister()); | 1258 summary->AddTemp(Location::RequiresRegister()); |
1258 const bool need_field_temp_reg = | 1259 const bool need_field_temp_reg = |
1259 field_has_length || (field().guarded_cid() == kIllegalCid); | 1260 field_has_length || (field().guarded_cid() == kIllegalCid); |
1260 if (need_field_temp_reg) { | 1261 if (need_field_temp_reg) { |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1565 __ b(fail, NE); | 1566 __ b(fail, NE); |
1566 } else { | 1567 } else { |
1567 UNREACHABLE(); | 1568 UNREACHABLE(); |
1568 } | 1569 } |
1569 } | 1570 } |
1570 } | 1571 } |
1571 __ Bind(&ok); | 1572 __ Bind(&ok); |
1572 } | 1573 } |
1573 | 1574 |
1574 | 1575 |
1575 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1576 class StoreInstanceFieldSlowPath : public SlowPathCode { |
| 1577 public: |
| 1578 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) |
| 1579 : instruction_(instruction) { } |
| 1580 |
| 1581 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1582 __ Comment("StoreInstanceFieldSlowPath"); |
| 1583 __ Bind(entry_label()); |
| 1584 const Class& double_class = compiler->double_class(); |
| 1585 const Code& stub = |
| 1586 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1587 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1588 |
| 1589 LocationSummary* locs = instruction_->locs(); |
| 1590 locs->live_registers()->Remove(locs->out()); |
| 1591 |
| 1592 compiler->SaveLiveRegisters(locs); |
| 1593 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1594 &label, |
| 1595 PcDescriptors::kOther, |
| 1596 locs); |
| 1597 __ MoveRegister(locs->temp(0).reg(), R0); |
| 1598 compiler->RestoreLiveRegisters(locs); |
| 1599 |
| 1600 __ b(exit_label()); |
| 1601 } |
| 1602 |
| 1603 private: |
| 1604 StoreInstanceFieldInstr* instruction_; |
| 1605 }; |
| 1606 |
| 1607 |
| 1608 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { |
1576 const intptr_t kNumInputs = 2; | 1609 const intptr_t kNumInputs = 2; |
1577 const intptr_t kNumTemps = 0; | 1610 const intptr_t kNumTemps = 0; |
1578 LocationSummary* summary = | 1611 LocationSummary* summary = |
1579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1612 new LocationSummary(kNumInputs, kNumTemps, |
| 1613 (field().guarded_cid() == kIllegalCid) || (is_initialization_) |
| 1614 ? LocationSummary::kCallOnSlowPath |
| 1615 : LocationSummary::kNoCall); |
| 1616 |
1580 summary->set_in(0, Location::RequiresRegister()); | 1617 summary->set_in(0, Location::RequiresRegister()); |
1581 summary->set_in(1, ShouldEmitStoreBarrier() | 1618 if (IsUnboxedStore() && opt) { |
| 1619 summary->set_in(1, Location::RequiresFpuRegister()); |
| 1620 summary->AddTemp(Location::RequiresRegister()); |
| 1621 summary->AddTemp(Location::RequiresRegister()); |
| 1622 } else if (IsPotentialUnboxedStore()) { |
| 1623 summary->set_in(1, ShouldEmitStoreBarrier() |
| 1624 ? Location::WritableRegister() |
| 1625 : Location::RequiresRegister()); |
| 1626 summary->AddTemp(Location::RequiresRegister()); |
| 1627 summary->AddTemp(Location::RequiresRegister()); |
| 1628 summary->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1629 : Location::FpuRegisterLocation(Q1)); |
| 1630 } else { |
| 1631 summary->set_in(1, ShouldEmitStoreBarrier() |
1582 ? Location::WritableRegister() | 1632 ? Location::WritableRegister() |
1583 : Location::RegisterOrConstant(value())); | 1633 : Location::RegisterOrConstant(value())); |
| 1634 } |
1584 return summary; | 1635 return summary; |
1585 } | 1636 } |
1586 | 1637 |
1587 | 1638 |
1588 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1639 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1640 Label skip_store; |
| 1641 |
1589 Register instance_reg = locs()->in(0).reg(); | 1642 Register instance_reg = locs()->in(0).reg(); |
| 1643 |
| 1644 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1645 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 1646 Register temp = locs()->temp(0).reg(); |
| 1647 Register temp2 = locs()->temp(1).reg(); |
| 1648 |
| 1649 if (is_initialization_) { |
| 1650 StoreInstanceFieldSlowPath* slow_path = |
| 1651 new StoreInstanceFieldSlowPath(this); |
| 1652 compiler->AddSlowPathCode(slow_path); |
| 1653 __ TryAllocate(compiler->double_class(), |
| 1654 slow_path->entry_label(), |
| 1655 temp); |
| 1656 __ Bind(slow_path->exit_label()); |
| 1657 __ MoveRegister(temp2, temp); |
| 1658 __ StoreIntoObject(instance_reg, |
| 1659 FieldAddress(instance_reg, field().Offset()), |
| 1660 temp2); |
| 1661 } else { |
| 1662 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); |
| 1663 } |
| 1664 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1665 return; |
| 1666 } |
| 1667 |
| 1668 if (IsPotentialUnboxedStore()) { |
| 1669 Register value_reg = locs()->in(1).reg(); |
| 1670 Register temp = locs()->temp(0).reg(); |
| 1671 Register temp2 = locs()->temp(1).reg(); |
| 1672 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); |
| 1673 |
| 1674 Label store_pointer, copy_payload; |
| 1675 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1676 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1677 __ CompareImmediate(temp2, kDoubleCid); |
| 1678 __ b(&store_pointer, NE); |
| 1679 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1680 __ CompareImmediate(temp2, kNullCid); |
| 1681 __ b(&store_pointer, EQ); |
| 1682 |
| 1683 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); |
| 1684 __ CompareImmediate(temp, |
| 1685 reinterpret_cast<intptr_t>(Object::null())); |
| 1686 __ b(©_payload, NE); |
| 1687 |
| 1688 StoreInstanceFieldSlowPath* slow_path = |
| 1689 new StoreInstanceFieldSlowPath(this); |
| 1690 compiler->AddSlowPathCode(slow_path); |
| 1691 |
| 1692 if (!compiler->is_optimizing()) { |
| 1693 locs()->live_registers()->Add(locs()->in(0)); |
| 1694 locs()->live_registers()->Add(locs()->in(1)); |
| 1695 } |
| 1696 |
| 1697 __ TryAllocate(compiler->double_class(), |
| 1698 slow_path->entry_label(), |
| 1699 temp); |
| 1700 __ Bind(slow_path->exit_label()); |
| 1701 __ MoveRegister(temp2, temp); |
| 1702 __ StoreIntoObject(instance_reg, |
| 1703 FieldAddress(instance_reg, field().Offset()), |
| 1704 temp2); |
| 1705 __ Bind(©_payload); |
| 1706 __ LoadDFromOffset(fpu_temp, |
| 1707 value_reg, |
| 1708 Double::value_offset() - kHeapObjectTag); |
| 1709 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); |
| 1710 __ b(&skip_store); |
| 1711 __ Bind(&store_pointer); |
| 1712 } |
| 1713 |
1590 if (ShouldEmitStoreBarrier()) { | 1714 if (ShouldEmitStoreBarrier()) { |
1591 Register value_reg = locs()->in(1).reg(); | 1715 Register value_reg = locs()->in(1).reg(); |
1592 __ StoreIntoObject(instance_reg, | 1716 __ StoreIntoObject(instance_reg, |
1593 FieldAddress(instance_reg, field().Offset()), | 1717 FieldAddress(instance_reg, field().Offset()), |
1594 value_reg, | 1718 value_reg, |
1595 CanValueBeSmi()); | 1719 CanValueBeSmi()); |
1596 } else { | 1720 } else { |
1597 if (locs()->in(1).IsConstant()) { | 1721 if (locs()->in(1).IsConstant()) { |
1598 __ StoreIntoObjectNoBarrier( | 1722 __ StoreIntoObjectNoBarrier( |
1599 instance_reg, | 1723 instance_reg, |
1600 FieldAddress(instance_reg, field().Offset()), | 1724 FieldAddress(instance_reg, field().Offset()), |
1601 locs()->in(1).constant()); | 1725 locs()->in(1).constant()); |
1602 } else { | 1726 } else { |
1603 Register value_reg = locs()->in(1).reg(); | 1727 Register value_reg = locs()->in(1).reg(); |
1604 __ StoreIntoObjectNoBarrier(instance_reg, | 1728 __ StoreIntoObjectNoBarrier(instance_reg, |
1605 FieldAddress(instance_reg, field().Offset()), value_reg); | 1729 FieldAddress(instance_reg, field().Offset()), value_reg); |
1606 } | 1730 } |
1607 } | 1731 } |
| 1732 __ Bind(&skip_store); |
1608 } | 1733 } |
1609 | 1734 |
1610 | 1735 |
1611 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 1736 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { |
1612 const intptr_t kNumInputs = 1; | 1737 const intptr_t kNumInputs = 1; |
1613 const intptr_t kNumTemps = 0; | 1738 const intptr_t kNumTemps = 0; |
1614 LocationSummary* summary = | 1739 LocationSummary* summary = |
1615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1740 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1616 summary->set_in(0, Location::RequiresRegister()); | 1741 summary->set_in(0, Location::RequiresRegister()); |
1617 summary->set_out(Location::RequiresRegister()); | 1742 summary->set_out(Location::RequiresRegister()); |
1618 return summary; | 1743 return summary; |
1619 } | 1744 } |
1620 | 1745 |
1621 | 1746 |
1622 // When the parser is building an implicit static getter for optimization, | 1747 // When the parser is building an implicit static getter for optimization, |
1623 // it can generate a function body where deoptimization ids do not line up | 1748 // it can generate a function body where deoptimization ids do not line up |
1624 // with the unoptimized code. | 1749 // with the unoptimized code. |
1625 // | 1750 // |
1626 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. | 1751 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. |
1627 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1752 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1628 Register field = locs()->in(0).reg(); | 1753 Register field = locs()->in(0).reg(); |
1629 Register result = locs()->out().reg(); | 1754 Register result = locs()->out().reg(); |
1630 __ LoadFromOffset(kWord, result, | 1755 __ LoadFromOffset(kWord, result, |
1631 field, Field::value_offset() - kHeapObjectTag); | 1756 field, Field::value_offset() - kHeapObjectTag); |
1632 } | 1757 } |
1633 | 1758 |
1634 | 1759 |
1635 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1760 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { |
1636 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1761 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
1637 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 1762 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
1638 : Location::RequiresRegister()); | 1763 : Location::RequiresRegister()); |
1639 locs->set_temp(0, Location::RequiresRegister()); | 1764 locs->set_temp(0, Location::RequiresRegister()); |
1640 return locs; | 1765 return locs; |
1641 } | 1766 } |
1642 | 1767 |
1643 | 1768 |
1644 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1769 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1645 Register value = locs()->in(0).reg(); | 1770 Register value = locs()->in(0).reg(); |
1646 Register temp = locs()->temp(0).reg(); | 1771 Register temp = locs()->temp(0).reg(); |
1647 | 1772 |
1648 __ LoadObject(temp, field()); | 1773 __ LoadObject(temp, field()); |
1649 if (this->value()->NeedsStoreBuffer()) { | 1774 if (this->value()->NeedsStoreBuffer()) { |
1650 __ StoreIntoObject(temp, | 1775 __ StoreIntoObject(temp, |
1651 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); | 1776 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); |
1652 } else { | 1777 } else { |
1653 __ StoreIntoObjectNoBarrier( | 1778 __ StoreIntoObjectNoBarrier( |
1654 temp, FieldAddress(temp, Field::value_offset()), value); | 1779 temp, FieldAddress(temp, Field::value_offset()), value); |
1655 } | 1780 } |
1656 } | 1781 } |
1657 | 1782 |
1658 | 1783 |
1659 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1784 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { |
1660 const intptr_t kNumInputs = 3; | 1785 const intptr_t kNumInputs = 3; |
1661 const intptr_t kNumTemps = 0; | 1786 const intptr_t kNumTemps = 0; |
1662 LocationSummary* summary = | 1787 LocationSummary* summary = |
1663 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1788 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1664 summary->set_in(0, Location::RegisterLocation(R0)); | 1789 summary->set_in(0, Location::RegisterLocation(R0)); |
1665 summary->set_in(1, Location::RegisterLocation(R2)); | 1790 summary->set_in(1, Location::RegisterLocation(R2)); |
1666 summary->set_in(2, Location::RegisterLocation(R1)); | 1791 summary->set_in(2, Location::RegisterLocation(R1)); |
1667 summary->set_out(Location::RegisterLocation(R0)); | 1792 summary->set_out(Location::RegisterLocation(R0)); |
1668 return summary; | 1793 return summary; |
1669 } | 1794 } |
1670 | 1795 |
1671 | 1796 |
1672 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1797 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1673 ASSERT(locs()->in(0).reg() == R0); // Value. | 1798 ASSERT(locs()->in(0).reg() == R0); // Value. |
1674 ASSERT(locs()->in(1).reg() == R2); // Instantiator. | 1799 ASSERT(locs()->in(1).reg() == R2); // Instantiator. |
1675 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. | 1800 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. |
1676 | 1801 |
1677 compiler->GenerateInstanceOf(token_pos(), | 1802 compiler->GenerateInstanceOf(token_pos(), |
1678 deopt_id(), | 1803 deopt_id(), |
1679 type(), | 1804 type(), |
1680 negate_result(), | 1805 negate_result(), |
1681 locs()); | 1806 locs()); |
1682 ASSERT(locs()->out().reg() == R0); | 1807 ASSERT(locs()->out().reg() == R0); |
1683 } | 1808 } |
1684 | 1809 |
1685 | 1810 |
1686 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1811 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
1687 const intptr_t kNumInputs = 1; | 1812 const intptr_t kNumInputs = 1; |
1688 const intptr_t kNumTemps = 0; | 1813 const intptr_t kNumTemps = 0; |
1689 LocationSummary* locs = | 1814 LocationSummary* locs = |
1690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1815 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1691 locs->set_in(0, Location::RegisterLocation(R1)); | 1816 locs->set_in(0, Location::RegisterLocation(R1)); |
1692 locs->set_out(Location::RegisterLocation(R0)); | 1817 locs->set_out(Location::RegisterLocation(R0)); |
1693 return locs; | 1818 return locs; |
1694 } | 1819 } |
1695 | 1820 |
1696 | 1821 |
1697 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1822 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1698 // Allocate the array. R2 = length, R1 = element type. | 1823 // Allocate the array. R2 = length, R1 = element type. |
1699 ASSERT(locs()->in(0).reg() == R1); | 1824 ASSERT(locs()->in(0).reg() == R1); |
1700 __ LoadImmediate(R2, Smi::RawValue(num_elements())); | 1825 __ LoadImmediate(R2, Smi::RawValue(num_elements())); |
1701 compiler->GenerateCall(token_pos(), | 1826 compiler->GenerateCall(token_pos(), |
1702 &StubCode::AllocateArrayLabel(), | 1827 &StubCode::AllocateArrayLabel(), |
1703 PcDescriptors::kOther, | 1828 PcDescriptors::kOther, |
1704 locs()); | 1829 locs()); |
1705 ASSERT(locs()->out().reg() == R0); | 1830 ASSERT(locs()->out().reg() == R0); |
1706 } | 1831 } |
1707 | 1832 |
1708 | 1833 |
1709 LocationSummary* | 1834 LocationSummary* |
1710 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1835 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const { |
1711 return MakeCallSummary(); | 1836 return MakeCallSummary(); |
1712 } | 1837 } |
1713 | 1838 |
1714 | 1839 |
1715 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1840 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( |
1716 FlowGraphCompiler* compiler) { | 1841 FlowGraphCompiler* compiler) { |
1717 compiler->GenerateRuntimeCall(token_pos(), | 1842 compiler->GenerateRuntimeCall(token_pos(), |
1718 deopt_id(), | 1843 deopt_id(), |
1719 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1844 kAllocateObjectWithBoundsCheckRuntimeEntry, |
1720 3, | 1845 3, |
1721 locs()); | 1846 locs()); |
1722 __ Drop(3); | 1847 __ Drop(3); |
1723 ASSERT(locs()->out().reg() == R0); | 1848 ASSERT(locs()->out().reg() == R0); |
1724 __ Pop(R0); // Pop new instance. | 1849 __ Pop(R0); // Pop new instance. |
1725 } | 1850 } |
1726 | 1851 |
1727 | 1852 |
1728 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { | 1853 class BoxDoubleSlowPath : public SlowPathCode { |
1729 return LocationSummary::Make(1, | 1854 public: |
1730 Location::RequiresRegister(), | 1855 explicit BoxDoubleSlowPath(Instruction* instruction) |
1731 LocationSummary::kNoCall); | 1856 : instruction_(instruction) { } |
| 1857 |
| 1858 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1859 __ Comment("BoxDoubleSlowPath"); |
| 1860 __ Bind(entry_label()); |
| 1861 const Class& double_class = compiler->double_class(); |
| 1862 const Code& stub = |
| 1863 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1864 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1865 |
| 1866 LocationSummary* locs = instruction_->locs(); |
| 1867 locs->live_registers()->Remove(locs->out()); |
| 1868 |
| 1869 compiler->SaveLiveRegisters(locs); |
| 1870 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 1871 &label, |
| 1872 PcDescriptors::kOther, |
| 1873 locs); |
| 1874 __ MoveRegister(locs->out().reg(), R0); |
| 1875 compiler->RestoreLiveRegisters(locs); |
| 1876 |
| 1877 __ b(exit_label()); |
| 1878 } |
| 1879 |
| 1880 private: |
| 1881 Instruction* instruction_; |
| 1882 }; |
| 1883 |
| 1884 |
| 1885 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 1886 const intptr_t kNumInputs = 1; |
| 1887 const intptr_t kNumTemps = 0; |
| 1888 LocationSummary* locs = |
| 1889 new LocationSummary( |
| 1890 kNumInputs, kNumTemps, |
| 1891 (opt && !IsPotentialUnboxedLoad()) |
| 1892 ? LocationSummary::kNoCall |
| 1893 : LocationSummary::kCallOnSlowPath); |
| 1894 |
| 1895 locs->set_in(0, Location::RequiresRegister()); |
| 1896 |
| 1897 if (IsUnboxedLoad() && opt) { |
| 1898 locs->AddTemp(Location::RequiresRegister()); |
| 1899 } else if (IsPotentialUnboxedLoad()) { |
| 1900 locs->AddTemp(opt ? Location::RequiresFpuRegister() |
| 1901 : Location::FpuRegisterLocation(Q1)); |
| 1902 locs->AddTemp(Location::RequiresRegister()); |
| 1903 } |
| 1904 locs->set_out(Location::RequiresRegister()); |
| 1905 return locs; |
1732 } | 1906 } |
1733 | 1907 |
1734 | 1908 |
1735 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1909 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1736 Register instance_reg = locs()->in(0).reg(); | 1910 Register instance_reg = locs()->in(0).reg(); |
| 1911 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 1912 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
| 1913 Register temp = locs()->temp(0).reg(); |
| 1914 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1915 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); |
| 1916 return; |
| 1917 } |
| 1918 |
| 1919 Label done; |
1737 Register result_reg = locs()->out().reg(); | 1920 Register result_reg = locs()->out().reg(); |
| 1921 if (IsPotentialUnboxedLoad()) { |
| 1922 Register temp = locs()->temp(1).reg(); |
| 1923 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |
1738 | 1924 |
| 1925 Label load_pointer; |
| 1926 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 1927 |
| 1928 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 1929 FieldAddress field_nullability_operand(result_reg, |
| 1930 Field::is_nullable_offset()); |
| 1931 |
| 1932 __ ldr(temp, field_cid_operand); |
| 1933 __ CompareImmediate(temp, kDoubleCid); |
| 1934 __ b(&load_pointer, NE); |
| 1935 |
| 1936 __ ldr(temp, field_nullability_operand); |
| 1937 __ CompareImmediate(temp, kNullCid); |
| 1938 __ b(&load_pointer, EQ); |
| 1939 |
| 1940 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| 1941 compiler->AddSlowPathCode(slow_path); |
| 1942 |
| 1943 if (!compiler->is_optimizing()) { |
| 1944 locs()->live_registers()->Add(locs()->in(0)); |
| 1945 } |
| 1946 |
| 1947 __ TryAllocate(compiler->double_class(), |
| 1948 slow_path->entry_label(), |
| 1949 result_reg); |
| 1950 __ Bind(slow_path->exit_label()); |
| 1951 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 1952 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1953 __ StoreDToOffset(value, |
| 1954 result_reg, |
| 1955 Double::value_offset() - kHeapObjectTag); |
| 1956 __ b(&done); |
| 1957 __ Bind(&load_pointer); |
| 1958 } |
1739 __ LoadFromOffset(kWord, result_reg, | 1959 __ LoadFromOffset(kWord, result_reg, |
1740 instance_reg, offset_in_bytes() - kHeapObjectTag); | 1960 instance_reg, offset_in_bytes() - kHeapObjectTag); |
| 1961 __ Bind(&done); |
1741 } | 1962 } |
1742 | 1963 |
1743 | 1964 |
1744 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { | 1965 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
1745 const intptr_t kNumInputs = 1; | 1966 const intptr_t kNumInputs = 1; |
1746 const intptr_t kNumTemps = 0; | 1967 const intptr_t kNumTemps = 0; |
1747 LocationSummary* locs = | 1968 LocationSummary* locs = |
1748 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1969 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1749 locs->set_in(0, Location::RegisterLocation(R0)); | 1970 locs->set_in(0, Location::RegisterLocation(R0)); |
1750 locs->set_out(Location::RegisterLocation(R0)); | 1971 locs->set_out(Location::RegisterLocation(R0)); |
1751 return locs; | 1972 return locs; |
1752 } | 1973 } |
1753 | 1974 |
1754 | 1975 |
(...skipping 11 matching lines...) Expand all Loading... |
1766 deopt_id(), | 1987 deopt_id(), |
1767 kInstantiateTypeRuntimeEntry, | 1988 kInstantiateTypeRuntimeEntry, |
1768 2, | 1989 2, |
1769 locs()); | 1990 locs()); |
1770 __ Drop(2); // Drop instantiator and uninstantiated type. | 1991 __ Drop(2); // Drop instantiator and uninstantiated type. |
1771 __ Pop(result_reg); // Pop instantiated type. | 1992 __ Pop(result_reg); // Pop instantiated type. |
1772 ASSERT(instantiator_reg == result_reg); | 1993 ASSERT(instantiator_reg == result_reg); |
1773 } | 1994 } |
1774 | 1995 |
1775 | 1996 |
1776 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 1997 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 1998 bool opt) const { |
1777 const intptr_t kNumInputs = 1; | 1999 const intptr_t kNumInputs = 1; |
1778 const intptr_t kNumTemps = 0; | 2000 const intptr_t kNumTemps = 0; |
1779 LocationSummary* locs = | 2001 LocationSummary* locs = |
1780 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1781 locs->set_in(0, Location::RegisterLocation(R0)); | 2003 locs->set_in(0, Location::RegisterLocation(R0)); |
1782 locs->set_out(Location::RegisterLocation(R0)); | 2004 locs->set_out(Location::RegisterLocation(R0)); |
1783 return locs; | 2005 return locs; |
1784 } | 2006 } |
1785 | 2007 |
1786 | 2008 |
(...skipping 28 matching lines...) Expand all Loading... |
1815 2, | 2037 2, |
1816 locs()); | 2038 locs()); |
1817 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2039 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
1818 __ Pop(result_reg); // Pop instantiated type arguments. | 2040 __ Pop(result_reg); // Pop instantiated type arguments. |
1819 __ Bind(&type_arguments_instantiated); | 2041 __ Bind(&type_arguments_instantiated); |
1820 ASSERT(instantiator_reg == result_reg); | 2042 ASSERT(instantiator_reg == result_reg); |
1821 } | 2043 } |
1822 | 2044 |
1823 | 2045 |
1824 LocationSummary* | 2046 LocationSummary* |
1825 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 2047 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const { |
1826 const intptr_t kNumInputs = 1; | 2048 const intptr_t kNumInputs = 1; |
1827 const intptr_t kNumTemps = 0; | 2049 const intptr_t kNumTemps = 0; |
1828 LocationSummary* locs = | 2050 LocationSummary* locs = |
1829 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1830 locs->set_in(0, Location::RequiresRegister()); | 2052 locs->set_in(0, Location::RequiresRegister()); |
1831 locs->set_out(Location::SameAsFirstInput()); | 2053 locs->set_out(Location::SameAsFirstInput()); |
1832 return locs; | 2054 return locs; |
1833 } | 2055 } |
1834 | 2056 |
1835 | 2057 |
(...skipping 21 matching lines...) Expand all Loading... |
1857 // instantiate the type arguments. | 2079 // instantiate the type arguments. |
1858 __ LoadObject(result_reg, type_arguments()); | 2080 __ LoadObject(result_reg, type_arguments()); |
1859 // result_reg: uninstantiated type arguments. | 2081 // result_reg: uninstantiated type arguments. |
1860 __ Bind(&type_arguments_instantiated); | 2082 __ Bind(&type_arguments_instantiated); |
1861 | 2083 |
1862 // result_reg: uninstantiated or instantiated type arguments. | 2084 // result_reg: uninstantiated or instantiated type arguments. |
1863 } | 2085 } |
1864 | 2086 |
1865 | 2087 |
1866 LocationSummary* | 2088 LocationSummary* |
1867 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 2089 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const { |
1868 const intptr_t kNumInputs = 1; | 2090 const intptr_t kNumInputs = 1; |
1869 const intptr_t kNumTemps = 0; | 2091 const intptr_t kNumTemps = 0; |
1870 LocationSummary* locs = | 2092 LocationSummary* locs = |
1871 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1872 locs->set_in(0, Location::RequiresRegister()); | 2094 locs->set_in(0, Location::RequiresRegister()); |
1873 locs->set_out(Location::SameAsFirstInput()); | 2095 locs->set_out(Location::SameAsFirstInput()); |
1874 return locs; | 2096 return locs; |
1875 } | 2097 } |
1876 | 2098 |
1877 | 2099 |
(...skipping 18 matching lines...) Expand all Loading... |
1896 __ b(&instantiator_not_null, NE); | 2118 __ b(&instantiator_not_null, NE); |
1897 // Null was used in VisitExtractConstructorTypeArguments as the | 2119 // Null was used in VisitExtractConstructorTypeArguments as the |
1898 // instantiated type arguments, no proper instantiator needed. | 2120 // instantiated type arguments, no proper instantiator needed. |
1899 __ LoadImmediate(instantiator_reg, | 2121 __ LoadImmediate(instantiator_reg, |
1900 Smi::RawValue(StubCode::kNoInstantiator)); | 2122 Smi::RawValue(StubCode::kNoInstantiator)); |
1901 __ Bind(&instantiator_not_null); | 2123 __ Bind(&instantiator_not_null); |
1902 // instantiator_reg: instantiator or kNoInstantiator. | 2124 // instantiator_reg: instantiator or kNoInstantiator. |
1903 } | 2125 } |
1904 | 2126 |
1905 | 2127 |
1906 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 2128 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
1907 const intptr_t kNumInputs = 0; | 2129 const intptr_t kNumInputs = 0; |
1908 const intptr_t kNumTemps = 1; | 2130 const intptr_t kNumTemps = 1; |
1909 LocationSummary* locs = | 2131 LocationSummary* locs = |
1910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2132 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1911 locs->set_temp(0, Location::RegisterLocation(R1)); | 2133 locs->set_temp(0, Location::RegisterLocation(R1)); |
1912 locs->set_out(Location::RegisterLocation(R0)); | 2134 locs->set_out(Location::RegisterLocation(R0)); |
1913 return locs; | 2135 return locs; |
1914 } | 2136 } |
1915 | 2137 |
1916 | 2138 |
1917 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2139 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1918 ASSERT(locs()->temp(0).reg() == R1); | 2140 ASSERT(locs()->temp(0).reg() == R1); |
1919 ASSERT(locs()->out().reg() == R0); | 2141 ASSERT(locs()->out().reg() == R0); |
1920 | 2142 |
1921 __ LoadImmediate(R1, num_context_variables()); | 2143 __ LoadImmediate(R1, num_context_variables()); |
1922 const ExternalLabel label("alloc_context", | 2144 const ExternalLabel label("alloc_context", |
1923 StubCode::AllocateContextEntryPoint()); | 2145 StubCode::AllocateContextEntryPoint()); |
1924 compiler->GenerateCall(token_pos(), | 2146 compiler->GenerateCall(token_pos(), |
1925 &label, | 2147 &label, |
1926 PcDescriptors::kOther, | 2148 PcDescriptors::kOther, |
1927 locs()); | 2149 locs()); |
1928 } | 2150 } |
1929 | 2151 |
1930 | 2152 |
1931 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 2153 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { |
1932 const intptr_t kNumInputs = 1; | 2154 const intptr_t kNumInputs = 1; |
1933 const intptr_t kNumTemps = 0; | 2155 const intptr_t kNumTemps = 0; |
1934 LocationSummary* locs = | 2156 LocationSummary* locs = |
1935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2157 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1936 locs->set_in(0, Location::RegisterLocation(R0)); | 2158 locs->set_in(0, Location::RegisterLocation(R0)); |
1937 locs->set_out(Location::RegisterLocation(R0)); | 2159 locs->set_out(Location::RegisterLocation(R0)); |
1938 return locs; | 2160 return locs; |
1939 } | 2161 } |
1940 | 2162 |
1941 | 2163 |
1942 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2164 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1943 Register context_value = locs()->in(0).reg(); | 2165 Register context_value = locs()->in(0).reg(); |
1944 Register result = locs()->out().reg(); | 2166 Register result = locs()->out().reg(); |
1945 | 2167 |
1946 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2168 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1947 __ Push(context_value); | 2169 __ Push(context_value); |
1948 compiler->GenerateRuntimeCall(token_pos(), | 2170 compiler->GenerateRuntimeCall(token_pos(), |
1949 deopt_id(), | 2171 deopt_id(), |
1950 kCloneContextRuntimeEntry, | 2172 kCloneContextRuntimeEntry, |
1951 1, | 2173 1, |
1952 locs()); | 2174 locs()); |
1953 __ Drop(1); // Remove argument. | 2175 __ Drop(1); // Remove argument. |
1954 __ Pop(result); // Get result (cloned context). | 2176 __ Pop(result); // Get result (cloned context). |
1955 } | 2177 } |
1956 | 2178 |
1957 | 2179 |
1958 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { | 2180 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const { |
1959 UNREACHABLE(); | 2181 UNREACHABLE(); |
1960 return NULL; | 2182 return NULL; |
1961 } | 2183 } |
1962 | 2184 |
1963 | 2185 |
1964 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2186 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1965 __ Bind(compiler->GetJumpLabel(this)); | 2187 __ Bind(compiler->GetJumpLabel(this)); |
1966 compiler->AddExceptionHandler(catch_try_index(), | 2188 compiler->AddExceptionHandler(catch_try_index(), |
1967 try_index(), | 2189 try_index(), |
1968 compiler->assembler()->CodeSize(), | 2190 compiler->assembler()->CodeSize(), |
(...skipping 16 matching lines...) Expand all Loading... |
1985 | 2207 |
1986 // Restore stack and initialize the two exception variables: | 2208 // Restore stack and initialize the two exception variables: |
1987 // exception and stack trace variables. | 2209 // exception and stack trace variables. |
1988 __ StoreToOffset(kWord, kExceptionObjectReg, | 2210 __ StoreToOffset(kWord, kExceptionObjectReg, |
1989 FP, exception_var().index() * kWordSize); | 2211 FP, exception_var().index() * kWordSize); |
1990 __ StoreToOffset(kWord, kStackTraceObjectReg, | 2212 __ StoreToOffset(kWord, kStackTraceObjectReg, |
1991 FP, stacktrace_var().index() * kWordSize); | 2213 FP, stacktrace_var().index() * kWordSize); |
1992 } | 2214 } |
1993 | 2215 |
1994 | 2216 |
1995 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2217 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const { |
1996 const intptr_t kNumInputs = 0; | 2218 const intptr_t kNumInputs = 0; |
1997 const intptr_t kNumTemps = 1; | 2219 const intptr_t kNumTemps = 1; |
1998 LocationSummary* summary = | 2220 LocationSummary* summary = |
1999 new LocationSummary(kNumInputs, | 2221 new LocationSummary(kNumInputs, |
2000 kNumTemps, | 2222 kNumTemps, |
2001 LocationSummary::kCallOnSlowPath); | 2223 LocationSummary::kCallOnSlowPath); |
2002 summary->set_temp(0, Location::RequiresRegister()); | 2224 summary->set_temp(0, Location::RequiresRegister()); |
2003 return summary; | 2225 return summary; |
2004 } | 2226 } |
2005 | 2227 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 Register temp = locs.temp(0).reg(); | 2390 Register temp = locs.temp(0).reg(); |
2169 __ Lsl(temp, left, IP); | 2391 __ Lsl(temp, left, IP); |
2170 __ cmp(left, ShifterOperand(temp, ASR, IP)); | 2392 __ cmp(left, ShifterOperand(temp, ASR, IP)); |
2171 __ b(deopt, NE); // Overflow. | 2393 __ b(deopt, NE); // Overflow. |
2172 // Shift for result now we know there is no overflow. | 2394 // Shift for result now we know there is no overflow. |
2173 __ Lsl(result, left, IP); | 2395 __ Lsl(result, left, IP); |
2174 } | 2396 } |
2175 } | 2397 } |
2176 | 2398 |
2177 | 2399 |
2178 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 2400 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const { |
2179 const intptr_t kNumInputs = 2; | 2401 const intptr_t kNumInputs = 2; |
2180 const intptr_t kNumTemps = 0; | 2402 const intptr_t kNumTemps = 0; |
2181 LocationSummary* summary = | 2403 LocationSummary* summary = |
2182 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2404 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2183 if (op_kind() == Token::kTRUNCDIV) { | 2405 if (op_kind() == Token::kTRUNCDIV) { |
2184 summary->set_in(0, Location::RequiresRegister()); | 2406 summary->set_in(0, Location::RequiresRegister()); |
2185 if (RightIsPowerOfTwoConstant()) { | 2407 if (RightIsPowerOfTwoConstant()) { |
2186 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2408 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
2187 summary->set_in(1, Location::Constant(right_constant->value())); | 2409 summary->set_in(1, Location::Constant(right_constant->value())); |
2188 summary->AddTemp(Location::RequiresRegister()); | 2410 summary->AddTemp(Location::RequiresRegister()); |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2499 UNREACHABLE(); | 2721 UNREACHABLE(); |
2500 break; | 2722 break; |
2501 } | 2723 } |
2502 default: | 2724 default: |
2503 UNREACHABLE(); | 2725 UNREACHABLE(); |
2504 break; | 2726 break; |
2505 } | 2727 } |
2506 } | 2728 } |
2507 | 2729 |
2508 | 2730 |
2509 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 2731 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const { |
2510 intptr_t left_cid = left()->Type()->ToCid(); | 2732 intptr_t left_cid = left()->Type()->ToCid(); |
2511 intptr_t right_cid = right()->Type()->ToCid(); | 2733 intptr_t right_cid = right()->Type()->ToCid(); |
2512 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); | 2734 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); |
2513 const intptr_t kNumInputs = 2; | 2735 const intptr_t kNumInputs = 2; |
2514 const intptr_t kNumTemps = 0; | 2736 const intptr_t kNumTemps = 0; |
2515 LocationSummary* summary = | 2737 LocationSummary* summary = |
2516 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2738 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2517 summary->set_in(0, Location::RequiresRegister()); | 2739 summary->set_in(0, Location::RequiresRegister()); |
2518 summary->set_in(1, Location::RequiresRegister()); | 2740 summary->set_in(1, Location::RequiresRegister()); |
2519 return summary; | 2741 return summary; |
(...skipping 11 matching lines...) Expand all Loading... |
2531 } else if (right_cid == kSmiCid) { | 2753 } else if (right_cid == kSmiCid) { |
2532 __ tst(left, ShifterOperand(kSmiTagMask)); | 2754 __ tst(left, ShifterOperand(kSmiTagMask)); |
2533 } else { | 2755 } else { |
2534 __ orr(IP, left, ShifterOperand(right)); | 2756 __ orr(IP, left, ShifterOperand(right)); |
2535 __ tst(IP, ShifterOperand(kSmiTagMask)); | 2757 __ tst(IP, ShifterOperand(kSmiTagMask)); |
2536 } | 2758 } |
2537 __ b(deopt, EQ); | 2759 __ b(deopt, EQ); |
2538 } | 2760 } |
2539 | 2761 |
2540 | 2762 |
2541 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 2763 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { |
2542 const intptr_t kNumInputs = 1; | 2764 const intptr_t kNumInputs = 1; |
2543 const intptr_t kNumTemps = 0; | 2765 const intptr_t kNumTemps = 0; |
2544 LocationSummary* summary = | 2766 LocationSummary* summary = |
2545 new LocationSummary(kNumInputs, | 2767 new LocationSummary(kNumInputs, |
2546 kNumTemps, | 2768 kNumTemps, |
2547 LocationSummary::kCallOnSlowPath); | 2769 LocationSummary::kCallOnSlowPath); |
2548 summary->set_in(0, Location::RequiresFpuRegister()); | 2770 summary->set_in(0, Location::RequiresFpuRegister()); |
2549 summary->set_out(Location::RequiresRegister()); | 2771 summary->set_out(Location::RequiresRegister()); |
2550 return summary; | 2772 return summary; |
2551 } | 2773 } |
2552 | 2774 |
2553 | 2775 |
2554 class BoxDoubleSlowPath : public SlowPathCode { | |
2555 public: | |
2556 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | |
2557 : instruction_(instruction) { } | |
2558 | |
2559 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2560 __ Comment("BoxDoubleSlowPath"); | |
2561 __ Bind(entry_label()); | |
2562 const Class& double_class = compiler->double_class(); | |
2563 const Code& stub = | |
2564 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | |
2565 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | |
2566 | |
2567 LocationSummary* locs = instruction_->locs(); | |
2568 locs->live_registers()->Remove(locs->out()); | |
2569 | |
2570 compiler->SaveLiveRegisters(locs); | |
2571 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | |
2572 &label, | |
2573 PcDescriptors::kOther, | |
2574 locs); | |
2575 __ MoveRegister(locs->out().reg(), R0); | |
2576 compiler->RestoreLiveRegisters(locs); | |
2577 | |
2578 __ b(exit_label()); | |
2579 } | |
2580 | |
2581 private: | |
2582 BoxDoubleInstr* instruction_; | |
2583 }; | |
2584 | |
2585 | |
2586 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2776 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2587 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2777 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
2588 compiler->AddSlowPathCode(slow_path); | 2778 compiler->AddSlowPathCode(slow_path); |
2589 | 2779 |
2590 const Register out_reg = locs()->out().reg(); | 2780 const Register out_reg = locs()->out().reg(); |
2591 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 2781 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
2592 | 2782 |
2593 __ TryAllocate(compiler->double_class(), | 2783 __ TryAllocate(compiler->double_class(), |
2594 slow_path->entry_label(), | 2784 slow_path->entry_label(), |
2595 out_reg); | 2785 out_reg); |
2596 __ Bind(slow_path->exit_label()); | 2786 __ Bind(slow_path->exit_label()); |
2597 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 2787 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
2598 } | 2788 } |
2599 | 2789 |
2600 | 2790 |
2601 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2791 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { |
2602 const intptr_t kNumInputs = 1; | 2792 const intptr_t kNumInputs = 1; |
2603 const intptr_t value_cid = value()->Type()->ToCid(); | 2793 const intptr_t value_cid = value()->Type()->ToCid(); |
2604 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); | 2794 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
2605 const bool needs_writable_input = (value_cid == kSmiCid); | 2795 const bool needs_writable_input = (value_cid == kSmiCid); |
2606 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 2796 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
2607 LocationSummary* summary = | 2797 LocationSummary* summary = |
2608 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2798 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2609 summary->set_in(0, needs_writable_input | 2799 summary->set_in(0, needs_writable_input |
2610 ? Location::WritableRegister() | 2800 ? Location::WritableRegister() |
2611 : Location::RequiresRegister()); | 2801 : Location::RequiresRegister()); |
(...skipping 27 matching lines...) Expand all Loading... |
2639 __ Bind(&is_smi); | 2829 __ Bind(&is_smi); |
2640 // TODO(regis): Why do we preserve value here but not above? | 2830 // TODO(regis): Why do we preserve value here but not above? |
2641 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag. | 2831 __ mov(IP, ShifterOperand(value, ASR, 1)); // Copy and untag. |
2642 __ vmovsr(STMP, IP); | 2832 __ vmovsr(STMP, IP); |
2643 __ vcvtdi(result, STMP); | 2833 __ vcvtdi(result, STMP); |
2644 __ Bind(&done); | 2834 __ Bind(&done); |
2645 } | 2835 } |
2646 } | 2836 } |
2647 | 2837 |
2648 | 2838 |
2649 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { | 2839 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
2650 const intptr_t kNumInputs = 1; | 2840 const intptr_t kNumInputs = 1; |
2651 const intptr_t kNumTemps = 0; | 2841 const intptr_t kNumTemps = 0; |
2652 LocationSummary* summary = | 2842 LocationSummary* summary = |
2653 new LocationSummary(kNumInputs, | 2843 new LocationSummary(kNumInputs, |
2654 kNumTemps, | 2844 kNumTemps, |
2655 LocationSummary::kCallOnSlowPath); | 2845 LocationSummary::kCallOnSlowPath); |
2656 summary->set_in(0, Location::RequiresFpuRegister()); | 2846 summary->set_in(0, Location::RequiresFpuRegister()); |
2657 summary->set_out(Location::RequiresRegister()); | 2847 summary->set_out(Location::RequiresRegister()); |
2658 return summary; | 2848 return summary; |
2659 } | 2849 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 out_reg); | 2895 out_reg); |
2706 __ Bind(slow_path->exit_label()); | 2896 __ Bind(slow_path->exit_label()); |
2707 | 2897 |
2708 __ StoreDToOffset(value_even, out_reg, | 2898 __ StoreDToOffset(value_even, out_reg, |
2709 Float32x4::value_offset() - kHeapObjectTag); | 2899 Float32x4::value_offset() - kHeapObjectTag); |
2710 __ StoreDToOffset(value_odd, out_reg, | 2900 __ StoreDToOffset(value_odd, out_reg, |
2711 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2901 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2712 } | 2902 } |
2713 | 2903 |
2714 | 2904 |
2715 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { | 2905 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
2716 const intptr_t value_cid = value()->Type()->ToCid(); | 2906 const intptr_t value_cid = value()->Type()->ToCid(); |
2717 const intptr_t kNumInputs = 1; | 2907 const intptr_t kNumInputs = 1; |
2718 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 2908 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
2719 LocationSummary* summary = | 2909 LocationSummary* summary = |
2720 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2910 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2721 summary->set_in(0, Location::RequiresRegister()); | 2911 summary->set_in(0, Location::RequiresRegister()); |
2722 if (kNumTemps > 0) { | 2912 if (kNumTemps > 0) { |
2723 ASSERT(kNumTemps == 1); | 2913 ASSERT(kNumTemps == 1); |
2724 summary->set_temp(0, Location::RequiresRegister()); | 2914 summary->set_temp(0, Location::RequiresRegister()); |
2725 } | 2915 } |
(...skipping 18 matching lines...) Expand all Loading... |
2744 | 2934 |
2745 const DRegister result_even = EvenDRegisterOf(result); | 2935 const DRegister result_even = EvenDRegisterOf(result); |
2746 const DRegister result_odd = OddDRegisterOf(result); | 2936 const DRegister result_odd = OddDRegisterOf(result); |
2747 __ LoadDFromOffset(result_even, value, | 2937 __ LoadDFromOffset(result_even, value, |
2748 Float32x4::value_offset() - kHeapObjectTag); | 2938 Float32x4::value_offset() - kHeapObjectTag); |
2749 __ LoadDFromOffset(result_odd, value, | 2939 __ LoadDFromOffset(result_odd, value, |
2750 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2940 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2751 } | 2941 } |
2752 | 2942 |
2753 | 2943 |
2754 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { | 2944 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
2755 const intptr_t kNumInputs = 1; | 2945 const intptr_t kNumInputs = 1; |
2756 const intptr_t kNumTemps = 0; | 2946 const intptr_t kNumTemps = 0; |
2757 LocationSummary* summary = | 2947 LocationSummary* summary = |
2758 new LocationSummary(kNumInputs, | 2948 new LocationSummary(kNumInputs, |
2759 kNumTemps, | 2949 kNumTemps, |
2760 LocationSummary::kCallOnSlowPath); | 2950 LocationSummary::kCallOnSlowPath); |
2761 summary->set_in(0, Location::RequiresFpuRegister()); | 2951 summary->set_in(0, Location::RequiresFpuRegister()); |
2762 summary->set_out(Location::RequiresRegister()); | 2952 summary->set_out(Location::RequiresRegister()); |
2763 return summary; | 2953 return summary; |
2764 } | 2954 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2809 slow_path->entry_label(), | 2999 slow_path->entry_label(), |
2810 out_reg); | 3000 out_reg); |
2811 __ Bind(slow_path->exit_label()); | 3001 __ Bind(slow_path->exit_label()); |
2812 __ StoreDToOffset(value_even, out_reg, | 3002 __ StoreDToOffset(value_even, out_reg, |
2813 Int32x4::value_offset() - kHeapObjectTag); | 3003 Int32x4::value_offset() - kHeapObjectTag); |
2814 __ StoreDToOffset(value_odd, out_reg, | 3004 __ StoreDToOffset(value_odd, out_reg, |
2815 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3005 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2816 } | 3006 } |
2817 | 3007 |
2818 | 3008 |
2819 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { | 3009 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
2820 const intptr_t value_cid = value()->Type()->ToCid(); | 3010 const intptr_t value_cid = value()->Type()->ToCid(); |
2821 const intptr_t kNumInputs = 1; | 3011 const intptr_t kNumInputs = 1; |
2822 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3012 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
2823 LocationSummary* summary = | 3013 LocationSummary* summary = |
2824 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3014 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2825 summary->set_in(0, Location::RequiresRegister()); | 3015 summary->set_in(0, Location::RequiresRegister()); |
2826 if (kNumTemps > 0) { | 3016 if (kNumTemps > 0) { |
2827 ASSERT(kNumTemps == 1); | 3017 ASSERT(kNumTemps == 1); |
2828 summary->set_temp(0, Location::RequiresRegister()); | 3018 summary->set_temp(0, Location::RequiresRegister()); |
2829 } | 3019 } |
(...skipping 18 matching lines...) Expand all Loading... |
2848 | 3038 |
2849 const DRegister result_even = EvenDRegisterOf(result); | 3039 const DRegister result_even = EvenDRegisterOf(result); |
2850 const DRegister result_odd = OddDRegisterOf(result); | 3040 const DRegister result_odd = OddDRegisterOf(result); |
2851 __ LoadDFromOffset(result_even, value, | 3041 __ LoadDFromOffset(result_even, value, |
2852 Int32x4::value_offset() - kHeapObjectTag); | 3042 Int32x4::value_offset() - kHeapObjectTag); |
2853 __ LoadDFromOffset(result_odd, value, | 3043 __ LoadDFromOffset(result_odd, value, |
2854 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3044 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2855 } | 3045 } |
2856 | 3046 |
2857 | 3047 |
2858 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 3048 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
2859 const intptr_t kNumInputs = 2; | 3049 const intptr_t kNumInputs = 2; |
2860 const intptr_t kNumTemps = 0; | 3050 const intptr_t kNumTemps = 0; |
2861 LocationSummary* summary = | 3051 LocationSummary* summary = |
2862 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3052 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2863 summary->set_in(0, Location::RequiresFpuRegister()); | 3053 summary->set_in(0, Location::RequiresFpuRegister()); |
2864 summary->set_in(1, Location::RequiresFpuRegister()); | 3054 summary->set_in(1, Location::RequiresFpuRegister()); |
2865 summary->set_out(Location::RequiresFpuRegister()); | 3055 summary->set_out(Location::RequiresFpuRegister()); |
2866 return summary; | 3056 return summary; |
2867 } | 3057 } |
2868 | 3058 |
2869 | 3059 |
2870 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3060 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2871 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 3061 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
2872 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 3062 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
2873 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 3063 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
2874 switch (op_kind()) { | 3064 switch (op_kind()) { |
2875 case Token::kADD: __ vaddd(result, left, right); break; | 3065 case Token::kADD: __ vaddd(result, left, right); break; |
2876 case Token::kSUB: __ vsubd(result, left, right); break; | 3066 case Token::kSUB: __ vsubd(result, left, right); break; |
2877 case Token::kMUL: __ vmuld(result, left, right); break; | 3067 case Token::kMUL: __ vmuld(result, left, right); break; |
2878 case Token::kDIV: __ vdivd(result, left, right); break; | 3068 case Token::kDIV: __ vdivd(result, left, right); break; |
2879 default: UNREACHABLE(); | 3069 default: UNREACHABLE(); |
2880 } | 3070 } |
2881 } | 3071 } |
2882 | 3072 |
2883 | 3073 |
2884 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { | 3074 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { |
2885 const intptr_t kNumInputs = 2; | 3075 const intptr_t kNumInputs = 2; |
2886 const intptr_t kNumTemps = 0; | 3076 const intptr_t kNumTemps = 0; |
2887 LocationSummary* summary = | 3077 LocationSummary* summary = |
2888 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2889 summary->set_in(0, Location::RequiresFpuRegister()); | 3079 summary->set_in(0, Location::RequiresFpuRegister()); |
2890 summary->set_in(1, Location::RequiresFpuRegister()); | 3080 summary->set_in(1, Location::RequiresFpuRegister()); |
2891 summary->set_out(Location::RequiresFpuRegister()); | 3081 summary->set_out(Location::RequiresFpuRegister()); |
2892 return summary; | 3082 return summary; |
2893 } | 3083 } |
2894 | 3084 |
2895 | 3085 |
2896 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3086 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2897 QRegister left = locs()->in(0).fpu_reg(); | 3087 QRegister left = locs()->in(0).fpu_reg(); |
2898 QRegister right = locs()->in(1).fpu_reg(); | 3088 QRegister right = locs()->in(1).fpu_reg(); |
2899 QRegister result = locs()->out().fpu_reg(); | 3089 QRegister result = locs()->out().fpu_reg(); |
2900 | 3090 |
2901 switch (op_kind()) { | 3091 switch (op_kind()) { |
2902 case Token::kADD: __ vaddqs(result, left, right); break; | 3092 case Token::kADD: __ vaddqs(result, left, right); break; |
2903 case Token::kSUB: __ vsubqs(result, left, right); break; | 3093 case Token::kSUB: __ vsubqs(result, left, right); break; |
2904 case Token::kMUL: __ vmulqs(result, left, right); break; | 3094 case Token::kMUL: __ vmulqs(result, left, right); break; |
2905 case Token::kDIV: __ Vdivqs(result, left, right); break; | 3095 case Token::kDIV: __ Vdivqs(result, left, right); break; |
2906 default: UNREACHABLE(); | 3096 default: UNREACHABLE(); |
2907 } | 3097 } |
2908 } | 3098 } |
2909 | 3099 |
2910 | 3100 |
2911 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { | 3101 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
2912 const intptr_t kNumInputs = 1; | 3102 const intptr_t kNumInputs = 1; |
2913 const intptr_t kNumTemps = 0; | 3103 const intptr_t kNumTemps = 0; |
2914 LocationSummary* summary = | 3104 LocationSummary* summary = |
2915 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2916 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3106 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
2917 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3107 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
2918 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3108 summary->set_out(Location::FpuRegisterLocation(Q6)); |
2919 return summary; | 3109 return summary; |
2920 } | 3110 } |
2921 | 3111 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 __ vmovs(sresult1, svalues[(mask_ >> 2) & 0x3]); | 3171 __ vmovs(sresult1, svalues[(mask_ >> 2) & 0x3]); |
2982 __ vmovs(sresult2, svalues[(mask_ >> 4) & 0x3]); | 3172 __ vmovs(sresult2, svalues[(mask_ >> 4) & 0x3]); |
2983 __ vmovs(sresult3, svalues[(mask_ >> 6) & 0x3]); | 3173 __ vmovs(sresult3, svalues[(mask_ >> 6) & 0x3]); |
2984 } | 3174 } |
2985 break; | 3175 break; |
2986 default: UNREACHABLE(); | 3176 default: UNREACHABLE(); |
2987 } | 3177 } |
2988 } | 3178 } |
2989 | 3179 |
2990 | 3180 |
2991 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 3181 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { |
2992 const intptr_t kNumInputs = 2; | 3182 const intptr_t kNumInputs = 2; |
2993 const intptr_t kNumTemps = 0; | 3183 const intptr_t kNumTemps = 0; |
2994 LocationSummary* summary = | 3184 LocationSummary* summary = |
2995 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2996 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. | 3186 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. |
2997 summary->set_in(0, Location::FpuRegisterLocation(Q4)); | 3187 summary->set_in(0, Location::FpuRegisterLocation(Q4)); |
2998 summary->set_in(1, Location::FpuRegisterLocation(Q5)); | 3188 summary->set_in(1, Location::FpuRegisterLocation(Q5)); |
2999 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3189 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3000 return summary; | 3190 return summary; |
3001 } | 3191 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3037 __ vmovs(sresult0, left_svalues[mask_ & 0x3]); | 3227 __ vmovs(sresult0, left_svalues[mask_ & 0x3]); |
3038 __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]); | 3228 __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]); |
3039 __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]); | 3229 __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]); |
3040 __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]); | 3230 __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]); |
3041 break; | 3231 break; |
3042 default: UNREACHABLE(); | 3232 default: UNREACHABLE(); |
3043 } | 3233 } |
3044 } | 3234 } |
3045 | 3235 |
3046 | 3236 |
3047 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 3237 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { |
3048 const intptr_t kNumInputs = 1; | 3238 const intptr_t kNumInputs = 1; |
3049 const intptr_t kNumTemps = 1; | 3239 const intptr_t kNumTemps = 1; |
3050 LocationSummary* summary = | 3240 LocationSummary* summary = |
3051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3241 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3052 summary->set_in(0, Location::FpuRegisterLocation(Q5)); | 3242 summary->set_in(0, Location::FpuRegisterLocation(Q5)); |
3053 summary->set_temp(0, Location::RequiresRegister()); | 3243 summary->set_temp(0, Location::RequiresRegister()); |
3054 summary->set_out(Location::RequiresRegister()); | 3244 summary->set_out(Location::RequiresRegister()); |
3055 return summary; | 3245 return summary; |
3056 } | 3246 } |
3057 | 3247 |
(...skipping 19 matching lines...) Expand all Loading... |
3077 __ orr(out, out, ShifterOperand(temp, LSL, 2)); | 3267 __ orr(out, out, ShifterOperand(temp, LSL, 2)); |
3078 // W lane. | 3268 // W lane. |
3079 __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 3269 __ vmovrs(temp, OddSRegisterOf(dvalue1)); |
3080 __ Lsr(temp, temp, 31); | 3270 __ Lsr(temp, temp, 31); |
3081 __ orr(out, out, ShifterOperand(temp, LSL, 3)); | 3271 __ orr(out, out, ShifterOperand(temp, LSL, 3)); |
3082 // Tag. | 3272 // Tag. |
3083 __ SmiTag(out); | 3273 __ SmiTag(out); |
3084 } | 3274 } |
3085 | 3275 |
3086 | 3276 |
3087 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { | 3277 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 3278 bool opt) const { |
3088 const intptr_t kNumInputs = 4; | 3279 const intptr_t kNumInputs = 4; |
3089 const intptr_t kNumTemps = 0; | 3280 const intptr_t kNumTemps = 0; |
3090 LocationSummary* summary = | 3281 LocationSummary* summary = |
3091 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3282 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3092 summary->set_in(0, Location::RequiresFpuRegister()); | 3283 summary->set_in(0, Location::RequiresFpuRegister()); |
3093 summary->set_in(1, Location::RequiresFpuRegister()); | 3284 summary->set_in(1, Location::RequiresFpuRegister()); |
3094 summary->set_in(2, Location::RequiresFpuRegister()); | 3285 summary->set_in(2, Location::RequiresFpuRegister()); |
3095 summary->set_in(3, Location::RequiresFpuRegister()); | 3286 summary->set_in(3, Location::RequiresFpuRegister()); |
3096 // Low (< 7) Q registers are needed for the vcvtsd instruction. | 3287 // Low (< 7) Q registers are needed for the vcvtsd instruction. |
3097 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3288 summary->set_out(Location::FpuRegisterLocation(Q6)); |
(...skipping 11 matching lines...) Expand all Loading... |
3109 DRegister dr0 = EvenDRegisterOf(r); | 3300 DRegister dr0 = EvenDRegisterOf(r); |
3110 DRegister dr1 = OddDRegisterOf(r); | 3301 DRegister dr1 = OddDRegisterOf(r); |
3111 | 3302 |
3112 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); | 3303 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); |
3113 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); | 3304 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); |
3114 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); | 3305 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); |
3115 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); | 3306 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); |
3116 } | 3307 } |
3117 | 3308 |
3118 | 3309 |
3119 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { | 3310 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { |
3120 const intptr_t kNumInputs = 0; | 3311 const intptr_t kNumInputs = 0; |
3121 const intptr_t kNumTemps = 0; | 3312 const intptr_t kNumTemps = 0; |
3122 LocationSummary* summary = | 3313 LocationSummary* summary = |
3123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3314 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3124 summary->set_out(Location::RequiresFpuRegister()); | 3315 summary->set_out(Location::RequiresFpuRegister()); |
3125 return summary; | 3316 return summary; |
3126 } | 3317 } |
3127 | 3318 |
3128 | 3319 |
3129 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3320 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3130 QRegister q = locs()->out().fpu_reg(); | 3321 QRegister q = locs()->out().fpu_reg(); |
3131 __ veorq(q, q, q); | 3322 __ veorq(q, q, q); |
3132 } | 3323 } |
3133 | 3324 |
3134 | 3325 |
3135 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { | 3326 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { |
3136 const intptr_t kNumInputs = 1; | 3327 const intptr_t kNumInputs = 1; |
3137 const intptr_t kNumTemps = 0; | 3328 const intptr_t kNumTemps = 0; |
3138 LocationSummary* summary = | 3329 LocationSummary* summary = |
3139 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3330 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3140 summary->set_in(0, Location::RequiresFpuRegister()); | 3331 summary->set_in(0, Location::RequiresFpuRegister()); |
3141 summary->set_out(Location::RequiresFpuRegister()); | 3332 summary->set_out(Location::RequiresFpuRegister()); |
3142 return summary; | 3333 return summary; |
3143 } | 3334 } |
3144 | 3335 |
3145 | 3336 |
3146 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3337 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3147 QRegister value = locs()->in(0).fpu_reg(); | 3338 QRegister value = locs()->in(0).fpu_reg(); |
3148 QRegister result = locs()->out().fpu_reg(); | 3339 QRegister result = locs()->out().fpu_reg(); |
3149 | 3340 |
3150 DRegister dvalue0 = EvenDRegisterOf(value); | 3341 DRegister dvalue0 = EvenDRegisterOf(value); |
3151 | 3342 |
3152 // Convert to Float32. | 3343 // Convert to Float32. |
3153 __ vcvtsd(STMP, dvalue0); | 3344 __ vcvtsd(STMP, dvalue0); |
3154 | 3345 |
3155 // Splat across all lanes. | 3346 // Splat across all lanes. |
3156 __ vdup(kWord, result, DTMP, 0); | 3347 __ vdup(kWord, result, DTMP, 0); |
3157 } | 3348 } |
3158 | 3349 |
3159 | 3350 |
3160 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { | 3351 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { |
3161 const intptr_t kNumInputs = 2; | 3352 const intptr_t kNumInputs = 2; |
3162 const intptr_t kNumTemps = 0; | 3353 const intptr_t kNumTemps = 0; |
3163 LocationSummary* summary = | 3354 LocationSummary* summary = |
3164 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3165 summary->set_in(0, Location::RequiresFpuRegister()); | 3356 summary->set_in(0, Location::RequiresFpuRegister()); |
3166 summary->set_in(1, Location::RequiresFpuRegister()); | 3357 summary->set_in(1, Location::RequiresFpuRegister()); |
3167 summary->set_out(Location::RequiresFpuRegister()); | 3358 summary->set_out(Location::RequiresFpuRegister()); |
3168 return summary; | 3359 return summary; |
3169 } | 3360 } |
3170 | 3361 |
(...skipping 24 matching lines...) Expand all Loading... |
3195 break; | 3386 break; |
3196 case MethodRecognizer::kFloat32x4LessThanOrEqual: | 3387 case MethodRecognizer::kFloat32x4LessThanOrEqual: |
3197 __ vcgeqs(result, right, left); | 3388 __ vcgeqs(result, right, left); |
3198 break; | 3389 break; |
3199 | 3390 |
3200 default: UNREACHABLE(); | 3391 default: UNREACHABLE(); |
3201 } | 3392 } |
3202 } | 3393 } |
3203 | 3394 |
3204 | 3395 |
3205 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { | 3396 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { |
3206 const intptr_t kNumInputs = 2; | 3397 const intptr_t kNumInputs = 2; |
3207 const intptr_t kNumTemps = 0; | 3398 const intptr_t kNumTemps = 0; |
3208 LocationSummary* summary = | 3399 LocationSummary* summary = |
3209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3210 summary->set_in(0, Location::RequiresFpuRegister()); | 3401 summary->set_in(0, Location::RequiresFpuRegister()); |
3211 summary->set_in(1, Location::RequiresFpuRegister()); | 3402 summary->set_in(1, Location::RequiresFpuRegister()); |
3212 summary->set_out(Location::RequiresFpuRegister()); | 3403 summary->set_out(Location::RequiresFpuRegister()); |
3213 return summary; | 3404 return summary; |
3214 } | 3405 } |
3215 | 3406 |
3216 | 3407 |
3217 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3408 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3218 QRegister left = locs()->in(0).fpu_reg(); | 3409 QRegister left = locs()->in(0).fpu_reg(); |
3219 QRegister right = locs()->in(1).fpu_reg(); | 3410 QRegister right = locs()->in(1).fpu_reg(); |
3220 QRegister result = locs()->out().fpu_reg(); | 3411 QRegister result = locs()->out().fpu_reg(); |
3221 | 3412 |
3222 switch (op_kind()) { | 3413 switch (op_kind()) { |
3223 case MethodRecognizer::kFloat32x4Min: | 3414 case MethodRecognizer::kFloat32x4Min: |
3224 __ vminqs(result, left, right); | 3415 __ vminqs(result, left, right); |
3225 break; | 3416 break; |
3226 case MethodRecognizer::kFloat32x4Max: | 3417 case MethodRecognizer::kFloat32x4Max: |
3227 __ vmaxqs(result, left, right); | 3418 __ vmaxqs(result, left, right); |
3228 break; | 3419 break; |
3229 default: UNREACHABLE(); | 3420 default: UNREACHABLE(); |
3230 } | 3421 } |
3231 } | 3422 } |
3232 | 3423 |
3233 | 3424 |
3234 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { | 3425 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { |
3235 const intptr_t kNumInputs = 1; | 3426 const intptr_t kNumInputs = 1; |
3236 const intptr_t kNumTemps = 1; | 3427 const intptr_t kNumTemps = 1; |
3237 LocationSummary* summary = | 3428 LocationSummary* summary = |
3238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3429 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3239 summary->set_in(0, Location::RequiresFpuRegister()); | 3430 summary->set_in(0, Location::RequiresFpuRegister()); |
3240 summary->set_out(Location::RequiresFpuRegister()); | 3431 summary->set_out(Location::RequiresFpuRegister()); |
3241 summary->set_temp(0, Location::RequiresFpuRegister()); | 3432 summary->set_temp(0, Location::RequiresFpuRegister()); |
3242 return summary; | 3433 return summary; |
3243 } | 3434 } |
3244 | 3435 |
(...skipping 11 matching lines...) Expand all Loading... |
3256 __ Vreciprocalqs(result, left); | 3447 __ Vreciprocalqs(result, left); |
3257 break; | 3448 break; |
3258 case MethodRecognizer::kFloat32x4ReciprocalSqrt: | 3449 case MethodRecognizer::kFloat32x4ReciprocalSqrt: |
3259 __ VreciprocalSqrtqs(result, left); | 3450 __ VreciprocalSqrtqs(result, left); |
3260 break; | 3451 break; |
3261 default: UNREACHABLE(); | 3452 default: UNREACHABLE(); |
3262 } | 3453 } |
3263 } | 3454 } |
3264 | 3455 |
3265 | 3456 |
3266 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { | 3457 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { |
3267 const intptr_t kNumInputs = 2; | 3458 const intptr_t kNumInputs = 2; |
3268 const intptr_t kNumTemps = 0; | 3459 const intptr_t kNumTemps = 0; |
3269 LocationSummary* summary = | 3460 LocationSummary* summary = |
3270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3461 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3271 summary->set_in(0, Location::RequiresFpuRegister()); | 3462 summary->set_in(0, Location::RequiresFpuRegister()); |
3272 summary->set_in(1, Location::RequiresFpuRegister()); | 3463 summary->set_in(1, Location::RequiresFpuRegister()); |
3273 summary->set_out(Location::RequiresFpuRegister()); | 3464 summary->set_out(Location::RequiresFpuRegister()); |
3274 return summary; | 3465 return summary; |
3275 } | 3466 } |
3276 | 3467 |
3277 | 3468 |
3278 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3469 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3279 QRegister left = locs()->in(0).fpu_reg(); | 3470 QRegister left = locs()->in(0).fpu_reg(); |
3280 QRegister right = locs()->in(1).fpu_reg(); | 3471 QRegister right = locs()->in(1).fpu_reg(); |
3281 QRegister result = locs()->out().fpu_reg(); | 3472 QRegister result = locs()->out().fpu_reg(); |
3282 | 3473 |
3283 switch (op_kind()) { | 3474 switch (op_kind()) { |
3284 case MethodRecognizer::kFloat32x4Scale: | 3475 case MethodRecognizer::kFloat32x4Scale: |
3285 __ vcvtsd(STMP, EvenDRegisterOf(left)); | 3476 __ vcvtsd(STMP, EvenDRegisterOf(left)); |
3286 __ vdup(kWord, result, DTMP, 0); | 3477 __ vdup(kWord, result, DTMP, 0); |
3287 __ vmulqs(result, result, right); | 3478 __ vmulqs(result, result, right); |
3288 break; | 3479 break; |
3289 default: UNREACHABLE(); | 3480 default: UNREACHABLE(); |
3290 } | 3481 } |
3291 } | 3482 } |
3292 | 3483 |
3293 | 3484 |
3294 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { | 3485 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { |
3295 const intptr_t kNumInputs = 1; | 3486 const intptr_t kNumInputs = 1; |
3296 const intptr_t kNumTemps = 0; | 3487 const intptr_t kNumTemps = 0; |
3297 LocationSummary* summary = | 3488 LocationSummary* summary = |
3298 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3489 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3299 summary->set_in(0, Location::RequiresFpuRegister()); | 3490 summary->set_in(0, Location::RequiresFpuRegister()); |
3300 summary->set_out(Location::RequiresFpuRegister()); | 3491 summary->set_out(Location::RequiresFpuRegister()); |
3301 return summary; | 3492 return summary; |
3302 } | 3493 } |
3303 | 3494 |
3304 | 3495 |
3305 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3496 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3306 QRegister left = locs()->in(0).fpu_reg(); | 3497 QRegister left = locs()->in(0).fpu_reg(); |
3307 QRegister result = locs()->out().fpu_reg(); | 3498 QRegister result = locs()->out().fpu_reg(); |
3308 | 3499 |
3309 switch (op_kind()) { | 3500 switch (op_kind()) { |
3310 case MethodRecognizer::kFloat32x4Negate: | 3501 case MethodRecognizer::kFloat32x4Negate: |
3311 __ vnegqs(result, left); | 3502 __ vnegqs(result, left); |
3312 break; | 3503 break; |
3313 case MethodRecognizer::kFloat32x4Absolute: | 3504 case MethodRecognizer::kFloat32x4Absolute: |
3314 __ vabsqs(result, left); | 3505 __ vabsqs(result, left); |
3315 break; | 3506 break; |
3316 default: UNREACHABLE(); | 3507 default: UNREACHABLE(); |
3317 } | 3508 } |
3318 } | 3509 } |
3319 | 3510 |
3320 | 3511 |
3321 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { | 3512 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { |
3322 const intptr_t kNumInputs = 3; | 3513 const intptr_t kNumInputs = 3; |
3323 const intptr_t kNumTemps = 0; | 3514 const intptr_t kNumTemps = 0; |
3324 LocationSummary* summary = | 3515 LocationSummary* summary = |
3325 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3516 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3326 summary->set_in(0, Location::RequiresFpuRegister()); | 3517 summary->set_in(0, Location::RequiresFpuRegister()); |
3327 summary->set_in(1, Location::RequiresFpuRegister()); | 3518 summary->set_in(1, Location::RequiresFpuRegister()); |
3328 summary->set_in(2, Location::RequiresFpuRegister()); | 3519 summary->set_in(2, Location::RequiresFpuRegister()); |
3329 summary->set_out(Location::RequiresFpuRegister()); | 3520 summary->set_out(Location::RequiresFpuRegister()); |
3330 return summary; | 3521 return summary; |
3331 } | 3522 } |
3332 | 3523 |
3333 | 3524 |
3334 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3525 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3335 QRegister left = locs()->in(0).fpu_reg(); | 3526 QRegister left = locs()->in(0).fpu_reg(); |
3336 QRegister lower = locs()->in(1).fpu_reg(); | 3527 QRegister lower = locs()->in(1).fpu_reg(); |
3337 QRegister upper = locs()->in(2).fpu_reg(); | 3528 QRegister upper = locs()->in(2).fpu_reg(); |
3338 QRegister result = locs()->out().fpu_reg(); | 3529 QRegister result = locs()->out().fpu_reg(); |
3339 __ vminqs(result, left, upper); | 3530 __ vminqs(result, left, upper); |
3340 __ vmaxqs(result, result, lower); | 3531 __ vmaxqs(result, result, lower); |
3341 } | 3532 } |
3342 | 3533 |
3343 | 3534 |
3344 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { | 3535 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { |
3345 const intptr_t kNumInputs = 2; | 3536 const intptr_t kNumInputs = 2; |
3346 const intptr_t kNumTemps = 0; | 3537 const intptr_t kNumTemps = 0; |
3347 LocationSummary* summary = | 3538 LocationSummary* summary = |
3348 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3539 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3349 summary->set_in(0, Location::RequiresFpuRegister()); | 3540 summary->set_in(0, Location::RequiresFpuRegister()); |
3350 summary->set_in(1, Location::RequiresFpuRegister()); | 3541 summary->set_in(1, Location::RequiresFpuRegister()); |
3351 // Low (< 7) Q registers are needed for the vmovs instruction. | 3542 // Low (< 7) Q registers are needed for the vmovs instruction. |
3352 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3543 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3353 return summary; | 3544 return summary; |
3354 } | 3545 } |
(...skipping 27 matching lines...) Expand all Loading... |
3382 __ vmovs(sresult2, STMP); | 3573 __ vmovs(sresult2, STMP); |
3383 break; | 3574 break; |
3384 case MethodRecognizer::kFloat32x4WithW: | 3575 case MethodRecognizer::kFloat32x4WithW: |
3385 __ vmovs(sresult3, STMP); | 3576 __ vmovs(sresult3, STMP); |
3386 break; | 3577 break; |
3387 default: UNREACHABLE(); | 3578 default: UNREACHABLE(); |
3388 } | 3579 } |
3389 } | 3580 } |
3390 | 3581 |
3391 | 3582 |
3392 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { | 3583 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { |
3393 const intptr_t kNumInputs = 1; | 3584 const intptr_t kNumInputs = 1; |
3394 const intptr_t kNumTemps = 0; | 3585 const intptr_t kNumTemps = 0; |
3395 LocationSummary* summary = | 3586 LocationSummary* summary = |
3396 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3587 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3397 summary->set_in(0, Location::RequiresFpuRegister()); | 3588 summary->set_in(0, Location::RequiresFpuRegister()); |
3398 summary->set_out(Location::RequiresFpuRegister()); | 3589 summary->set_out(Location::RequiresFpuRegister()); |
3399 return summary; | 3590 return summary; |
3400 } | 3591 } |
3401 | 3592 |
3402 | 3593 |
3403 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3594 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3404 QRegister value = locs()->in(0).fpu_reg(); | 3595 QRegister value = locs()->in(0).fpu_reg(); |
3405 QRegister result = locs()->out().fpu_reg(); | 3596 QRegister result = locs()->out().fpu_reg(); |
3406 | 3597 |
3407 if (value != result) { | 3598 if (value != result) { |
3408 __ vmovq(result, value); | 3599 __ vmovq(result, value); |
3409 } | 3600 } |
3410 } | 3601 } |
3411 | 3602 |
3412 | 3603 |
3413 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { | 3604 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
| 3605 bool opt) const { |
3414 const intptr_t kNumInputs = 4; | 3606 const intptr_t kNumInputs = 4; |
3415 const intptr_t kNumTemps = 1; | 3607 const intptr_t kNumTemps = 1; |
3416 LocationSummary* summary = | 3608 LocationSummary* summary = |
3417 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3418 summary->set_in(0, Location::RequiresRegister()); | 3610 summary->set_in(0, Location::RequiresRegister()); |
3419 summary->set_in(1, Location::RequiresRegister()); | 3611 summary->set_in(1, Location::RequiresRegister()); |
3420 summary->set_in(2, Location::RequiresRegister()); | 3612 summary->set_in(2, Location::RequiresRegister()); |
3421 summary->set_in(3, Location::RequiresRegister()); | 3613 summary->set_in(3, Location::RequiresRegister()); |
3422 summary->set_temp(0, Location::RequiresRegister()); | 3614 summary->set_temp(0, Location::RequiresRegister()); |
3423 // Low (< 7) Q register needed for the vmovsr instruction. | 3615 // Low (< 7) Q register needed for the vmovsr instruction. |
(...skipping 26 matching lines...) Expand all Loading... |
3450 __ vmovsr(sresult1, temp, EQ); | 3642 __ vmovsr(sresult1, temp, EQ); |
3451 | 3643 |
3452 __ CompareObject(v2, Bool::True()); | 3644 __ CompareObject(v2, Bool::True()); |
3453 __ vmovsr(sresult2, temp, EQ); | 3645 __ vmovsr(sresult2, temp, EQ); |
3454 | 3646 |
3455 __ CompareObject(v3, Bool::True()); | 3647 __ CompareObject(v3, Bool::True()); |
3456 __ vmovsr(sresult3, temp, EQ); | 3648 __ vmovsr(sresult3, temp, EQ); |
3457 } | 3649 } |
3458 | 3650 |
3459 | 3651 |
3460 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { | 3652 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { |
3461 const intptr_t kNumInputs = 1; | 3653 const intptr_t kNumInputs = 1; |
3462 const intptr_t kNumTemps = 0; | 3654 const intptr_t kNumTemps = 0; |
3463 LocationSummary* summary = | 3655 LocationSummary* summary = |
3464 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3656 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3465 // Low (< 7) Q registers are needed for the vmovrs instruction. | 3657 // Low (< 7) Q registers are needed for the vmovrs instruction. |
3466 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 3658 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
3467 summary->set_out(Location::RequiresRegister()); | 3659 summary->set_out(Location::RequiresRegister()); |
3468 return summary; | 3660 return summary; |
3469 } | 3661 } |
3470 | 3662 |
(...skipping 24 matching lines...) Expand all Loading... |
3495 break; | 3687 break; |
3496 default: UNREACHABLE(); | 3688 default: UNREACHABLE(); |
3497 } | 3689 } |
3498 | 3690 |
3499 __ tst(result, ShifterOperand(result)); | 3691 __ tst(result, ShifterOperand(result)); |
3500 __ LoadObject(result, Bool::True(), NE); | 3692 __ LoadObject(result, Bool::True(), NE); |
3501 __ LoadObject(result, Bool::False(), EQ); | 3693 __ LoadObject(result, Bool::False(), EQ); |
3502 } | 3694 } |
3503 | 3695 |
3504 | 3696 |
3505 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { | 3697 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { |
3506 const intptr_t kNumInputs = 3; | 3698 const intptr_t kNumInputs = 3; |
3507 const intptr_t kNumTemps = 1; | 3699 const intptr_t kNumTemps = 1; |
3508 LocationSummary* summary = | 3700 LocationSummary* summary = |
3509 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3701 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3510 summary->set_in(0, Location::RequiresFpuRegister()); | 3702 summary->set_in(0, Location::RequiresFpuRegister()); |
3511 summary->set_in(1, Location::RequiresFpuRegister()); | 3703 summary->set_in(1, Location::RequiresFpuRegister()); |
3512 summary->set_in(2, Location::RequiresFpuRegister()); | 3704 summary->set_in(2, Location::RequiresFpuRegister()); |
3513 summary->set_temp(0, Location::RequiresFpuRegister()); | 3705 summary->set_temp(0, Location::RequiresFpuRegister()); |
3514 summary->set_out(Location::RequiresFpuRegister()); | 3706 summary->set_out(Location::RequiresFpuRegister()); |
3515 return summary; | 3707 return summary; |
(...skipping 14 matching lines...) Expand all Loading... |
3530 __ vornq(temp, QTMP, temp); // temp <- ~temp. | 3722 __ vornq(temp, QTMP, temp); // temp <- ~temp. |
3531 // mask = mask & trueValue. | 3723 // mask = mask & trueValue. |
3532 __ vandq(mask, mask, trueValue); | 3724 __ vandq(mask, mask, trueValue); |
3533 // temp = temp & falseValue. | 3725 // temp = temp & falseValue. |
3534 __ vandq(temp, temp, falseValue); | 3726 __ vandq(temp, temp, falseValue); |
3535 // out = mask | temp. | 3727 // out = mask | temp. |
3536 __ vorrq(out, mask, temp); | 3728 __ vorrq(out, mask, temp); |
3537 } | 3729 } |
3538 | 3730 |
3539 | 3731 |
3540 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { | 3732 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { |
3541 const intptr_t kNumInputs = 2; | 3733 const intptr_t kNumInputs = 2; |
3542 const intptr_t kNumTemps = 0; | 3734 const intptr_t kNumTemps = 0; |
3543 LocationSummary* summary = | 3735 LocationSummary* summary = |
3544 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3736 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3545 summary->set_in(0, Location::RequiresFpuRegister()); | 3737 summary->set_in(0, Location::RequiresFpuRegister()); |
3546 summary->set_in(1, Location::RequiresRegister()); | 3738 summary->set_in(1, Location::RequiresRegister()); |
3547 // Low (< 7) Q register needed for the vmovsr instruction. | 3739 // Low (< 7) Q register needed for the vmovsr instruction. |
3548 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3740 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3549 return summary; | 3741 return summary; |
3550 } | 3742 } |
(...skipping 29 matching lines...) Expand all Loading... |
3580 __ vmovsr(sresult2, TMP); | 3772 __ vmovsr(sresult2, TMP); |
3581 break; | 3773 break; |
3582 case MethodRecognizer::kInt32x4WithFlagW: | 3774 case MethodRecognizer::kInt32x4WithFlagW: |
3583 __ vmovsr(sresult3, TMP); | 3775 __ vmovsr(sresult3, TMP); |
3584 break; | 3776 break; |
3585 default: UNREACHABLE(); | 3777 default: UNREACHABLE(); |
3586 } | 3778 } |
3587 } | 3779 } |
3588 | 3780 |
3589 | 3781 |
3590 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3782 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { |
3591 const intptr_t kNumInputs = 1; | 3783 const intptr_t kNumInputs = 1; |
3592 const intptr_t kNumTemps = 0; | 3784 const intptr_t kNumTemps = 0; |
3593 LocationSummary* summary = | 3785 LocationSummary* summary = |
3594 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3786 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3595 summary->set_in(0, Location::RequiresFpuRegister()); | 3787 summary->set_in(0, Location::RequiresFpuRegister()); |
3596 summary->set_out(Location::RequiresFpuRegister()); | 3788 summary->set_out(Location::RequiresFpuRegister()); |
3597 return summary; | 3789 return summary; |
3598 } | 3790 } |
3599 | 3791 |
3600 | 3792 |
3601 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3793 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3602 QRegister value = locs()->in(0).fpu_reg(); | 3794 QRegister value = locs()->in(0).fpu_reg(); |
3603 QRegister result = locs()->out().fpu_reg(); | 3795 QRegister result = locs()->out().fpu_reg(); |
3604 | 3796 |
3605 if (value != result) { | 3797 if (value != result) { |
3606 __ vmovq(result, value); | 3798 __ vmovq(result, value); |
3607 } | 3799 } |
3608 } | 3800 } |
3609 | 3801 |
3610 | 3802 |
3611 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { | 3803 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { |
3612 const intptr_t kNumInputs = 2; | 3804 const intptr_t kNumInputs = 2; |
3613 const intptr_t kNumTemps = 0; | 3805 const intptr_t kNumTemps = 0; |
3614 LocationSummary* summary = | 3806 LocationSummary* summary = |
3615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3807 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3616 summary->set_in(0, Location::RequiresFpuRegister()); | 3808 summary->set_in(0, Location::RequiresFpuRegister()); |
3617 summary->set_in(1, Location::RequiresFpuRegister()); | 3809 summary->set_in(1, Location::RequiresFpuRegister()); |
3618 summary->set_out(Location::RequiresFpuRegister()); | 3810 summary->set_out(Location::RequiresFpuRegister()); |
3619 return summary; | 3811 return summary; |
3620 } | 3812 } |
3621 | 3813 |
(...skipping 19 matching lines...) Expand all Loading... |
3641 __ vaddqi(kWord, result, left, right); | 3833 __ vaddqi(kWord, result, left, right); |
3642 break; | 3834 break; |
3643 case Token::kSUB: | 3835 case Token::kSUB: |
3644 __ vsubqi(kWord, result, left, right); | 3836 __ vsubqi(kWord, result, left, right); |
3645 break; | 3837 break; |
3646 default: UNREACHABLE(); | 3838 default: UNREACHABLE(); |
3647 } | 3839 } |
3648 } | 3840 } |
3649 | 3841 |
3650 | 3842 |
3651 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { | 3843 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
3652 if ((kind() == MethodRecognizer::kMathSin) || | 3844 if ((kind() == MethodRecognizer::kMathSin) || |
3653 (kind() == MethodRecognizer::kMathCos)) { | 3845 (kind() == MethodRecognizer::kMathCos)) { |
3654 const intptr_t kNumInputs = 1; | 3846 const intptr_t kNumInputs = 1; |
3655 const intptr_t kNumTemps = 0; | 3847 const intptr_t kNumTemps = 0; |
3656 LocationSummary* summary = | 3848 LocationSummary* summary = |
3657 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 3849 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
3658 summary->set_in(0, Location::FpuRegisterLocation(Q0)); | 3850 summary->set_in(0, Location::FpuRegisterLocation(Q0)); |
3659 summary->set_out(Location::FpuRegisterLocation(Q0)); | 3851 summary->set_out(Location::FpuRegisterLocation(Q0)); |
3660 #if !defined(ARM_FLOAT_ABI_HARD) | 3852 #if !defined(ARM_FLOAT_ABI_HARD) |
3661 summary->AddTemp(Location::RegisterLocation(R0)); | 3853 summary->AddTemp(Location::RegisterLocation(R0)); |
(...skipping 29 matching lines...) Expand all Loading... |
3691 __ vmovrrd(R0, R1, D0); | 3883 __ vmovrrd(R0, R1, D0); |
3692 __ vmovrrd(R2, R3, D1); | 3884 __ vmovrrd(R2, R3, D1); |
3693 __ CallRuntime(TargetFunction(), InputCount()); | 3885 __ CallRuntime(TargetFunction(), InputCount()); |
3694 __ vmovdrr(D0, R0, R1); | 3886 __ vmovdrr(D0, R0, R1); |
3695 __ vmovdrr(D1, R2, R3); | 3887 __ vmovdrr(D1, R2, R3); |
3696 #endif | 3888 #endif |
3697 } | 3889 } |
3698 } | 3890 } |
3699 | 3891 |
3700 | 3892 |
3701 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3893 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
3702 if (result_cid() == kDoubleCid) { | 3894 if (result_cid() == kDoubleCid) { |
3703 const intptr_t kNumInputs = 2; | 3895 const intptr_t kNumInputs = 2; |
3704 const intptr_t kNumTemps = 1; | 3896 const intptr_t kNumTemps = 1; |
3705 LocationSummary* summary = | 3897 LocationSummary* summary = |
3706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3898 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3707 summary->set_in(0, Location::RequiresFpuRegister()); | 3899 summary->set_in(0, Location::RequiresFpuRegister()); |
3708 summary->set_in(1, Location::RequiresFpuRegister()); | 3900 summary->set_in(1, Location::RequiresFpuRegister()); |
3709 // Reuse the left register so that code can be made shorter. | 3901 // Reuse the left register so that code can be made shorter. |
3710 summary->set_out(Location::SameAsFirstInput()); | 3902 summary->set_out(Location::SameAsFirstInput()); |
3711 summary->set_temp(0, Location::RequiresRegister()); | 3903 summary->set_temp(0, Location::RequiresRegister()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3776 __ cmp(left, ShifterOperand(right)); | 3968 __ cmp(left, ShifterOperand(right)); |
3777 ASSERT(result == left); | 3969 ASSERT(result == left); |
3778 if (is_min) { | 3970 if (is_min) { |
3779 __ mov(result, ShifterOperand(right), GT); | 3971 __ mov(result, ShifterOperand(right), GT); |
3780 } else { | 3972 } else { |
3781 __ mov(result, ShifterOperand(right), LT); | 3973 __ mov(result, ShifterOperand(right), LT); |
3782 } | 3974 } |
3783 } | 3975 } |
3784 | 3976 |
3785 | 3977 |
3786 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3978 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { |
3787 const intptr_t kNumInputs = 1; | 3979 const intptr_t kNumInputs = 1; |
3788 const intptr_t kNumTemps = 0; | 3980 const intptr_t kNumTemps = 0; |
3789 LocationSummary* summary = | 3981 LocationSummary* summary = |
3790 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3982 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3791 summary->set_in(0, Location::RequiresRegister()); | 3983 summary->set_in(0, Location::RequiresRegister()); |
3792 // We make use of 3-operand instructions by not requiring result register | 3984 // We make use of 3-operand instructions by not requiring result register |
3793 // to be identical to first input register as on Intel. | 3985 // to be identical to first input register as on Intel. |
3794 summary->set_out(Location::RequiresRegister()); | 3986 summary->set_out(Location::RequiresRegister()); |
3795 return summary; | 3987 return summary; |
3796 } | 3988 } |
(...skipping 14 matching lines...) Expand all Loading... |
3811 __ mvn(result, ShifterOperand(value)); | 4003 __ mvn(result, ShifterOperand(value)); |
3812 // Remove inverted smi-tag. | 4004 // Remove inverted smi-tag. |
3813 __ bic(result, result, ShifterOperand(kSmiTagMask)); | 4005 __ bic(result, result, ShifterOperand(kSmiTagMask)); |
3814 break; | 4006 break; |
3815 default: | 4007 default: |
3816 UNREACHABLE(); | 4008 UNREACHABLE(); |
3817 } | 4009 } |
3818 } | 4010 } |
3819 | 4011 |
3820 | 4012 |
3821 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { | 4013 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
3822 const intptr_t kNumInputs = 1; | 4014 const intptr_t kNumInputs = 1; |
3823 const intptr_t kNumTemps = 0; | 4015 const intptr_t kNumTemps = 0; |
3824 LocationSummary* summary = | 4016 LocationSummary* summary = |
3825 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4017 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3826 summary->set_in(0, Location::RequiresFpuRegister()); | 4018 summary->set_in(0, Location::RequiresFpuRegister()); |
3827 summary->set_out(Location::RequiresFpuRegister()); | 4019 summary->set_out(Location::RequiresFpuRegister()); |
3828 return summary; | 4020 return summary; |
3829 } | 4021 } |
3830 | 4022 |
3831 | 4023 |
3832 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4024 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3833 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4025 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
3834 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4026 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
3835 __ vnegd(result, value); | 4027 __ vnegd(result, value); |
3836 } | 4028 } |
3837 | 4029 |
3838 | 4030 |
3839 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 4031 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { |
3840 const intptr_t kNumInputs = 1; | 4032 const intptr_t kNumInputs = 1; |
3841 const intptr_t kNumTemps = 0; | 4033 const intptr_t kNumTemps = 0; |
3842 LocationSummary* result = | 4034 LocationSummary* result = |
3843 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4035 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3844 result->set_in(0, Location::WritableRegister()); | 4036 result->set_in(0, Location::WritableRegister()); |
3845 result->set_out(Location::RequiresFpuRegister()); | 4037 result->set_out(Location::RequiresFpuRegister()); |
3846 return result; | 4038 return result; |
3847 } | 4039 } |
3848 | 4040 |
3849 | 4041 |
3850 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4042 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3851 Register value = locs()->in(0).reg(); | 4043 Register value = locs()->in(0).reg(); |
3852 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); | 4044 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); |
3853 __ SmiUntag(value); | 4045 __ SmiUntag(value); |
3854 __ vmovsr(STMP, value); | 4046 __ vmovsr(STMP, value); |
3855 __ vcvtdi(result, STMP); | 4047 __ vcvtdi(result, STMP); |
3856 } | 4048 } |
3857 | 4049 |
3858 | 4050 |
3859 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { | 4051 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { |
3860 const intptr_t kNumInputs = 1; | 4052 const intptr_t kNumInputs = 1; |
3861 const intptr_t kNumTemps = 0; | 4053 const intptr_t kNumTemps = 0; |
3862 LocationSummary* result = | 4054 LocationSummary* result = |
3863 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4055 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
3864 result->set_in(0, Location::RegisterLocation(R1)); | 4056 result->set_in(0, Location::RegisterLocation(R1)); |
3865 result->set_out(Location::RegisterLocation(R0)); | 4057 result->set_out(Location::RegisterLocation(R0)); |
3866 return result; | 4058 return result; |
3867 } | 4059 } |
3868 | 4060 |
3869 | 4061 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3901 compiler->GenerateStaticCall(deopt_id(), | 4093 compiler->GenerateStaticCall(deopt_id(), |
3902 instance_call()->token_pos(), | 4094 instance_call()->token_pos(), |
3903 target, | 4095 target, |
3904 kNumberOfArguments, | 4096 kNumberOfArguments, |
3905 Object::null_array(), // No argument names., | 4097 Object::null_array(), // No argument names., |
3906 locs()); | 4098 locs()); |
3907 __ Bind(&done); | 4099 __ Bind(&done); |
3908 } | 4100 } |
3909 | 4101 |
3910 | 4102 |
3911 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { | 4103 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { |
3912 const intptr_t kNumInputs = 1; | 4104 const intptr_t kNumInputs = 1; |
3913 const intptr_t kNumTemps = 0; | 4105 const intptr_t kNumTemps = 0; |
3914 LocationSummary* result = new LocationSummary( | 4106 LocationSummary* result = new LocationSummary( |
3915 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4107 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3916 result->set_in(0, Location::RequiresFpuRegister()); | 4108 result->set_in(0, Location::RequiresFpuRegister()); |
3917 result->set_out(Location::RequiresRegister()); | 4109 result->set_out(Location::RequiresRegister()); |
3918 return result; | 4110 return result; |
3919 } | 4111 } |
3920 | 4112 |
3921 | 4113 |
3922 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4114 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3923 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4115 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); |
3924 Register result = locs()->out().reg(); | 4116 Register result = locs()->out().reg(); |
3925 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4117 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
3926 // First check for NaN. Checking for minint after the conversion doesn't work | 4118 // First check for NaN. Checking for minint after the conversion doesn't work |
3927 // on ARM because vcvtid gives 0 for NaN. | 4119 // on ARM because vcvtid gives 0 for NaN. |
3928 __ vcmpd(value, value); | 4120 __ vcmpd(value, value); |
3929 __ vmstat(); | 4121 __ vmstat(); |
3930 __ b(deopt, VS); | 4122 __ b(deopt, VS); |
3931 | 4123 |
3932 __ vcvtid(STMP, value); | 4124 __ vcvtid(STMP, value); |
3933 __ vmovrs(result, STMP); | 4125 __ vmovrs(result, STMP); |
3934 // Check for overflow and that it fits into Smi. | 4126 // Check for overflow and that it fits into Smi. |
3935 __ CompareImmediate(result, 0xC0000000); | 4127 __ CompareImmediate(result, 0xC0000000); |
3936 __ b(deopt, MI); | 4128 __ b(deopt, MI); |
3937 __ SmiTag(result); | 4129 __ SmiTag(result); |
3938 } | 4130 } |
3939 | 4131 |
3940 | 4132 |
3941 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 4133 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { |
3942 const intptr_t kNumInputs = 1; | 4134 const intptr_t kNumInputs = 1; |
3943 const intptr_t kNumTemps = 0; | 4135 const intptr_t kNumTemps = 0; |
3944 LocationSummary* result = | 4136 LocationSummary* result = |
3945 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4137 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3946 result->set_in(0, Location::RequiresFpuRegister()); | 4138 result->set_in(0, Location::RequiresFpuRegister()); |
3947 result->set_out(Location::RequiresFpuRegister()); | 4139 result->set_out(Location::RequiresFpuRegister()); |
3948 return result; | 4140 return result; |
3949 } | 4141 } |
3950 | 4142 |
3951 | 4143 |
(...skipping 12 matching lines...) Expand all Loading... |
3964 case MethodRecognizer::kDoubleCeil: | 4156 case MethodRecognizer::kDoubleCeil: |
3965 UNIMPLEMENTED(); | 4157 UNIMPLEMENTED(); |
3966 // __ roundsd(result, value, Assembler::kRoundUp); | 4158 // __ roundsd(result, value, Assembler::kRoundUp); |
3967 break; | 4159 break; |
3968 default: | 4160 default: |
3969 UNREACHABLE(); | 4161 UNREACHABLE(); |
3970 } | 4162 } |
3971 } | 4163 } |
3972 | 4164 |
3973 | 4165 |
3974 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 4166 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { |
3975 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 4167 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
3976 const intptr_t kNumTemps = 0; | 4168 const intptr_t kNumTemps = 0; |
3977 LocationSummary* result = | 4169 LocationSummary* result = |
3978 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 4170 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
3979 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 4171 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
3980 if (InputCount() == 2) { | 4172 if (InputCount() == 2) { |
3981 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 4173 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
3982 } | 4174 } |
3983 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 4175 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
3984 result->AddTemp(Location::RegisterLocation(R2)); | 4176 result->AddTemp(Location::RegisterLocation(R2)); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4048 __ vmovrrd(R0, R1, D0); | 4240 __ vmovrrd(R0, R1, D0); |
4049 __ vmovrrd(R2, R3, D1); | 4241 __ vmovrrd(R2, R3, D1); |
4050 __ CallRuntime(TargetFunction(), InputCount()); | 4242 __ CallRuntime(TargetFunction(), InputCount()); |
4051 __ vmovdrr(D0, R0, R1); | 4243 __ vmovdrr(D0, R0, R1); |
4052 __ vmovdrr(D1, R2, R3); | 4244 __ vmovdrr(D1, R2, R3); |
4053 #endif | 4245 #endif |
4054 __ Bind(&skip_call); | 4246 __ Bind(&skip_call); |
4055 } | 4247 } |
4056 | 4248 |
4057 | 4249 |
4058 LocationSummary* MergedMathInstr::MakeLocationSummary() const { | 4250 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { |
4059 if (kind() == MergedMathInstr::kTruncDivMod) { | 4251 if (kind() == MergedMathInstr::kTruncDivMod) { |
4060 const intptr_t kNumInputs = 2; | 4252 const intptr_t kNumInputs = 2; |
4061 const intptr_t kNumTemps = 4; | 4253 const intptr_t kNumTemps = 4; |
4062 LocationSummary* summary = | 4254 LocationSummary* summary = |
4063 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4064 summary->set_in(0, Location::RequiresRegister()); | 4256 summary->set_in(0, Location::RequiresRegister()); |
4065 summary->set_in(1, Location::RequiresRegister()); | 4257 summary->set_in(1, Location::RequiresRegister()); |
4066 summary->set_temp(0, Location::RequiresRegister()); | 4258 summary->set_temp(0, Location::RequiresRegister()); |
4067 summary->set_temp(1, Location::RequiresFpuRegister()); | 4259 summary->set_temp(1, Location::RequiresFpuRegister()); |
4068 summary->set_temp(2, Location::RequiresRegister()); // result_div. | 4260 summary->set_temp(2, Location::RequiresRegister()); // result_div. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4137 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); | 4329 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); |
4138 return; | 4330 return; |
4139 } | 4331 } |
4140 if (kind() == MergedMathInstr::kSinCos) { | 4332 if (kind() == MergedMathInstr::kSinCos) { |
4141 UNIMPLEMENTED(); | 4333 UNIMPLEMENTED(); |
4142 } | 4334 } |
4143 UNIMPLEMENTED(); | 4335 UNIMPLEMENTED(); |
4144 } | 4336 } |
4145 | 4337 |
4146 | 4338 |
4147 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4339 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 4340 bool opt) const { |
4148 return MakeCallSummary(); | 4341 return MakeCallSummary(); |
4149 } | 4342 } |
4150 | 4343 |
4151 | 4344 |
4152 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4345 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4153 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4346 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
4154 kDeoptPolymorphicInstanceCallTestFail); | 4347 kDeoptPolymorphicInstanceCallTestFail); |
4155 if (ic_data().NumberOfChecks() == 0) { | 4348 if (ic_data().NumberOfChecks() == 0) { |
4156 __ b(deopt); | 4349 __ b(deopt); |
4157 return; | 4350 return; |
(...skipping 22 matching lines...) Expand all Loading... |
4180 R2, // Class id register. | 4373 R2, // Class id register. |
4181 instance_call()->ArgumentCount(), | 4374 instance_call()->ArgumentCount(), |
4182 instance_call()->argument_names(), | 4375 instance_call()->argument_names(), |
4183 deopt, | 4376 deopt, |
4184 deopt_id(), | 4377 deopt_id(), |
4185 instance_call()->token_pos(), | 4378 instance_call()->token_pos(), |
4186 locs()); | 4379 locs()); |
4187 } | 4380 } |
4188 | 4381 |
4189 | 4382 |
4190 LocationSummary* BranchInstr::MakeLocationSummary() const { | 4383 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { |
4191 UNREACHABLE(); | 4384 comparison()->InitializeLocationSummary(opt); |
4192 return NULL; | 4385 // Branches don't produce a result. |
| 4386 comparison()->locs()->set_out(Location::NoLocation()); |
| 4387 return comparison()->locs(); |
4193 } | 4388 } |
4194 | 4389 |
4195 | 4390 |
4196 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4391 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4197 comparison()->EmitBranchCode(compiler, this); | 4392 comparison()->EmitBranchCode(compiler, this); |
4198 } | 4393 } |
4199 | 4394 |
4200 | 4395 |
4201 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 4396 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
4202 const intptr_t kNumInputs = 1; | 4397 const intptr_t kNumInputs = 1; |
4203 const intptr_t kNumTemps = 0; | 4398 const intptr_t kNumTemps = 0; |
4204 LocationSummary* summary = | 4399 LocationSummary* summary = |
4205 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4206 summary->set_in(0, Location::RequiresRegister()); | 4401 summary->set_in(0, Location::RequiresRegister()); |
4207 if (!IsNullCheck()) { | 4402 if (!IsNullCheck()) { |
4208 summary->AddTemp(Location::RequiresRegister()); | 4403 summary->AddTemp(Location::RequiresRegister()); |
4209 } | 4404 } |
4210 return summary; | 4405 return summary; |
4211 } | 4406 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4245 if (i == (num_checks - 1)) { | 4440 if (i == (num_checks - 1)) { |
4246 __ b(deopt, NE); | 4441 __ b(deopt, NE); |
4247 } else { | 4442 } else { |
4248 __ b(&is_ok, EQ); | 4443 __ b(&is_ok, EQ); |
4249 } | 4444 } |
4250 } | 4445 } |
4251 __ Bind(&is_ok); | 4446 __ Bind(&is_ok); |
4252 } | 4447 } |
4253 | 4448 |
4254 | 4449 |
4255 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 4450 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { |
4256 const intptr_t kNumInputs = 1; | 4451 const intptr_t kNumInputs = 1; |
4257 const intptr_t kNumTemps = 0; | 4452 const intptr_t kNumTemps = 0; |
4258 LocationSummary* summary = | 4453 LocationSummary* summary = |
4259 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4454 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4260 summary->set_in(0, Location::RequiresRegister()); | 4455 summary->set_in(0, Location::RequiresRegister()); |
4261 return summary; | 4456 return summary; |
4262 } | 4457 } |
4263 | 4458 |
4264 | 4459 |
4265 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4460 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4266 Register value = locs()->in(0).reg(); | 4461 Register value = locs()->in(0).reg(); |
4267 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4462 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
4268 kDeoptCheckSmi); | 4463 kDeoptCheckSmi); |
4269 __ tst(value, ShifterOperand(kSmiTagMask)); | 4464 __ tst(value, ShifterOperand(kSmiTagMask)); |
4270 __ b(deopt, NE); | 4465 __ b(deopt, NE); |
4271 } | 4466 } |
4272 | 4467 |
4273 | 4468 |
4274 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 4469 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
4275 const intptr_t kNumInputs = 2; | 4470 const intptr_t kNumInputs = 2; |
4276 const intptr_t kNumTemps = 0; | 4471 const intptr_t kNumTemps = 0; |
4277 LocationSummary* locs = | 4472 LocationSummary* locs = |
4278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4473 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4279 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4474 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
4280 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 4475 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
4281 return locs; | 4476 return locs; |
4282 } | 4477 } |
4283 | 4478 |
4284 | 4479 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4317 __ b(deopt, CS); | 4512 __ b(deopt, CS); |
4318 } else { | 4513 } else { |
4319 Register length = length_loc.reg(); | 4514 Register length = length_loc.reg(); |
4320 Register index = index_loc.reg(); | 4515 Register index = index_loc.reg(); |
4321 __ cmp(index, ShifterOperand(length)); | 4516 __ cmp(index, ShifterOperand(length)); |
4322 __ b(deopt, CS); | 4517 __ b(deopt, CS); |
4323 } | 4518 } |
4324 } | 4519 } |
4325 | 4520 |
4326 | 4521 |
4327 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 4522 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
4328 UNIMPLEMENTED(); | 4523 UNIMPLEMENTED(); |
4329 return NULL; | 4524 return NULL; |
4330 } | 4525 } |
4331 | 4526 |
4332 | 4527 |
4333 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4528 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4334 UNIMPLEMENTED(); | 4529 UNIMPLEMENTED(); |
4335 } | 4530 } |
4336 | 4531 |
4337 | 4532 |
4338 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { | 4533 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const { |
4339 UNIMPLEMENTED(); | 4534 UNIMPLEMENTED(); |
4340 return NULL; | 4535 return NULL; |
4341 } | 4536 } |
4342 | 4537 |
4343 | 4538 |
4344 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4539 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4345 UNIMPLEMENTED(); | 4540 UNIMPLEMENTED(); |
4346 } | 4541 } |
4347 | 4542 |
4348 | 4543 |
4349 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 4544 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
4350 UNIMPLEMENTED(); | 4545 UNIMPLEMENTED(); |
4351 return NULL; | 4546 return NULL; |
4352 } | 4547 } |
4353 | 4548 |
4354 | 4549 |
4355 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4550 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4356 UNIMPLEMENTED(); | 4551 UNIMPLEMENTED(); |
4357 } | 4552 } |
4358 | 4553 |
4359 | 4554 |
4360 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { | 4555 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
4361 UNIMPLEMENTED(); | 4556 UNIMPLEMENTED(); |
4362 return NULL; | 4557 return NULL; |
4363 } | 4558 } |
4364 | 4559 |
4365 | 4560 |
4366 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4561 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4367 UNIMPLEMENTED(); | 4562 UNIMPLEMENTED(); |
4368 } | 4563 } |
4369 | 4564 |
4370 | 4565 |
4371 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { | 4566 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
4372 UNIMPLEMENTED(); | 4567 UNIMPLEMENTED(); |
4373 return NULL; | 4568 return NULL; |
4374 } | 4569 } |
4375 | 4570 |
4376 | 4571 |
4377 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4572 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4378 UNIMPLEMENTED(); | 4573 UNIMPLEMENTED(); |
4379 } | 4574 } |
4380 | 4575 |
4381 | 4576 |
4382 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 4577 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const { |
4383 return new LocationSummary(0, 0, LocationSummary::kCall); | 4578 return new LocationSummary(0, 0, LocationSummary::kCall); |
4384 } | 4579 } |
4385 | 4580 |
4386 | 4581 |
4387 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4582 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4388 compiler->GenerateRuntimeCall(token_pos(), | 4583 compiler->GenerateRuntimeCall(token_pos(), |
4389 deopt_id(), | 4584 deopt_id(), |
4390 kThrowRuntimeEntry, | 4585 kThrowRuntimeEntry, |
4391 1, | 4586 1, |
4392 locs()); | 4587 locs()); |
4393 __ bkpt(0); | 4588 __ bkpt(0); |
4394 } | 4589 } |
4395 | 4590 |
4396 | 4591 |
4397 LocationSummary* ReThrowInstr::MakeLocationSummary() const { | 4592 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const { |
4398 return new LocationSummary(0, 0, LocationSummary::kCall); | 4593 return new LocationSummary(0, 0, LocationSummary::kCall); |
4399 } | 4594 } |
4400 | 4595 |
4401 | 4596 |
4402 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4597 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4403 compiler->SetNeedsStacktrace(catch_try_index()); | 4598 compiler->SetNeedsStacktrace(catch_try_index()); |
4404 compiler->GenerateRuntimeCall(token_pos(), | 4599 compiler->GenerateRuntimeCall(token_pos(), |
4405 deopt_id(), | 4600 deopt_id(), |
4406 kReThrowRuntimeEntry, | 4601 kReThrowRuntimeEntry, |
4407 2, | 4602 2, |
(...skipping 20 matching lines...) Expand all Loading... |
4428 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4623 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
4429 deopt_id_, | 4624 deopt_id_, |
4430 Scanner::kDummyTokenIndex); | 4625 Scanner::kDummyTokenIndex); |
4431 } | 4626 } |
4432 if (HasParallelMove()) { | 4627 if (HasParallelMove()) { |
4433 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 4628 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
4434 } | 4629 } |
4435 } | 4630 } |
4436 | 4631 |
4437 | 4632 |
4438 LocationSummary* GotoInstr::MakeLocationSummary() const { | 4633 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { |
4439 return new LocationSummary(0, 0, LocationSummary::kNoCall); | 4634 return new LocationSummary(0, 0, LocationSummary::kNoCall); |
4440 } | 4635 } |
4441 | 4636 |
4442 | 4637 |
4443 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4638 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4444 if (!compiler->is_optimizing()) { | 4639 if (!compiler->is_optimizing()) { |
4445 compiler->EmitEdgeCounter(); | 4640 compiler->EmitEdgeCounter(); |
4446 // Add a deoptimization descriptor for deoptimizing instructions that | 4641 // Add a deoptimization descriptor for deoptimizing instructions that |
4447 // may be inserted before this instruction. On ARM this descriptor | 4642 // may be inserted before this instruction. On ARM this descriptor |
4448 // points after the edge counter code so that we can reuse the same | 4643 // points after the edge counter code so that we can reuse the same |
4449 // pattern matching code as at call sites, which matches backwards from | 4644 // pattern matching code as at call sites, which matches backwards from |
4450 // the end of the pattern. | 4645 // the end of the pattern. |
4451 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 4646 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
4452 GetDeoptId(), | 4647 GetDeoptId(), |
4453 Scanner::kDummyTokenIndex); | 4648 Scanner::kDummyTokenIndex); |
4454 } | 4649 } |
4455 if (HasParallelMove()) { | 4650 if (HasParallelMove()) { |
4456 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 4651 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
4457 } | 4652 } |
4458 | 4653 |
4459 // We can fall through if the successor is the next block in the list. | 4654 // We can fall through if the successor is the next block in the list. |
4460 // Otherwise, we need a jump. | 4655 // Otherwise, we need a jump. |
4461 if (!compiler->CanFallThroughTo(successor())) { | 4656 if (!compiler->CanFallThroughTo(successor())) { |
4462 __ b(compiler->GetJumpLabel(successor())); | 4657 __ b(compiler->GetJumpLabel(successor())); |
4463 } | 4658 } |
4464 } | 4659 } |
4465 | 4660 |
4466 | 4661 |
4467 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 4662 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { |
4468 return LocationSummary::Make(0, | 4663 return LocationSummary::Make(0, |
4469 Location::RequiresRegister(), | 4664 Location::RequiresRegister(), |
4470 LocationSummary::kNoCall); | 4665 LocationSummary::kNoCall); |
4471 } | 4666 } |
4472 | 4667 |
4473 | 4668 |
4474 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4669 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4475 __ mov(locs()->out().reg(), ShifterOperand(CTX)); | 4670 __ mov(locs()->out().reg(), ShifterOperand(CTX)); |
4476 } | 4671 } |
4477 | 4672 |
4478 | 4673 |
4479 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { | 4674 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { |
4480 const intptr_t kNumInputs = 2; | 4675 const intptr_t kNumInputs = 2; |
4481 const intptr_t kNumTemps = 0; | 4676 const intptr_t kNumTemps = 0; |
4482 if (needs_number_check()) { | 4677 if (needs_number_check()) { |
4483 LocationSummary* locs = | 4678 LocationSummary* locs = |
4484 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
4485 locs->set_in(0, Location::RegisterLocation(R0)); | 4680 locs->set_in(0, Location::RegisterLocation(R0)); |
4486 locs->set_in(1, Location::RegisterLocation(R1)); | 4681 locs->set_in(1, Location::RegisterLocation(R1)); |
4487 locs->set_out(Location::RegisterLocation(R0)); | 4682 locs->set_out(Location::RegisterLocation(R0)); |
4488 return locs; | 4683 return locs; |
4489 } | 4684 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4542 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 4737 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
4543 BranchInstr* branch) { | 4738 BranchInstr* branch) { |
4544 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4739 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
4545 | 4740 |
4546 BranchLabels labels = compiler->CreateBranchLabels(branch); | 4741 BranchLabels labels = compiler->CreateBranchLabels(branch); |
4547 Condition true_condition = EmitComparisonCode(compiler, labels); | 4742 Condition true_condition = EmitComparisonCode(compiler, labels); |
4548 EmitBranchOnCondition(compiler, true_condition, labels); | 4743 EmitBranchOnCondition(compiler, true_condition, labels); |
4549 } | 4744 } |
4550 | 4745 |
4551 | 4746 |
4552 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { | 4747 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { |
4553 return LocationSummary::Make(1, | 4748 return LocationSummary::Make(1, |
4554 Location::RequiresRegister(), | 4749 Location::RequiresRegister(), |
4555 LocationSummary::kNoCall); | 4750 LocationSummary::kNoCall); |
4556 } | 4751 } |
4557 | 4752 |
4558 | 4753 |
4559 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4754 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4560 Register value = locs()->in(0).reg(); | 4755 Register value = locs()->in(0).reg(); |
4561 Register result = locs()->out().reg(); | 4756 Register result = locs()->out().reg(); |
4562 | 4757 |
4563 __ LoadObject(result, Bool::True()); | 4758 __ LoadObject(result, Bool::True()); |
4564 __ cmp(result, ShifterOperand(value)); | 4759 __ cmp(result, ShifterOperand(value)); |
4565 __ LoadObject(result, Bool::False(), EQ); | 4760 __ LoadObject(result, Bool::False(), EQ); |
4566 } | 4761 } |
4567 | 4762 |
4568 | 4763 |
4569 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { | 4764 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const { |
4570 const intptr_t kNumInputs = 2; | 4765 const intptr_t kNumInputs = 2; |
4571 const intptr_t kNumTemps = 0; | 4766 const intptr_t kNumTemps = 0; |
4572 LocationSummary* locs = | 4767 LocationSummary* locs = |
4573 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4768 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4574 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() | 4769 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() |
4575 : Location::RequiresRegister()); | 4770 : Location::RequiresRegister()); |
4576 locs->set_in(1, Location::RequiresRegister()); | 4771 locs->set_in(1, Location::RequiresRegister()); |
4577 return locs; | 4772 return locs; |
4578 } | 4773 } |
4579 | 4774 |
4580 | 4775 |
4581 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4776 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4582 Register value_reg = locs()->in(0).reg(); | 4777 Register value_reg = locs()->in(0).reg(); |
4583 Register dest_reg = locs()->in(1).reg(); | 4778 Register dest_reg = locs()->in(1).reg(); |
4584 | 4779 |
4585 if (value()->NeedsStoreBuffer()) { | 4780 if (value()->NeedsStoreBuffer()) { |
4586 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), | 4781 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
4587 value_reg); | 4782 value_reg); |
4588 } else { | 4783 } else { |
4589 __ StoreIntoObjectNoBarrier( | 4784 __ StoreIntoObjectNoBarrier( |
4590 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); | 4785 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); |
4591 } | 4786 } |
4592 } | 4787 } |
4593 | 4788 |
4594 | 4789 |
4595 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { | 4790 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { |
4596 return MakeCallSummary(); | 4791 return MakeCallSummary(); |
4597 } | 4792 } |
4598 | 4793 |
4599 | 4794 |
4600 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4795 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4601 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 4796 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); |
4602 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); | 4797 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); |
4603 compiler->GenerateCall(token_pos(), | 4798 compiler->GenerateCall(token_pos(), |
4604 &label, | 4799 &label, |
4605 PcDescriptors::kOther, | 4800 PcDescriptors::kOther, |
4606 locs()); | 4801 locs()); |
4607 __ Drop(ArgumentCount()); // Discard arguments. | 4802 __ Drop(ArgumentCount()); // Discard arguments. |
4608 } | 4803 } |
4609 | 4804 |
4610 | 4805 |
4611 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { | 4806 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const { |
4612 return MakeCallSummary(); | 4807 return MakeCallSummary(); |
4613 } | 4808 } |
4614 | 4809 |
4615 | 4810 |
4616 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4811 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4617 const Function& closure_function = function(); | 4812 const Function& closure_function = function(); |
4618 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); | 4813 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); |
4619 const Code& stub = Code::Handle( | 4814 const Code& stub = Code::Handle( |
4620 StubCode::GetAllocationStubForClosure(closure_function)); | 4815 StubCode::GetAllocationStubForClosure(closure_function)); |
4621 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 4816 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
4622 compiler->GenerateCall(token_pos(), | 4817 compiler->GenerateCall(token_pos(), |
4623 &label, | 4818 &label, |
4624 PcDescriptors::kOther, | 4819 PcDescriptors::kOther, |
4625 locs()); | 4820 locs()); |
4626 __ Drop(2); // Discard type arguments and receiver. | 4821 __ Drop(2); // Discard type arguments and receiver. |
4627 } | 4822 } |
4628 | 4823 |
4629 } // namespace dart | 4824 } // namespace dart |
4630 | 4825 |
4631 #endif // defined TARGET_ARCH_ARM | 4826 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |