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

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

Issue 99573005: Add mutable double boxes for fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
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
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
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(&copy_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(&copy_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698