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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_mips.cc ('k') | runtime/vm/object.h » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "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 RAX. 29 // on the stack and return the result in a fixed register RAX.
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(RAX)); 32 result->set_out(Location::RegisterLocation(RAX));
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 __ pushq(value.reg()); 53 __ pushq(value.reg());
54 } else if (value.IsConstant()) { 54 } else if (value.IsConstant()) {
55 __ PushObject(value.constant(), PP); 55 __ PushObject(value.constant(), PP);
56 } else { 56 } else {
57 ASSERT(value.IsStackSlot()); 57 ASSERT(value.IsStackSlot());
58 __ pushq(value.ToStackSlotAddress()); 58 __ pushq(value.ToStackSlotAddress());
59 } 59 }
60 } 60 }
61 } 61 }
62 62
63 63
64 LocationSummary* ReturnInstr::MakeLocationSummary() const { 64 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const {
65 const intptr_t kNumInputs = 1; 65 const intptr_t kNumInputs = 1;
66 const intptr_t kNumTemps = 0; 66 const intptr_t kNumTemps = 0;
67 LocationSummary* locs = 67 LocationSummary* locs =
68 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 68 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
69 locs->set_in(0, Location::RegisterLocation(RAX)); 69 locs->set_in(0, Location::RegisterLocation(RAX));
70 return locs; 70 return locs;
71 } 71 }
72 72
73 73
74 // Attempt optimized compilation at return instruction instead of at the entry. 74 // Attempt optimized compilation at return instruction instead of at the entry.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 123 }
124 124
125 125
126 // Detect pattern when one value is zero and another is a power of 2. 126 // Detect pattern when one value is zero and another is a power of 2.
127 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 127 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
128 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 128 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
129 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 129 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
130 } 130 }
131 131
132 132
133 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { 133 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
134 LocationSummary* locs = comparison()->MakeLocationSummary(); 134 comparison()->InitializeLocationSummary(opt);
135 // TODO(vegorov): support byte register constraints in the register allocator. 135 // TODO(vegorov): support byte register constraints in the register allocator.
136 locs->set_out(Location::RegisterLocation(RDX)); 136 comparison()->locs()->set_out(Location::RegisterLocation(RDX));
137 return locs; 137 return comparison()->locs();
138 } 138 }
139 139
140 140
141 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 141 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
142 ASSERT(locs()->out().reg() == RDX); 142 ASSERT(locs()->out().reg() == RDX);
143 143
144 // Clear upper part of the out register. We are going to use setcc on it 144 // Clear upper part of the out register. We are going to use setcc on it
145 // which is a byte move. 145 // which is a byte move.
146 __ xorq(RDX, RDX); 146 __ xorq(RDX, RDX);
147 147
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 __ AddImmediate(RDX, Immediate(-1), PP); 180 __ AddImmediate(RDX, Immediate(-1), PP);
181 __ AndImmediate(RDX, 181 __ AndImmediate(RDX,
182 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP); 182 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP);
183 if (false_value != 0) { 183 if (false_value != 0) {
184 __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP); 184 __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP);
185 } 185 }
186 } 186 }
187 } 187 }
188 188
189 189
190 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 190 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
191 const intptr_t kNumInputs = 0; 191 const intptr_t kNumInputs = 0;
192 return LocationSummary::Make(kNumInputs, 192 return LocationSummary::Make(kNumInputs,
193 Location::RequiresRegister(), 193 Location::RequiresRegister(),
194 LocationSummary::kNoCall); 194 LocationSummary::kNoCall);
195 } 195 }
196 196
197 197
198 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 198 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
199 Register result = locs()->out().reg(); 199 Register result = locs()->out().reg();
200 __ movq(result, Address(RBP, local().index() * kWordSize)); 200 __ movq(result, Address(RBP, local().index() * kWordSize));
201 } 201 }
202 202
203 203
204 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { 204 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
205 const intptr_t kNumInputs = 1; 205 const intptr_t kNumInputs = 1;
206 return LocationSummary::Make(kNumInputs, 206 return LocationSummary::Make(kNumInputs,
207 Location::SameAsFirstInput(), 207 Location::SameAsFirstInput(),
208 LocationSummary::kNoCall); 208 LocationSummary::kNoCall);
209 } 209 }
210 210
211 211
212 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 212 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
213 Register value = locs()->in(0).reg(); 213 Register value = locs()->in(0).reg();
214 Register result = locs()->out().reg(); 214 Register result = locs()->out().reg();
215 ASSERT(result == value); // Assert that register assignment is correct. 215 ASSERT(result == value); // Assert that register assignment is correct.
216 __ movq(Address(RBP, local().index() * kWordSize), value); 216 __ movq(Address(RBP, local().index() * kWordSize), value);
217 } 217 }
218 218
219 219
220 LocationSummary* ConstantInstr::MakeLocationSummary() const { 220 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
221 const intptr_t kNumInputs = 0; 221 const intptr_t kNumInputs = 0;
222 return LocationSummary::Make(kNumInputs, 222 return LocationSummary::Make(kNumInputs,
223 Location::RequiresRegister(), 223 Location::RequiresRegister(),
224 LocationSummary::kNoCall); 224 LocationSummary::kNoCall);
225 } 225 }
226 226
227 227
228 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 228 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
229 // The register allocator drops constant definitions that have no uses. 229 // The register allocator drops constant definitions that have no uses.
230 if (!locs()->out().IsInvalid()) { 230 if (!locs()->out().IsInvalid()) {
231 Register result = locs()->out().reg(); 231 Register result = locs()->out().reg();
232 __ LoadObject(result, value(), PP); 232 __ LoadObject(result, value(), PP);
233 } 233 }
234 } 234 }
235 235
236 236
237 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 237 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
238 const intptr_t kNumInputs = 3; 238 const intptr_t kNumInputs = 3;
239 const intptr_t kNumTemps = 0; 239 const intptr_t kNumTemps = 0;
240 LocationSummary* summary = 240 LocationSummary* summary =
241 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 241 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
242 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 242 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
243 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. 243 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
244 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. 244 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments.
245 summary->set_out(Location::RegisterLocation(RAX)); 245 summary->set_out(Location::RegisterLocation(RAX));
246 return summary; 246 return summary;
247 } 247 }
248 248
249 249
250 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 250 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
251 const intptr_t kNumInputs = 1; 251 const intptr_t kNumInputs = 1;
252 const intptr_t kNumTemps = 0; 252 const intptr_t kNumTemps = 0;
253 LocationSummary* locs = 253 LocationSummary* locs =
254 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 254 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
255 locs->set_in(0, Location::RegisterLocation(RAX)); 255 locs->set_in(0, Location::RegisterLocation(RAX));
256 locs->set_out(Location::RegisterLocation(RAX)); 256 locs->set_out(Location::RegisterLocation(RAX));
257 return locs; 257 return locs;
258 } 258 }
259 259
260 260
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 case Token::kGT: return GREATER; 301 case Token::kGT: return GREATER;
302 case Token::kLTE: return LESS_EQUAL; 302 case Token::kLTE: return LESS_EQUAL;
303 case Token::kGTE: return GREATER_EQUAL; 303 case Token::kGTE: return GREATER_EQUAL;
304 default: 304 default:
305 UNREACHABLE(); 305 UNREACHABLE();
306 return OVERFLOW; 306 return OVERFLOW;
307 } 307 }
308 } 308 }
309 309
310 310
311 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 311 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
312 const intptr_t kNumInputs = 2; 312 const intptr_t kNumInputs = 2;
313 if (operation_cid() == kDoubleCid) { 313 if (operation_cid() == kDoubleCid) {
314 const intptr_t kNumTemps = 0; 314 const intptr_t kNumTemps = 0;
315 LocationSummary* locs = 315 LocationSummary* locs =
316 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 316 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
317 locs->set_in(0, Location::RequiresFpuRegister()); 317 locs->set_in(0, Location::RequiresFpuRegister());
318 locs->set_in(1, Location::RequiresFpuRegister()); 318 locs->set_in(1, Location::RequiresFpuRegister());
319 locs->set_out(Location::RequiresRegister()); 319 locs->set_out(Location::RequiresRegister());
320 return locs; 320 return locs;
321 } 321 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 484 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
485 BranchInstr* branch) { 485 BranchInstr* branch) {
486 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 486 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
487 487
488 BranchLabels labels = compiler->CreateBranchLabels(branch); 488 BranchLabels labels = compiler->CreateBranchLabels(branch);
489 Condition true_condition = EmitComparisonCode(compiler, labels); 489 Condition true_condition = EmitComparisonCode(compiler, labels);
490 EmitBranchOnCondition(compiler, true_condition, labels); 490 EmitBranchOnCondition(compiler, true_condition, labels);
491 } 491 }
492 492
493 493
494 LocationSummary* TestSmiInstr::MakeLocationSummary() const { 494 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const {
495 const intptr_t kNumInputs = 2; 495 const intptr_t kNumInputs = 2;
496 const intptr_t kNumTemps = 0; 496 const intptr_t kNumTemps = 0;
497 LocationSummary* locs = 497 LocationSummary* locs =
498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
499 locs->set_in(0, Location::RequiresRegister()); 499 locs->set_in(0, Location::RequiresRegister());
500 // Only one input can be a constant operand. The case of two constant 500 // Only one input can be a constant operand. The case of two constant
501 // operands should be handled by constant propagation. 501 // operands should be handled by constant propagation.
502 locs->set_in(1, Location::RegisterOrConstant(right())); 502 locs->set_in(1, Location::RegisterOrConstant(right()));
503 return locs; 503 return locs;
504 } 504 }
(...skipping 23 matching lines...) Expand all
528 528
529 529
530 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, 530 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
531 BranchInstr* branch) { 531 BranchInstr* branch) {
532 BranchLabels labels = compiler->CreateBranchLabels(branch); 532 BranchLabels labels = compiler->CreateBranchLabels(branch);
533 Condition true_condition = EmitComparisonCode(compiler, labels); 533 Condition true_condition = EmitComparisonCode(compiler, labels);
534 EmitBranchOnCondition(compiler, true_condition, labels); 534 EmitBranchOnCondition(compiler, true_condition, labels);
535 } 535 }
536 536
537 537
538 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 538 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const {
539 const intptr_t kNumInputs = 2; 539 const intptr_t kNumInputs = 2;
540 const intptr_t kNumTemps = 0; 540 const intptr_t kNumTemps = 0;
541 if (operation_cid() == kDoubleCid) { 541 if (operation_cid() == kDoubleCid) {
542 LocationSummary* summary = 542 LocationSummary* summary =
543 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 543 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
544 summary->set_in(0, Location::RequiresFpuRegister()); 544 summary->set_in(0, Location::RequiresFpuRegister());
545 summary->set_in(1, Location::RequiresFpuRegister()); 545 summary->set_in(1, Location::RequiresFpuRegister());
546 summary->set_out(Location::RequiresRegister()); 546 summary->set_out(Location::RequiresRegister());
547 return summary; 547 return summary;
548 } 548 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 589
590 590
591 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 591 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
592 BranchInstr* branch) { 592 BranchInstr* branch) {
593 BranchLabels labels = compiler->CreateBranchLabels(branch); 593 BranchLabels labels = compiler->CreateBranchLabels(branch);
594 Condition true_condition = EmitComparisonCode(compiler, labels); 594 Condition true_condition = EmitComparisonCode(compiler, labels);
595 EmitBranchOnCondition(compiler, true_condition, labels); 595 EmitBranchOnCondition(compiler, true_condition, labels);
596 } 596 }
597 597
598 598
599 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 599 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
600 const intptr_t kNumInputs = 0; 600 const intptr_t kNumInputs = 0;
601 const intptr_t kNumTemps = 3; 601 const intptr_t kNumTemps = 3;
602 LocationSummary* locs = 602 LocationSummary* locs =
603 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 603 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
604 locs->set_temp(0, Location::RegisterLocation(RAX)); 604 locs->set_temp(0, Location::RegisterLocation(RAX));
605 locs->set_temp(1, Location::RegisterLocation(RBX)); 605 locs->set_temp(1, Location::RegisterLocation(RBX));
606 locs->set_temp(2, Location::RegisterLocation(R10)); 606 locs->set_temp(2, Location::RegisterLocation(R10));
607 locs->set_out(Location::RegisterLocation(RAX)); 607 locs->set_out(Location::RegisterLocation(RAX));
608 return locs; 608 return locs;
609 } 609 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 const Object& constant = index->definition()->AsConstant()->value(); 645 const Object& constant = index->definition()->AsConstant()->value();
646 if (!constant.IsSmi()) return false; 646 if (!constant.IsSmi()) return false;
647 const Smi& smi_const = Smi::Cast(constant); 647 const Smi& smi_const = Smi::Cast(constant);
648 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid); 648 const intptr_t scale = FlowGraphCompiler::ElementSizeFor(cid);
649 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid); 649 const intptr_t data_offset = FlowGraphCompiler::DataOffsetFor(cid);
650 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset; 650 const int64_t disp = smi_const.AsInt64Value() * scale + data_offset;
651 return Utils::IsInt(32, disp); 651 return Utils::IsInt(32, disp);
652 } 652 }
653 653
654 654
655 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary() const { 655 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const {
656 const intptr_t kNumInputs = 1; 656 const intptr_t kNumInputs = 1;
657 // TODO(fschneider): Allow immediate operands for the char code. 657 // TODO(fschneider): Allow immediate operands for the char code.
658 return LocationSummary::Make(kNumInputs, 658 return LocationSummary::Make(kNumInputs,
659 Location::RequiresRegister(), 659 Location::RequiresRegister(),
660 LocationSummary::kNoCall); 660 LocationSummary::kNoCall);
661 } 661 }
662 662
663 663
664 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 664 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
665 Register char_code = locs()->in(0).reg(); 665 Register char_code = locs()->in(0).reg();
666 Register result = locs()->out().reg(); 666 Register result = locs()->out().reg();
667 __ LoadImmediate(result, 667 __ LoadImmediate(result,
668 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP); 668 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP);
669 __ movq(result, Address(result, 669 __ movq(result, Address(result,
670 char_code, 670 char_code,
671 TIMES_HALF_WORD_SIZE, // Char code is a smi. 671 TIMES_HALF_WORD_SIZE, // Char code is a smi.
672 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 672 Symbols::kNullCharCodeSymbolOffset * kWordSize));
673 } 673 }
674 674
675 675
676 LocationSummary* StringInterpolateInstr::MakeLocationSummary() const { 676 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
677 const intptr_t kNumInputs = 1; 677 const intptr_t kNumInputs = 1;
678 const intptr_t kNumTemps = 0; 678 const intptr_t kNumTemps = 0;
679 LocationSummary* summary = 679 LocationSummary* summary =
680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
681 summary->set_in(0, Location::RegisterLocation(RAX)); 681 summary->set_in(0, Location::RegisterLocation(RAX));
682 summary->set_out(Location::RegisterLocation(RAX)); 682 summary->set_out(Location::RegisterLocation(RAX));
683 return summary; 683 return summary;
684 } 684 }
685 685
686 686
687 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 687 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
688 Register array = locs()->in(0).reg(); 688 Register array = locs()->in(0).reg();
689 __ pushq(array); 689 __ pushq(array);
690 const int kNumberOfArguments = 1; 690 const int kNumberOfArguments = 1;
691 const Array& kNoArgumentNames = Object::null_array(); 691 const Array& kNoArgumentNames = Object::null_array();
692 compiler->GenerateStaticCall(deopt_id(), 692 compiler->GenerateStaticCall(deopt_id(),
693 token_pos(), 693 token_pos(),
694 CallFunction(), 694 CallFunction(),
695 kNumberOfArguments, 695 kNumberOfArguments,
696 kNoArgumentNames, 696 kNoArgumentNames,
697 locs()); 697 locs());
698 ASSERT(locs()->out().reg() == RAX); 698 ASSERT(locs()->out().reg() == RAX);
699 } 699 }
700 700
701 701
702 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { 702 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
703 const intptr_t kNumInputs = 1; 703 const intptr_t kNumInputs = 1;
704 return LocationSummary::Make(kNumInputs, 704 return LocationSummary::Make(kNumInputs,
705 Location::RequiresRegister(), 705 Location::RequiresRegister(),
706 LocationSummary::kNoCall); 706 LocationSummary::kNoCall);
707 } 707 }
708 708
709 709
710 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 710 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
711 Register object = locs()->in(0).reg(); 711 Register object = locs()->in(0).reg();
712 Register result = locs()->out().reg(); 712 Register result = locs()->out().reg();
713 __ movq(result, FieldAddress(object, offset())); 713 __ movq(result, FieldAddress(object, offset()));
714 } 714 }
715 715
716 716
717 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 717 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const {
718 const intptr_t kNumInputs = 1; 718 const intptr_t kNumInputs = 1;
719 return LocationSummary::Make(kNumInputs, 719 return LocationSummary::Make(kNumInputs,
720 Location::RequiresRegister(), 720 Location::RequiresRegister(),
721 LocationSummary::kNoCall); 721 LocationSummary::kNoCall);
722 } 722 }
723 723
724 724
725 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 725 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
726 Register object = locs()->in(0).reg(); 726 Register object = locs()->in(0).reg();
727 Register result = locs()->out().reg(); 727 Register result = locs()->out().reg();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return kUnboxedInt32x4; 794 return kUnboxedInt32x4;
795 case kTypedDataFloat32x4ArrayCid: 795 case kTypedDataFloat32x4ArrayCid:
796 return kUnboxedFloat32x4; 796 return kUnboxedFloat32x4;
797 default: 797 default:
798 UNIMPLEMENTED(); 798 UNIMPLEMENTED();
799 return kTagged; 799 return kTagged;
800 } 800 }
801 } 801 }
802 802
803 803
804 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 804 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const {
805 const intptr_t kNumInputs = 2; 805 const intptr_t kNumInputs = 2;
806 const intptr_t kNumTemps = 0; 806 const intptr_t kNumTemps = 0;
807 LocationSummary* locs = 807 LocationSummary* locs =
808 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 808 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
809 locs->set_in(0, Location::RequiresRegister()); 809 locs->set_in(0, Location::RequiresRegister());
810 // The smi index is either untagged (element size == 1), or it is left smi 810 // The smi index is either untagged (element size == 1), or it is left smi
811 // tagged (for all element sizes > 1). 811 // tagged (for all element sizes > 1).
812 if (index_scale() == 1) { 812 if (index_scale() == 1) {
813 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 813 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
814 ? Location::Constant( 814 ? Location::Constant(
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 return kUnboxedFloat32x4; 945 return kUnboxedFloat32x4;
946 case kTypedDataInt32x4ArrayCid: 946 case kTypedDataInt32x4ArrayCid:
947 return kUnboxedInt32x4; 947 return kUnboxedInt32x4;
948 default: 948 default:
949 UNIMPLEMENTED(); 949 UNIMPLEMENTED();
950 return kTagged; 950 return kTagged;
951 } 951 }
952 } 952 }
953 953
954 954
955 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 955 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const {
956 const intptr_t kNumInputs = 3; 956 const intptr_t kNumInputs = 3;
957 const intptr_t kNumTemps = 0; 957 const intptr_t kNumTemps = 0;
958 LocationSummary* locs = 958 LocationSummary* locs =
959 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 959 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
960 locs->set_in(0, Location::RequiresRegister()); 960 locs->set_in(0, Location::RequiresRegister());
961 // The smi index is either untagged (element size == 1), or it is left smi 961 // The smi index is either untagged (element size == 1), or it is left smi
962 // tagged (for all element sizes > 1). 962 // tagged (for all element sizes > 1).
963 if (index_scale() == 1) { 963 if (index_scale() == 1) {
964 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 964 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
965 ? Location::Constant( 965 ? Location::Constant(
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 case kTypedDataInt32x4ArrayCid: 1123 case kTypedDataInt32x4ArrayCid:
1124 case kTypedDataFloat32x4ArrayCid: 1124 case kTypedDataFloat32x4ArrayCid:
1125 __ movups(element_address, locs()->in(2).fpu_reg()); 1125 __ movups(element_address, locs()->in(2).fpu_reg());
1126 break; 1126 break;
1127 default: 1127 default:
1128 UNREACHABLE(); 1128 UNREACHABLE();
1129 } 1129 }
1130 } 1130 }
1131 1131
1132 1132
1133 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { 1133 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const {
1134 const intptr_t kNumInputs = 1; 1134 const intptr_t kNumInputs = 1;
1135 LocationSummary* summary = 1135 LocationSummary* summary =
1136 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); 1136 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
1137 summary->set_in(0, Location::RequiresRegister()); 1137 summary->set_in(0, Location::RequiresRegister());
1138 const bool field_has_length = field().needs_length_check(); 1138 const bool field_has_length = field().needs_length_check();
1139 const bool need_value_temp_reg = 1139 const bool need_value_temp_reg =
1140 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && 1140 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
1141 (field().guarded_cid() != kSmiCid))); 1141 (field().guarded_cid() != kSmiCid)));
1142 if (need_value_temp_reg) { 1142 if (need_value_temp_reg) {
1143 summary->AddTemp(Location::RequiresRegister()); 1143 summary->AddTemp(Location::RequiresRegister());
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 __ j(NOT_EQUAL, fail); 1469 __ j(NOT_EQUAL, fail);
1470 } else { 1470 } else {
1471 UNREACHABLE(); 1471 UNREACHABLE();
1472 } 1472 }
1473 } 1473 }
1474 } 1474 }
1475 __ Bind(&ok); 1475 __ Bind(&ok);
1476 } 1476 }
1477 1477
1478 1478
1479 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 1479 class StoreInstanceFieldSlowPath : public SlowPathCode {
1480 public:
1481 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction)
1482 : instruction_(instruction) { }
1483
1484 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1485 __ Comment("StoreInstanceFieldSlowPath");
1486 __ Bind(entry_label());
1487 const Class& double_class = compiler->double_class();
1488 const Code& stub =
1489 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1490 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1491
1492 LocationSummary* locs = instruction_->locs();
1493 locs->live_registers()->Remove(locs->out());
1494
1495 compiler->SaveLiveRegisters(locs);
1496 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
1497 &label,
1498 PcDescriptors::kOther,
1499 locs);
1500 __ MoveRegister(locs->temp(0).reg(), RAX);
1501 compiler->RestoreLiveRegisters(locs);
1502
1503 __ jmp(exit_label());
1504 }
1505
1506 private:
1507 StoreInstanceFieldInstr* instruction_;
1508 };
1509
1510
1511 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1480 const intptr_t kNumInputs = 2; 1512 const intptr_t kNumInputs = 2;
1481 const intptr_t kNumTemps = 0; 1513 const intptr_t kNumTemps = 0;
1482 LocationSummary* summary = 1514 LocationSummary* summary =
1483 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1515 new LocationSummary(kNumInputs, kNumTemps,
1516 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1517 ? LocationSummary::kCallOnSlowPath
1518 : LocationSummary::kNoCall);
1519
1484 summary->set_in(0, Location::RequiresRegister()); 1520 summary->set_in(0, Location::RequiresRegister());
1485 summary->set_in(1, ShouldEmitStoreBarrier() 1521 if (IsUnboxedStore() && opt) {
1522 summary->set_in(1, Location::RequiresFpuRegister());
1523 summary->AddTemp(Location::RequiresRegister());
1524 summary->AddTemp(Location::RequiresRegister());
1525 } else if (IsPotentialUnboxedStore()) {
1526 summary->set_in(1, ShouldEmitStoreBarrier()
1527 ? Location::WritableRegister()
1528 : Location::RequiresRegister());
1529 summary->AddTemp(Location::RequiresRegister());
1530 summary->AddTemp(Location::RequiresRegister());
1531 summary->AddTemp(opt ? Location::RequiresFpuRegister()
1532 : Location::FpuRegisterLocation(XMM1));
1533 } else {
1534 summary->set_in(1, ShouldEmitStoreBarrier()
1486 ? Location::WritableRegister() 1535 ? Location::WritableRegister()
1487 : Location::RegisterOrConstant(value())); 1536 : Location::RegisterOrConstant(value()));
1537 }
1488 return summary; 1538 return summary;
1489 } 1539 }
1490 1540
1491 1541
1492 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1542 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1543 Label skip_store;
1544
1493 Register instance_reg = locs()->in(0).reg(); 1545 Register instance_reg = locs()->in(0).reg();
1546
1547 if (IsUnboxedStore() && compiler->is_optimizing()) {
1548 XmmRegister value = locs()->in(1).fpu_reg();
1549 Register temp = locs()->temp(0).reg();
1550 Register temp2 = locs()->temp(1).reg();
1551
1552 if (is_initialization_) {
1553 StoreInstanceFieldSlowPath* slow_path =
1554 new StoreInstanceFieldSlowPath(this);
1555 compiler->AddSlowPathCode(slow_path);
1556
1557 __ TryAllocate(compiler->double_class(),
1558 slow_path->entry_label(),
1559 Assembler::kFarJump,
1560 temp,
1561 PP);
1562 __ Bind(slow_path->exit_label());
1563 __ movq(temp2, temp);
1564 __ StoreIntoObject(instance_reg,
1565 FieldAddress(instance_reg, field().Offset()),
1566 temp2);
1567 } else {
1568 __ movq(temp, FieldAddress(instance_reg, field().Offset()));
1569 }
1570 __ movsd(FieldAddress(temp, Double::value_offset()), value);
1571 return;
1572 }
1573
1574 if (IsPotentialUnboxedStore()) {
1575 Register value_reg = locs()->in(1).reg();
1576 Register temp = locs()->temp(0).reg();
1577 Register temp2 = locs()->temp(1).reg();
1578 FpuRegister fpu_temp = locs()->temp(2).fpu_reg();
1579
1580 Label store_pointer, copy_payload;
1581 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP);
1582 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()),
1583 Immediate(kDoubleCid));
1584 __ j(NOT_EQUAL, &store_pointer);
1585 __ cmpq(FieldAddress(temp, Field::is_nullable_offset()),
1586 Immediate(kNullCid));
1587 __ j(EQUAL, &store_pointer);
1588
1589 __ movq(temp, FieldAddress(instance_reg, field().Offset()));
1590 __ CompareObject(temp, Object::null_object(), PP);
1591 __ j(NOT_EQUAL, &copy_payload);
1592
1593 StoreInstanceFieldSlowPath* slow_path =
1594 new StoreInstanceFieldSlowPath(this);
1595 compiler->AddSlowPathCode(slow_path);
1596
1597 if (!compiler->is_optimizing()) {
1598 locs()->live_registers()->Add(locs()->in(0));
1599 locs()->live_registers()->Add(locs()->in(1));
1600 }
1601 __ TryAllocate(compiler->double_class(),
1602 slow_path->entry_label(),
1603 Assembler::kFarJump,
1604 temp,
1605 PP);
1606 __ Bind(slow_path->exit_label());
1607 __ movq(temp2, temp);
1608 __ StoreIntoObject(instance_reg,
1609 FieldAddress(instance_reg, field().Offset()),
1610 temp2);
1611
1612 __ Bind(&copy_payload);
1613 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset()));
1614 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp);
1615 __ jmp(&skip_store);
1616 __ Bind(&store_pointer);
1617 }
1618
1494 if (ShouldEmitStoreBarrier()) { 1619 if (ShouldEmitStoreBarrier()) {
1495 Register value_reg = locs()->in(1).reg(); 1620 Register value_reg = locs()->in(1).reg();
1496 __ StoreIntoObject(instance_reg, 1621 __ StoreIntoObject(instance_reg,
1497 FieldAddress(instance_reg, field().Offset()), 1622 FieldAddress(instance_reg, field().Offset()),
1498 value_reg, 1623 value_reg,
1499 CanValueBeSmi()); 1624 CanValueBeSmi());
1500 } else { 1625 } else {
1501 if (locs()->in(1).IsConstant()) { 1626 if (locs()->in(1).IsConstant()) {
1502 __ StoreObject(FieldAddress(instance_reg, field().Offset()), 1627 __ StoreObject(FieldAddress(instance_reg, field().Offset()),
1503 locs()->in(1).constant(), PP); 1628 locs()->in(1).constant(), PP);
1504 } else { 1629 } else {
1505 Register value_reg = locs()->in(1).reg(); 1630 Register value_reg = locs()->in(1).reg();
1506 __ StoreIntoObjectNoBarrier(instance_reg, 1631 __ StoreIntoObjectNoBarrier(instance_reg,
1507 FieldAddress(instance_reg, field().Offset()), value_reg); 1632 FieldAddress(instance_reg, field().Offset()), value_reg);
1508 } 1633 }
1509 } 1634 }
1635 __ Bind(&skip_store);
1510 } 1636 }
1511 1637
1512 1638
1513 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { 1639 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1514 const intptr_t kNumInputs = 1; 1640 const intptr_t kNumInputs = 1;
1515 const intptr_t kNumTemps = 0; 1641 const intptr_t kNumTemps = 0;
1516 LocationSummary* summary = 1642 LocationSummary* summary =
1517 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1643 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1518 summary->set_in(0, Location::RequiresRegister()); 1644 summary->set_in(0, Location::RequiresRegister());
1519 summary->set_out(Location::RequiresRegister()); 1645 summary->set_out(Location::RequiresRegister());
1520 return summary; 1646 return summary;
1521 } 1647 }
1522 1648
1523 1649
1524 // When the parser is building an implicit static getter for optimization, 1650 // When the parser is building an implicit static getter for optimization,
1525 // it can generate a function body where deoptimization ids do not line up 1651 // it can generate a function body where deoptimization ids do not line up
1526 // with the unoptimized code. 1652 // with the unoptimized code.
1527 // 1653 //
1528 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1654 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1529 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1655 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1530 Register field = locs()->in(0).reg(); 1656 Register field = locs()->in(0).reg();
1531 Register result = locs()->out().reg(); 1657 Register result = locs()->out().reg();
1532 __ movq(result, FieldAddress(field, Field::value_offset())); 1658 __ movq(result, FieldAddress(field, Field::value_offset()));
1533 } 1659 }
1534 1660
1535 1661
1536 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { 1662 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1537 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1663 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1538 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1664 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1539 : Location::RequiresRegister()); 1665 : Location::RequiresRegister());
1540 locs->set_temp(0, Location::RequiresRegister()); 1666 locs->set_temp(0, Location::RequiresRegister());
1541 return locs; 1667 return locs;
1542 } 1668 }
1543 1669
1544 1670
1545 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1671 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1546 Register value = locs()->in(0).reg(); 1672 Register value = locs()->in(0).reg();
1547 Register temp = locs()->temp(0).reg(); 1673 Register temp = locs()->temp(0).reg();
1548 1674
1549 __ LoadObject(temp, field(), PP); 1675 __ LoadObject(temp, field(), PP);
1550 if (this->value()->NeedsStoreBuffer()) { 1676 if (this->value()->NeedsStoreBuffer()) {
1551 __ StoreIntoObject(temp, 1677 __ StoreIntoObject(temp,
1552 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); 1678 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi());
1553 } else { 1679 } else {
1554 __ StoreIntoObjectNoBarrier( 1680 __ StoreIntoObjectNoBarrier(
1555 temp, FieldAddress(temp, Field::value_offset()), value); 1681 temp, FieldAddress(temp, Field::value_offset()), value);
1556 } 1682 }
1557 } 1683 }
1558 1684
1559 1685
1560 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { 1686 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1561 const intptr_t kNumInputs = 3; 1687 const intptr_t kNumInputs = 3;
1562 const intptr_t kNumTemps = 0; 1688 const intptr_t kNumTemps = 0;
1563 LocationSummary* summary = 1689 LocationSummary* summary =
1564 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1565 summary->set_in(0, Location::RegisterLocation(RAX)); 1691 summary->set_in(0, Location::RegisterLocation(RAX));
1566 summary->set_in(1, Location::RegisterLocation(RCX)); 1692 summary->set_in(1, Location::RegisterLocation(RCX));
1567 summary->set_in(2, Location::RegisterLocation(RDX)); 1693 summary->set_in(2, Location::RegisterLocation(RDX));
1568 summary->set_out(Location::RegisterLocation(RAX)); 1694 summary->set_out(Location::RegisterLocation(RAX));
1569 return summary; 1695 return summary;
1570 } 1696 }
1571 1697
1572 1698
1573 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1699 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1574 ASSERT(locs()->in(0).reg() == RAX); // Value. 1700 ASSERT(locs()->in(0).reg() == RAX); // Value.
1575 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1701 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1576 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1702 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1577 1703
1578 compiler->GenerateInstanceOf(token_pos(), 1704 compiler->GenerateInstanceOf(token_pos(),
1579 deopt_id(), 1705 deopt_id(),
1580 type(), 1706 type(),
1581 negate_result(), 1707 negate_result(),
1582 locs()); 1708 locs());
1583 ASSERT(locs()->out().reg() == RAX); 1709 ASSERT(locs()->out().reg() == RAX);
1584 } 1710 }
1585 1711
1586 1712
1587 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { 1713 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1588 const intptr_t kNumInputs = 1; 1714 const intptr_t kNumInputs = 1;
1589 const intptr_t kNumTemps = 0; 1715 const intptr_t kNumTemps = 0;
1590 LocationSummary* locs = 1716 LocationSummary* locs =
1591 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1717 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1592 locs->set_in(0, Location::RegisterLocation(RBX)); 1718 locs->set_in(0, Location::RegisterLocation(RBX));
1593 locs->set_out(Location::RegisterLocation(RAX)); 1719 locs->set_out(Location::RegisterLocation(RAX));
1594 return locs; 1720 return locs;
1595 } 1721 }
1596 1722
1597 1723
1598 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1724 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1599 // Allocate the array. R10 = length, RBX = element type. 1725 // Allocate the array. R10 = length, RBX = element type.
1600 ASSERT(locs()->in(0).reg() == RBX); 1726 ASSERT(locs()->in(0).reg() == RBX);
1601 __ LoadImmediate(R10, Immediate(Smi::RawValue(num_elements())), PP); 1727 __ LoadImmediate(R10, Immediate(Smi::RawValue(num_elements())), PP);
1602 compiler->GenerateCall(token_pos(), 1728 compiler->GenerateCall(token_pos(),
1603 &StubCode::AllocateArrayLabel(), 1729 &StubCode::AllocateArrayLabel(),
1604 PcDescriptors::kOther, 1730 PcDescriptors::kOther,
1605 locs()); 1731 locs());
1606 ASSERT(locs()->out().reg() == RAX); 1732 ASSERT(locs()->out().reg() == RAX);
1607 } 1733 }
1608 1734
1609 1735
1610 LocationSummary* 1736 LocationSummary*
1611 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { 1737 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary(bool opt) const {
1612 return MakeCallSummary(); 1738 return MakeCallSummary();
1613 } 1739 }
1614 1740
1615 1741
1616 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( 1742 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
1617 FlowGraphCompiler* compiler) { 1743 FlowGraphCompiler* compiler) {
1618 compiler->GenerateRuntimeCall(token_pos(), 1744 compiler->GenerateRuntimeCall(token_pos(),
1619 deopt_id(), 1745 deopt_id(),
1620 kAllocateObjectWithBoundsCheckRuntimeEntry, 1746 kAllocateObjectWithBoundsCheckRuntimeEntry,
1621 3, 1747 3,
1622 locs()); 1748 locs());
1623 __ Drop(3); 1749 __ Drop(3);
1624 ASSERT(locs()->out().reg() == RAX); 1750 ASSERT(locs()->out().reg() == RAX);
1625 __ popq(RAX); // Pop new instance. 1751 __ popq(RAX); // Pop new instance.
1626 } 1752 }
1627 1753
1628 1754
1629 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { 1755 class BoxDoubleSlowPath : public SlowPathCode {
1630 return LocationSummary::Make(1, 1756 public:
1631 Location::RequiresRegister(), 1757 explicit BoxDoubleSlowPath(Instruction* instruction)
1632 LocationSummary::kNoCall); 1758 : instruction_(instruction) { }
1759
1760 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1761 __ Comment("BoxDoubleSlowPath");
1762 __ Bind(entry_label());
1763 const Class& double_class = compiler->double_class();
1764 const Code& stub =
1765 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1766 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1767
1768 LocationSummary* locs = instruction_->locs();
1769 locs->live_registers()->Remove(locs->out());
1770
1771 compiler->SaveLiveRegisters(locs);
1772 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
1773 &label,
1774 PcDescriptors::kOther,
1775 locs);
1776 __ MoveRegister(locs->out().reg(), RAX);
1777 compiler->RestoreLiveRegisters(locs);
1778
1779 __ jmp(exit_label());
1780 }
1781
1782 private:
1783 Instruction* instruction_;
1784 };
1785
1786
1787 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1788 const intptr_t kNumInputs = 1;
1789 const intptr_t kNumTemps = 0;
1790 LocationSummary* locs =
1791 new LocationSummary(
1792 kNumInputs, kNumTemps,
1793 (opt && !IsPotentialUnboxedLoad())
1794 ? LocationSummary::kNoCall
1795 : LocationSummary::kCallOnSlowPath);
1796
1797 locs->set_in(0, Location::RequiresRegister());
1798
1799 if (IsUnboxedLoad() && opt) {
1800 locs->AddTemp(Location::RequiresRegister());
1801 } else if (IsPotentialUnboxedLoad()) {
1802 locs->AddTemp(opt ? Location::RequiresFpuRegister()
1803 : Location::FpuRegisterLocation(XMM1));
1804 locs->AddTemp(Location::RequiresRegister());
1805 }
1806 locs->set_out(Location::RequiresRegister());
1807 return locs;
1633 } 1808 }
1634 1809
1635 1810
1636 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1811 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1637 Register instance_reg = locs()->in(0).reg(); 1812 Register instance_reg = locs()->in(0).reg();
1638 Register result_reg = locs()->out().reg(); 1813 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1814 XmmRegister result = locs()->out().fpu_reg();
1815 Register temp = locs()->temp(0).reg();
1816 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes()));
1817 __ movsd(result, FieldAddress(temp, Double::value_offset()));
1818 return;
1819 }
1639 1820
1640 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1821 Label done;
1822 Register result = locs()->out().reg();
1823 if (IsPotentialUnboxedLoad()) {
1824 Register temp = locs()->temp(1).reg();
1825 XmmRegister value = locs()->temp(0).fpu_reg();
1826
1827 Label load_pointer;
1828 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP);
1829
1830
1831 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()),
1832 Immediate(kDoubleCid));
1833 __ j(NOT_EQUAL, &load_pointer);
1834 __ cmpq(FieldAddress(result, Field::is_nullable_offset()),
1835 Immediate(kNullCid));
1836 __ j(EQUAL, &load_pointer);
1837
1838 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1839 compiler->AddSlowPathCode(slow_path);
1840
1841 if (!compiler->is_optimizing()) {
1842 locs()->live_registers()->Add(locs()->in(0));
1843 }
1844
1845 __ TryAllocate(compiler->double_class(),
1846 slow_path->entry_label(),
1847 Assembler::kFarJump,
1848 result,
1849 PP);
1850 __ Bind(slow_path->exit_label());
1851 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes()));
1852 __ movsd(value, FieldAddress(temp, Double::value_offset()));
1853 __ movsd(FieldAddress(result, Double::value_offset()), value);
1854 __ jmp(&done);
1855 __ Bind(&load_pointer);
1856 }
1857 __ movq(result, FieldAddress(instance_reg, offset_in_bytes()));
1858 __ Bind(&done);
1641 } 1859 }
1642 1860
1643 1861
1644 LocationSummary* InstantiateTypeInstr::MakeLocationSummary() const { 1862 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
1645 const intptr_t kNumInputs = 1; 1863 const intptr_t kNumInputs = 1;
1646 const intptr_t kNumTemps = 0; 1864 const intptr_t kNumTemps = 0;
1647 LocationSummary* locs = 1865 LocationSummary* locs =
1648 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1649 locs->set_in(0, Location::RegisterLocation(RAX)); 1867 locs->set_in(0, Location::RegisterLocation(RAX));
1650 locs->set_out(Location::RegisterLocation(RAX)); 1868 locs->set_out(Location::RegisterLocation(RAX));
1651 return locs; 1869 return locs;
1652 } 1870 }
1653 1871
1654 1872
(...skipping 11 matching lines...) Expand all
1666 deopt_id(), 1884 deopt_id(),
1667 kInstantiateTypeRuntimeEntry, 1885 kInstantiateTypeRuntimeEntry,
1668 2, 1886 2,
1669 locs()); 1887 locs());
1670 __ Drop(2); // Drop instantiator and uninstantiated type. 1888 __ Drop(2); // Drop instantiator and uninstantiated type.
1671 __ popq(result_reg); // Pop instantiated type. 1889 __ popq(result_reg); // Pop instantiated type.
1672 ASSERT(instantiator_reg == result_reg); 1890 ASSERT(instantiator_reg == result_reg);
1673 } 1891 }
1674 1892
1675 1893
1676 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1894 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
1895 bool opt) const {
1677 const intptr_t kNumInputs = 1; 1896 const intptr_t kNumInputs = 1;
1678 const intptr_t kNumTemps = 0; 1897 const intptr_t kNumTemps = 0;
1679 LocationSummary* locs = 1898 LocationSummary* locs =
1680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1681 locs->set_in(0, Location::RegisterLocation(RAX)); 1900 locs->set_in(0, Location::RegisterLocation(RAX));
1682 locs->set_out(Location::RegisterLocation(RAX)); 1901 locs->set_out(Location::RegisterLocation(RAX));
1683 return locs; 1902 return locs;
1684 } 1903 }
1685 1904
1686 1905
(...skipping 27 matching lines...) Expand all
1714 2, 1933 2,
1715 locs()); 1934 locs());
1716 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1935 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1717 __ popq(result_reg); // Pop instantiated type arguments. 1936 __ popq(result_reg); // Pop instantiated type arguments.
1718 __ Bind(&type_arguments_instantiated); 1937 __ Bind(&type_arguments_instantiated);
1719 ASSERT(instantiator_reg == result_reg); 1938 ASSERT(instantiator_reg == result_reg);
1720 } 1939 }
1721 1940
1722 1941
1723 LocationSummary* 1942 LocationSummary*
1724 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1943 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const {
1725 const intptr_t kNumInputs = 1; 1944 const intptr_t kNumInputs = 1;
1726 const intptr_t kNumTemps = 0; 1945 const intptr_t kNumTemps = 0;
1727 LocationSummary* locs = 1946 LocationSummary* locs =
1728 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1729 locs->set_in(0, Location::RequiresRegister()); 1948 locs->set_in(0, Location::RequiresRegister());
1730 locs->set_out(Location::SameAsFirstInput()); 1949 locs->set_out(Location::SameAsFirstInput());
1731 return locs; 1950 return locs;
1732 } 1951 }
1733 1952
1734 1953
(...skipping 21 matching lines...) Expand all
1756 // instantiate the type arguments. 1975 // instantiate the type arguments.
1757 __ LoadObject(result_reg, type_arguments(), PP); 1976 __ LoadObject(result_reg, type_arguments(), PP);
1758 // result_reg: uninstantiated type arguments. 1977 // result_reg: uninstantiated type arguments.
1759 1978
1760 __ Bind(&type_arguments_instantiated); 1979 __ Bind(&type_arguments_instantiated);
1761 // result_reg: uninstantiated or instantiated type arguments. 1980 // result_reg: uninstantiated or instantiated type arguments.
1762 } 1981 }
1763 1982
1764 1983
1765 LocationSummary* 1984 LocationSummary*
1766 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1985 ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const {
1767 const intptr_t kNumInputs = 1; 1986 const intptr_t kNumInputs = 1;
1768 const intptr_t kNumTemps = 0; 1987 const intptr_t kNumTemps = 0;
1769 LocationSummary* locs = 1988 LocationSummary* locs =
1770 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1989 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1771 locs->set_in(0, Location::RequiresRegister()); 1990 locs->set_in(0, Location::RequiresRegister());
1772 locs->set_out(Location::SameAsFirstInput()); 1991 locs->set_out(Location::SameAsFirstInput());
1773 return locs; 1992 return locs;
1774 } 1993 }
1775 1994
1776 1995
(...skipping 18 matching lines...) Expand all
1795 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); 2014 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
1796 // Null was used in VisitExtractConstructorTypeArguments as the 2015 // Null was used in VisitExtractConstructorTypeArguments as the
1797 // instantiated type arguments, no proper instantiator needed. 2016 // instantiated type arguments, no proper instantiator needed.
1798 __ LoadImmediate(instantiator_reg, 2017 __ LoadImmediate(instantiator_reg,
1799 Immediate(Smi::RawValue(StubCode::kNoInstantiator)), PP); 2018 Immediate(Smi::RawValue(StubCode::kNoInstantiator)), PP);
1800 __ Bind(&instantiator_not_null); 2019 __ Bind(&instantiator_not_null);
1801 // instantiator_reg: instantiator or kNoInstantiator. 2020 // instantiator_reg: instantiator or kNoInstantiator.
1802 } 2021 }
1803 2022
1804 2023
1805 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 2024 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
1806 const intptr_t kNumInputs = 0; 2025 const intptr_t kNumInputs = 0;
1807 const intptr_t kNumTemps = 1; 2026 const intptr_t kNumTemps = 1;
1808 LocationSummary* locs = 2027 LocationSummary* locs =
1809 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2028 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1810 locs->set_temp(0, Location::RegisterLocation(R10)); 2029 locs->set_temp(0, Location::RegisterLocation(R10));
1811 locs->set_out(Location::RegisterLocation(RAX)); 2030 locs->set_out(Location::RegisterLocation(RAX));
1812 return locs; 2031 return locs;
1813 } 2032 }
1814 2033
1815 2034
1816 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2035 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1817 ASSERT(locs()->temp(0).reg() == R10); 2036 ASSERT(locs()->temp(0).reg() == R10);
1818 ASSERT(locs()->out().reg() == RAX); 2037 ASSERT(locs()->out().reg() == RAX);
1819 2038
1820 __ LoadImmediate(R10, Immediate(num_context_variables()), PP); 2039 __ LoadImmediate(R10, Immediate(num_context_variables()), PP);
1821 const ExternalLabel label("alloc_context", 2040 const ExternalLabel label("alloc_context",
1822 StubCode::AllocateContextEntryPoint()); 2041 StubCode::AllocateContextEntryPoint());
1823 compiler->GenerateCall(token_pos(), 2042 compiler->GenerateCall(token_pos(),
1824 &label, 2043 &label,
1825 PcDescriptors::kOther, 2044 PcDescriptors::kOther,
1826 locs()); 2045 locs());
1827 } 2046 }
1828 2047
1829 2048
1830 LocationSummary* CloneContextInstr::MakeLocationSummary() const { 2049 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
1831 const intptr_t kNumInputs = 1; 2050 const intptr_t kNumInputs = 1;
1832 const intptr_t kNumTemps = 0; 2051 const intptr_t kNumTemps = 0;
1833 LocationSummary* locs = 2052 LocationSummary* locs =
1834 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1835 locs->set_in(0, Location::RegisterLocation(RAX)); 2054 locs->set_in(0, Location::RegisterLocation(RAX));
1836 locs->set_out(Location::RegisterLocation(RAX)); 2055 locs->set_out(Location::RegisterLocation(RAX));
1837 return locs; 2056 return locs;
1838 } 2057 }
1839 2058
1840 2059
1841 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2060 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1842 Register context_value = locs()->in(0).reg(); 2061 Register context_value = locs()->in(0).reg();
1843 Register result = locs()->out().reg(); 2062 Register result = locs()->out().reg();
1844 2063
1845 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 2064 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
1846 __ pushq(context_value); 2065 __ pushq(context_value);
1847 compiler->GenerateRuntimeCall(token_pos(), 2066 compiler->GenerateRuntimeCall(token_pos(),
1848 deopt_id(), 2067 deopt_id(),
1849 kCloneContextRuntimeEntry, 2068 kCloneContextRuntimeEntry,
1850 1, 2069 1,
1851 locs()); 2070 locs());
1852 __ popq(result); // Remove argument. 2071 __ popq(result); // Remove argument.
1853 __ popq(result); // Get result (cloned context). 2072 __ popq(result); // Get result (cloned context).
1854 } 2073 }
1855 2074
1856 2075
1857 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary() const { 2076 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(bool opt) const {
1858 UNREACHABLE(); 2077 UNREACHABLE();
1859 return NULL; 2078 return NULL;
1860 } 2079 }
1861 2080
1862 2081
1863 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2082 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1864 __ Bind(compiler->GetJumpLabel(this)); 2083 __ Bind(compiler->GetJumpLabel(this));
1865 compiler->AddExceptionHandler(catch_try_index(), 2084 compiler->AddExceptionHandler(catch_try_index(),
1866 try_index(), 2085 try_index(),
1867 compiler->assembler()->CodeSize(), 2086 compiler->assembler()->CodeSize(),
(...skipping 16 matching lines...) Expand all
1884 2103
1885 // Restore stack and initialize the two exception variables: 2104 // Restore stack and initialize the two exception variables:
1886 // exception and stack trace variables. 2105 // exception and stack trace variables.
1887 __ movq(Address(RBP, exception_var().index() * kWordSize), 2106 __ movq(Address(RBP, exception_var().index() * kWordSize),
1888 kExceptionObjectReg); 2107 kExceptionObjectReg);
1889 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), 2108 __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
1890 kStackTraceObjectReg); 2109 kStackTraceObjectReg);
1891 } 2110 }
1892 2111
1893 2112
1894 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 2113 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary(bool opt) const {
1895 const intptr_t kNumInputs = 0; 2114 const intptr_t kNumInputs = 0;
1896 const intptr_t kNumTemps = 1; 2115 const intptr_t kNumTemps = 1;
1897 LocationSummary* summary = 2116 LocationSummary* summary =
1898 new LocationSummary(kNumInputs, 2117 new LocationSummary(kNumInputs,
1899 kNumTemps, 2118 kNumTemps,
1900 LocationSummary::kCallOnSlowPath); 2119 LocationSummary::kCallOnSlowPath);
1901 summary->set_temp(0, Location::RequiresRegister()); 2120 summary->set_temp(0, Location::RequiresRegister());
1902 return summary; 2121 return summary;
1903 } 2122 }
1904 2123
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 } 2326 }
2108 } 2327 }
2109 2328
2110 2329
2111 static bool CanBeImmediate(const Object& constant) { 2330 static bool CanBeImmediate(const Object& constant) {
2112 return constant.IsSmi() && 2331 return constant.IsSmi() &&
2113 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); 2332 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32();
2114 } 2333 }
2115 2334
2116 2335
2117 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 2336 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(bool opt) const {
2118 const intptr_t kNumInputs = 2; 2337 const intptr_t kNumInputs = 2;
2119 2338
2120 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2339 ConstantInstr* right_constant = right()->definition()->AsConstant();
2121 if ((right_constant != NULL) && 2340 if ((right_constant != NULL) &&
2122 (op_kind() != Token::kTRUNCDIV) && 2341 (op_kind() != Token::kTRUNCDIV) &&
2123 (op_kind() != Token::kSHL) && 2342 (op_kind() != Token::kSHL) &&
2124 (op_kind() != Token::kMUL) && 2343 (op_kind() != Token::kMUL) &&
2125 (op_kind() != Token::kMOD) && 2344 (op_kind() != Token::kMOD) &&
2126 CanBeImmediate(right_constant->value())) { 2345 CanBeImmediate(right_constant->value())) {
2127 const intptr_t kNumTemps = 0; 2346 const intptr_t kNumTemps = 0;
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 default: 2777 default:
2559 UNREACHABLE(); 2778 UNREACHABLE();
2560 break; 2779 break;
2561 } 2780 }
2562 if (FLAG_throw_on_javascript_int_overflow) { 2781 if (FLAG_throw_on_javascript_int_overflow) {
2563 EmitJavascriptOverflowCheck(compiler, range(), deopt, result); 2782 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
2564 } 2783 }
2565 } 2784 }
2566 2785
2567 2786
2568 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { 2787 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(bool opt) const {
2569 intptr_t left_cid = left()->Type()->ToCid(); 2788 intptr_t left_cid = left()->Type()->ToCid();
2570 intptr_t right_cid = right()->Type()->ToCid(); 2789 intptr_t right_cid = right()->Type()->ToCid();
2571 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); 2790 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid));
2572 const intptr_t kNumInputs = 2; 2791 const intptr_t kNumInputs = 2;
2573 const bool need_temp = (left_cid != kSmiCid) && (right_cid != kSmiCid); 2792 const bool need_temp = (left_cid != kSmiCid) && (right_cid != kSmiCid);
2574 const intptr_t kNumTemps = need_temp ? 1 : 0; 2793 const intptr_t kNumTemps = need_temp ? 1 : 0;
2575 LocationSummary* summary = 2794 LocationSummary* summary =
2576 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2795 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2577 summary->set_in(0, Location::RequiresRegister()); 2796 summary->set_in(0, Location::RequiresRegister());
2578 summary->set_in(1, Location::RequiresRegister()); 2797 summary->set_in(1, Location::RequiresRegister());
(...skipping 15 matching lines...) Expand all
2594 } else { 2813 } else {
2595 Register temp = locs()->temp(0).reg(); 2814 Register temp = locs()->temp(0).reg();
2596 __ movq(temp, left); 2815 __ movq(temp, left);
2597 __ orq(temp, right); 2816 __ orq(temp, right);
2598 __ testq(temp, Immediate(kSmiTagMask)); 2817 __ testq(temp, Immediate(kSmiTagMask));
2599 } 2818 }
2600 __ j(ZERO, deopt); 2819 __ j(ZERO, deopt);
2601 } 2820 }
2602 2821
2603 2822
2604 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { 2823 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2605 const intptr_t kNumInputs = 1; 2824 const intptr_t kNumInputs = 1;
2606 const intptr_t kNumTemps = 0; 2825 const intptr_t kNumTemps = 0;
2607 LocationSummary* summary = 2826 LocationSummary* summary =
2608 new LocationSummary(kNumInputs, 2827 new LocationSummary(kNumInputs,
2609 kNumTemps, 2828 kNumTemps,
2610 LocationSummary::kCallOnSlowPath); 2829 LocationSummary::kCallOnSlowPath);
2611 summary->set_in(0, Location::RequiresFpuRegister()); 2830 summary->set_in(0, Location::RequiresFpuRegister());
2612 summary->set_out(Location::RequiresRegister()); 2831 summary->set_out(Location::RequiresRegister());
2613 return summary; 2832 return summary;
2614 } 2833 }
2615 2834
2616 2835
2617 class BoxDoubleSlowPath : public SlowPathCode {
2618 public:
2619 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
2620 : instruction_(instruction) { }
2621
2622 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2623 __ Comment("BoxDoubleSlowPath");
2624 __ Bind(entry_label());
2625 const Class& double_class = compiler->double_class();
2626 const Code& stub =
2627 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2628 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2629
2630 LocationSummary* locs = instruction_->locs();
2631 locs->live_registers()->Remove(locs->out());
2632
2633 compiler->SaveLiveRegisters(locs);
2634 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position.
2635 &label,
2636 PcDescriptors::kOther,
2637 locs);
2638 __ MoveRegister(locs->out().reg(), RAX);
2639 compiler->RestoreLiveRegisters(locs);
2640
2641 __ jmp(exit_label());
2642 }
2643
2644 private:
2645 BoxDoubleInstr* instruction_;
2646 };
2647
2648
2649 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2836 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2650 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2837 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2651 compiler->AddSlowPathCode(slow_path); 2838 compiler->AddSlowPathCode(slow_path);
2652 2839
2653 Register out_reg = locs()->out().reg(); 2840 Register out_reg = locs()->out().reg();
2654 XmmRegister value = locs()->in(0).fpu_reg(); 2841 XmmRegister value = locs()->in(0).fpu_reg();
2655 2842
2656 __ TryAllocate(compiler->double_class(), 2843 __ TryAllocate(compiler->double_class(),
2657 slow_path->entry_label(), 2844 slow_path->entry_label(),
2658 Assembler::kFarJump, 2845 Assembler::kFarJump,
2659 out_reg, 2846 out_reg,
2660 PP); 2847 PP);
2661 __ Bind(slow_path->exit_label()); 2848 __ Bind(slow_path->exit_label());
2662 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 2849 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
2663 } 2850 }
2664 2851
2665 2852
2666 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 2853 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
2667 const intptr_t kNumInputs = 1; 2854 const intptr_t kNumInputs = 1;
2668 const intptr_t kNumTemps = 0; 2855 const intptr_t kNumTemps = 0;
2669 LocationSummary* summary = 2856 LocationSummary* summary =
2670 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2857 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2671 const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid); 2858 const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid);
2672 summary->set_in(0, needs_writable_input 2859 summary->set_in(0, needs_writable_input
2673 ? Location::WritableRegister() 2860 ? Location::WritableRegister()
2674 : Location::RequiresRegister()); 2861 : Location::RequiresRegister());
2675 summary->set_out(Location::RequiresFpuRegister()); 2862 summary->set_out(Location::RequiresFpuRegister());
2676 return summary; 2863 return summary;
(...skipping 20 matching lines...) Expand all
2697 __ movsd(result, FieldAddress(value, Double::value_offset())); 2884 __ movsd(result, FieldAddress(value, Double::value_offset()));
2698 __ jmp(&done); 2885 __ jmp(&done);
2699 __ Bind(&is_smi); 2886 __ Bind(&is_smi);
2700 __ SmiUntag(value); 2887 __ SmiUntag(value);
2701 __ cvtsi2sd(result, value); 2888 __ cvtsi2sd(result, value);
2702 __ Bind(&done); 2889 __ Bind(&done);
2703 } 2890 }
2704 } 2891 }
2705 2892
2706 2893
2707 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary() const { 2894 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2708 const intptr_t kNumInputs = 1; 2895 const intptr_t kNumInputs = 1;
2709 const intptr_t kNumTemps = 0; 2896 const intptr_t kNumTemps = 0;
2710 LocationSummary* summary = 2897 LocationSummary* summary =
2711 new LocationSummary(kNumInputs, 2898 new LocationSummary(kNumInputs,
2712 kNumTemps, 2899 kNumTemps,
2713 LocationSummary::kCallOnSlowPath); 2900 LocationSummary::kCallOnSlowPath);
2714 summary->set_in(0, Location::RequiresFpuRegister()); 2901 summary->set_in(0, Location::RequiresFpuRegister());
2715 summary->set_out(Location::RequiresRegister()); 2902 summary->set_out(Location::RequiresRegister());
2716 return summary; 2903 return summary;
2717 } 2904 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 __ TryAllocate(compiler->float32x4_class(), 2946 __ TryAllocate(compiler->float32x4_class(),
2760 slow_path->entry_label(), 2947 slow_path->entry_label(),
2761 Assembler::kFarJump, 2948 Assembler::kFarJump,
2762 out_reg, 2949 out_reg,
2763 PP); 2950 PP);
2764 __ Bind(slow_path->exit_label()); 2951 __ Bind(slow_path->exit_label());
2765 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); 2952 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
2766 } 2953 }
2767 2954
2768 2955
2769 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary() const { 2956 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2770 const intptr_t kNumInputs = 1; 2957 const intptr_t kNumInputs = 1;
2771 return LocationSummary::Make(kNumInputs, 2958 return LocationSummary::Make(kNumInputs,
2772 Location::RequiresFpuRegister(), 2959 Location::RequiresFpuRegister(),
2773 LocationSummary::kNoCall); 2960 LocationSummary::kNoCall);
2774 } 2961 }
2775 2962
2776 2963
2777 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 2964 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2778 const intptr_t value_cid = value()->Type()->ToCid(); 2965 const intptr_t value_cid = value()->Type()->ToCid();
2779 const Register value = locs()->in(0).reg(); 2966 const Register value = locs()->in(0).reg();
2780 const XmmRegister result = locs()->out().fpu_reg(); 2967 const XmmRegister result = locs()->out().fpu_reg();
2781 2968
2782 if (value_cid != kFloat32x4Cid) { 2969 if (value_cid != kFloat32x4Cid) {
2783 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 2970 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2784 __ testq(value, Immediate(kSmiTagMask)); 2971 __ testq(value, Immediate(kSmiTagMask));
2785 __ j(ZERO, deopt); 2972 __ j(ZERO, deopt);
2786 __ CompareClassId(value, kFloat32x4Cid); 2973 __ CompareClassId(value, kFloat32x4Cid);
2787 __ j(NOT_EQUAL, deopt); 2974 __ j(NOT_EQUAL, deopt);
2788 } 2975 }
2789 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 2976 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
2790 } 2977 }
2791 2978
2792 2979
2793 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { 2980 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
2794 const intptr_t kNumInputs = 1; 2981 const intptr_t kNumInputs = 1;
2795 const intptr_t kNumTemps = 0; 2982 const intptr_t kNumTemps = 0;
2796 LocationSummary* summary = 2983 LocationSummary* summary =
2797 new LocationSummary(kNumInputs, 2984 new LocationSummary(kNumInputs,
2798 kNumTemps, 2985 kNumTemps,
2799 LocationSummary::kCallOnSlowPath); 2986 LocationSummary::kCallOnSlowPath);
2800 summary->set_in(0, Location::RequiresFpuRegister()); 2987 summary->set_in(0, Location::RequiresFpuRegister());
2801 summary->set_out(Location::RequiresRegister()); 2988 summary->set_out(Location::RequiresRegister());
2802 return summary; 2989 return summary;
2803 } 2990 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 __ TryAllocate(compiler->int32x4_class(), 3032 __ TryAllocate(compiler->int32x4_class(),
2846 slow_path->entry_label(), 3033 slow_path->entry_label(),
2847 Assembler::kFarJump, 3034 Assembler::kFarJump,
2848 out_reg, 3035 out_reg,
2849 PP); 3036 PP);
2850 __ Bind(slow_path->exit_label()); 3037 __ Bind(slow_path->exit_label());
2851 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); 3038 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
2852 } 3039 }
2853 3040
2854 3041
2855 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { 3042 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const {
2856 const intptr_t kNumInputs = 1; 3043 const intptr_t kNumInputs = 1;
2857 const intptr_t kNumTemps = 0; 3044 const intptr_t kNumTemps = 0;
2858 LocationSummary* summary = 3045 LocationSummary* summary =
2859 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2860 summary->set_in(0, Location::RequiresRegister()); 3047 summary->set_in(0, Location::RequiresRegister());
2861 summary->set_out(Location::RequiresFpuRegister()); 3048 summary->set_out(Location::RequiresFpuRegister());
2862 return summary; 3049 return summary;
2863 } 3050 }
2864 3051
2865 3052
2866 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3053 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2867 const intptr_t value_cid = value()->Type()->ToCid(); 3054 const intptr_t value_cid = value()->Type()->ToCid();
2868 const Register value = locs()->in(0).reg(); 3055 const Register value = locs()->in(0).reg();
2869 const XmmRegister result = locs()->out().fpu_reg(); 3056 const XmmRegister result = locs()->out().fpu_reg();
2870 3057
2871 if (value_cid != kInt32x4Cid) { 3058 if (value_cid != kInt32x4Cid) {
2872 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3059 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
2873 __ testq(value, Immediate(kSmiTagMask)); 3060 __ testq(value, Immediate(kSmiTagMask));
2874 __ j(ZERO, deopt); 3061 __ j(ZERO, deopt);
2875 __ CompareClassId(value, kInt32x4Cid); 3062 __ CompareClassId(value, kInt32x4Cid);
2876 __ j(NOT_EQUAL, deopt); 3063 __ j(NOT_EQUAL, deopt);
2877 } 3064 }
2878 __ movups(result, FieldAddress(value, Int32x4::value_offset())); 3065 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
2879 } 3066 }
2880 3067
2881 3068
2882 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { 3069 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
2883 const intptr_t kNumInputs = 2; 3070 const intptr_t kNumInputs = 2;
2884 const intptr_t kNumTemps = 0; 3071 const intptr_t kNumTemps = 0;
2885 LocationSummary* summary = 3072 LocationSummary* summary =
2886 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3073 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2887 summary->set_in(0, Location::RequiresFpuRegister()); 3074 summary->set_in(0, Location::RequiresFpuRegister());
2888 summary->set_in(1, Location::RequiresFpuRegister()); 3075 summary->set_in(1, Location::RequiresFpuRegister());
2889 summary->set_out(Location::SameAsFirstInput()); 3076 summary->set_out(Location::SameAsFirstInput());
2890 return summary; 3077 return summary;
2891 } 3078 }
2892 3079
2893 3080
2894 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3081 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2895 XmmRegister left = locs()->in(0).fpu_reg(); 3082 XmmRegister left = locs()->in(0).fpu_reg();
2896 XmmRegister right = locs()->in(1).fpu_reg(); 3083 XmmRegister right = locs()->in(1).fpu_reg();
2897 3084
2898 ASSERT(locs()->out().fpu_reg() == left); 3085 ASSERT(locs()->out().fpu_reg() == left);
2899 3086
2900 switch (op_kind()) { 3087 switch (op_kind()) {
2901 case Token::kADD: __ addsd(left, right); break; 3088 case Token::kADD: __ addsd(left, right); break;
2902 case Token::kSUB: __ subsd(left, right); break; 3089 case Token::kSUB: __ subsd(left, right); break;
2903 case Token::kMUL: __ mulsd(left, right); break; 3090 case Token::kMUL: __ mulsd(left, right); break;
2904 case Token::kDIV: __ divsd(left, right); break; 3091 case Token::kDIV: __ divsd(left, right); break;
2905 default: UNREACHABLE(); 3092 default: UNREACHABLE();
2906 } 3093 }
2907 } 3094 }
2908 3095
2909 3096
2910 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary() const { 3097 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
2911 const intptr_t kNumInputs = 2; 3098 const intptr_t kNumInputs = 2;
2912 const intptr_t kNumTemps = 0; 3099 const intptr_t kNumTemps = 0;
2913 LocationSummary* summary = 3100 LocationSummary* summary =
2914 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2915 summary->set_in(0, Location::RequiresFpuRegister()); 3102 summary->set_in(0, Location::RequiresFpuRegister());
2916 summary->set_in(1, Location::RequiresFpuRegister()); 3103 summary->set_in(1, Location::RequiresFpuRegister());
2917 summary->set_out(Location::SameAsFirstInput()); 3104 summary->set_out(Location::SameAsFirstInput());
2918 return summary; 3105 return summary;
2919 } 3106 }
2920 3107
2921 3108
2922 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3109 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2923 XmmRegister left = locs()->in(0).fpu_reg(); 3110 XmmRegister left = locs()->in(0).fpu_reg();
2924 XmmRegister right = locs()->in(1).fpu_reg(); 3111 XmmRegister right = locs()->in(1).fpu_reg();
2925 3112
2926 ASSERT(locs()->out().fpu_reg() == left); 3113 ASSERT(locs()->out().fpu_reg() == left);
2927 3114
2928 switch (op_kind()) { 3115 switch (op_kind()) {
2929 case Token::kADD: __ addps(left, right); break; 3116 case Token::kADD: __ addps(left, right); break;
2930 case Token::kSUB: __ subps(left, right); break; 3117 case Token::kSUB: __ subps(left, right); break;
2931 case Token::kMUL: __ mulps(left, right); break; 3118 case Token::kMUL: __ mulps(left, right); break;
2932 case Token::kDIV: __ divps(left, right); break; 3119 case Token::kDIV: __ divps(left, right); break;
2933 default: UNREACHABLE(); 3120 default: UNREACHABLE();
2934 } 3121 }
2935 } 3122 }
2936 3123
2937 3124
2938 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const { 3125 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const {
2939 const intptr_t kNumInputs = 1; 3126 const intptr_t kNumInputs = 1;
2940 const intptr_t kNumTemps = 0; 3127 const intptr_t kNumTemps = 0;
2941 LocationSummary* summary = 3128 LocationSummary* summary =
2942 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3129 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2943 summary->set_in(0, Location::RequiresFpuRegister()); 3130 summary->set_in(0, Location::RequiresFpuRegister());
2944 summary->set_out(Location::SameAsFirstInput()); 3131 summary->set_out(Location::SameAsFirstInput());
2945 return summary; 3132 return summary;
2946 } 3133 }
2947 3134
2948 3135
(...skipping 21 matching lines...) Expand all
2970 break; 3157 break;
2971 case MethodRecognizer::kFloat32x4Shuffle: 3158 case MethodRecognizer::kFloat32x4Shuffle:
2972 case MethodRecognizer::kInt32x4Shuffle: 3159 case MethodRecognizer::kInt32x4Shuffle:
2973 __ shufps(value, value, Immediate(mask_)); 3160 __ shufps(value, value, Immediate(mask_));
2974 break; 3161 break;
2975 default: UNREACHABLE(); 3162 default: UNREACHABLE();
2976 } 3163 }
2977 } 3164 }
2978 3165
2979 3166
2980 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { 3167 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const {
2981 const intptr_t kNumInputs = 2; 3168 const intptr_t kNumInputs = 2;
2982 const intptr_t kNumTemps = 0; 3169 const intptr_t kNumTemps = 0;
2983 LocationSummary* summary = 3170 LocationSummary* summary =
2984 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3171 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2985 summary->set_in(0, Location::RequiresFpuRegister()); 3172 summary->set_in(0, Location::RequiresFpuRegister());
2986 summary->set_in(1, Location::RequiresFpuRegister()); 3173 summary->set_in(1, Location::RequiresFpuRegister());
2987 summary->set_out(Location::SameAsFirstInput()); 3174 summary->set_out(Location::SameAsFirstInput());
2988 return summary; 3175 return summary;
2989 } 3176 }
2990 3177
2991 3178
2992 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3179 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2993 XmmRegister left = locs()->in(0).fpu_reg(); 3180 XmmRegister left = locs()->in(0).fpu_reg();
2994 XmmRegister right = locs()->in(1).fpu_reg(); 3181 XmmRegister right = locs()->in(1).fpu_reg();
2995 3182
2996 ASSERT(locs()->out().fpu_reg() == left); 3183 ASSERT(locs()->out().fpu_reg() == left);
2997 switch (op_kind()) { 3184 switch (op_kind()) {
2998 case MethodRecognizer::kFloat32x4ShuffleMix: 3185 case MethodRecognizer::kFloat32x4ShuffleMix:
2999 case MethodRecognizer::kInt32x4ShuffleMix: 3186 case MethodRecognizer::kInt32x4ShuffleMix:
3000 __ shufps(left, right, Immediate(mask_)); 3187 __ shufps(left, right, Immediate(mask_));
3001 break; 3188 break;
3002 default: UNREACHABLE(); 3189 default: UNREACHABLE();
3003 } 3190 }
3004 } 3191 }
3005 3192
3006 3193
3007 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { 3194 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const {
3008 const intptr_t kNumInputs = 1; 3195 const intptr_t kNumInputs = 1;
3009 const intptr_t kNumTemps = 0; 3196 const intptr_t kNumTemps = 0;
3010 LocationSummary* summary = 3197 LocationSummary* summary =
3011 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3198 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3012 summary->set_in(0, Location::RequiresFpuRegister()); 3199 summary->set_in(0, Location::RequiresFpuRegister());
3013 summary->set_out(Location::RequiresRegister()); 3200 summary->set_out(Location::RequiresRegister());
3014 return summary; 3201 return summary;
3015 } 3202 }
3016 3203
3017 3204
3018 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3205 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3019 XmmRegister value = locs()->in(0).fpu_reg(); 3206 XmmRegister value = locs()->in(0).fpu_reg();
3020 Register out = locs()->out().reg(); 3207 Register out = locs()->out().reg();
3021 3208
3022 __ movmskps(out, value); 3209 __ movmskps(out, value);
3023 __ SmiTag(out); 3210 __ SmiTag(out);
3024 } 3211 }
3025 3212
3026 3213
3027 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { 3214 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
3215 bool opt) const {
3028 const intptr_t kNumInputs = 4; 3216 const intptr_t kNumInputs = 4;
3029 const intptr_t kNumTemps = 0; 3217 const intptr_t kNumTemps = 0;
3030 LocationSummary* summary = 3218 LocationSummary* summary =
3031 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3219 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3032 summary->set_in(0, Location::RequiresFpuRegister()); 3220 summary->set_in(0, Location::RequiresFpuRegister());
3033 summary->set_in(1, Location::RequiresFpuRegister()); 3221 summary->set_in(1, Location::RequiresFpuRegister());
3034 summary->set_in(2, Location::RequiresFpuRegister()); 3222 summary->set_in(2, Location::RequiresFpuRegister());
3035 summary->set_in(3, Location::RequiresFpuRegister()); 3223 summary->set_in(3, Location::RequiresFpuRegister());
3036 summary->set_out(Location::SameAsFirstInput()); 3224 summary->set_out(Location::SameAsFirstInput());
3037 return summary; 3225 return summary;
(...skipping 16 matching lines...) Expand all
3054 __ cvtsd2ss(v0, v0); 3242 __ cvtsd2ss(v0, v0);
3055 __ movss(Address(RSP, 8), v0); 3243 __ movss(Address(RSP, 8), v0);
3056 __ movsd(v0, v3); 3244 __ movsd(v0, v3);
3057 __ cvtsd2ss(v0, v0); 3245 __ cvtsd2ss(v0, v0);
3058 __ movss(Address(RSP, 12), v0); 3246 __ movss(Address(RSP, 12), v0);
3059 __ movups(v0, Address(RSP, 0)); 3247 __ movups(v0, Address(RSP, 0));
3060 __ AddImmediate(RSP, Immediate(16), PP); 3248 __ AddImmediate(RSP, Immediate(16), PP);
3061 } 3249 }
3062 3250
3063 3251
3064 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const { 3252 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const {
3065 const intptr_t kNumInputs = 0; 3253 const intptr_t kNumInputs = 0;
3066 const intptr_t kNumTemps = 0; 3254 const intptr_t kNumTemps = 0;
3067 LocationSummary* summary = 3255 LocationSummary* summary =
3068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3256 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3069 summary->set_out(Location::RequiresFpuRegister()); 3257 summary->set_out(Location::RequiresFpuRegister());
3070 return summary; 3258 return summary;
3071 } 3259 }
3072 3260
3073 3261
3074 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3262 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3075 XmmRegister value = locs()->out().fpu_reg(); 3263 XmmRegister value = locs()->out().fpu_reg();
3076 __ xorps(value, value); 3264 __ xorps(value, value);
3077 } 3265 }
3078 3266
3079 3267
3080 LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const { 3268 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const {
3081 const intptr_t kNumInputs = 1; 3269 const intptr_t kNumInputs = 1;
3082 const intptr_t kNumTemps = 0; 3270 const intptr_t kNumTemps = 0;
3083 LocationSummary* summary = 3271 LocationSummary* summary =
3084 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3272 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3085 summary->set_in(0, Location::RequiresFpuRegister()); 3273 summary->set_in(0, Location::RequiresFpuRegister());
3086 summary->set_out(Location::SameAsFirstInput()); 3274 summary->set_out(Location::SameAsFirstInput());
3087 return summary; 3275 return summary;
3088 } 3276 }
3089 3277
3090 3278
3091 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3279 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3092 XmmRegister value = locs()->out().fpu_reg(); 3280 XmmRegister value = locs()->out().fpu_reg();
3093 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); 3281 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg());
3094 // Convert to Float32. 3282 // Convert to Float32.
3095 __ cvtsd2ss(value, value); 3283 __ cvtsd2ss(value, value);
3096 // Splat across all lanes. 3284 // Splat across all lanes.
3097 __ shufps(value, value, Immediate(0x00)); 3285 __ shufps(value, value, Immediate(0x00));
3098 } 3286 }
3099 3287
3100 3288
3101 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const { 3289 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const {
3102 const intptr_t kNumInputs = 2; 3290 const intptr_t kNumInputs = 2;
3103 const intptr_t kNumTemps = 0; 3291 const intptr_t kNumTemps = 0;
3104 LocationSummary* summary = 3292 LocationSummary* summary =
3105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3293 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3106 summary->set_in(0, Location::RequiresFpuRegister()); 3294 summary->set_in(0, Location::RequiresFpuRegister());
3107 summary->set_in(1, Location::RequiresFpuRegister()); 3295 summary->set_in(1, Location::RequiresFpuRegister());
3108 summary->set_out(Location::SameAsFirstInput()); 3296 summary->set_out(Location::SameAsFirstInput());
3109 return summary; 3297 return summary;
3110 } 3298 }
3111 3299
(...skipping 22 matching lines...) Expand all
3134 break; 3322 break;
3135 case MethodRecognizer::kFloat32x4LessThanOrEqual: 3323 case MethodRecognizer::kFloat32x4LessThanOrEqual:
3136 __ cmppsle(left, right); 3324 __ cmppsle(left, right);
3137 break; 3325 break;
3138 3326
3139 default: UNREACHABLE(); 3327 default: UNREACHABLE();
3140 } 3328 }
3141 } 3329 }
3142 3330
3143 3331
3144 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { 3332 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const {
3145 const intptr_t kNumInputs = 2; 3333 const intptr_t kNumInputs = 2;
3146 const intptr_t kNumTemps = 0; 3334 const intptr_t kNumTemps = 0;
3147 LocationSummary* summary = 3335 LocationSummary* summary =
3148 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3336 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3149 summary->set_in(0, Location::RequiresFpuRegister()); 3337 summary->set_in(0, Location::RequiresFpuRegister());
3150 summary->set_in(1, Location::RequiresFpuRegister()); 3338 summary->set_in(1, Location::RequiresFpuRegister());
3151 summary->set_out(Location::SameAsFirstInput()); 3339 summary->set_out(Location::SameAsFirstInput());
3152 return summary; 3340 return summary;
3153 } 3341 }
3154 3342
3155 3343
3156 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3344 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3157 XmmRegister left = locs()->in(0).fpu_reg(); 3345 XmmRegister left = locs()->in(0).fpu_reg();
3158 XmmRegister right = locs()->in(1).fpu_reg(); 3346 XmmRegister right = locs()->in(1).fpu_reg();
3159 3347
3160 ASSERT(locs()->out().fpu_reg() == left); 3348 ASSERT(locs()->out().fpu_reg() == left);
3161 3349
3162 switch (op_kind()) { 3350 switch (op_kind()) {
3163 case MethodRecognizer::kFloat32x4Min: 3351 case MethodRecognizer::kFloat32x4Min:
3164 __ minps(left, right); 3352 __ minps(left, right);
3165 break; 3353 break;
3166 case MethodRecognizer::kFloat32x4Max: 3354 case MethodRecognizer::kFloat32x4Max:
3167 __ maxps(left, right); 3355 __ maxps(left, right);
3168 break; 3356 break;
3169 default: UNREACHABLE(); 3357 default: UNREACHABLE();
3170 } 3358 }
3171 } 3359 }
3172 3360
3173 3361
3174 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { 3362 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const {
3175 const intptr_t kNumInputs = 2; 3363 const intptr_t kNumInputs = 2;
3176 const intptr_t kNumTemps = 0; 3364 const intptr_t kNumTemps = 0;
3177 LocationSummary* summary = 3365 LocationSummary* summary =
3178 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3366 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3179 summary->set_in(0, Location::RequiresFpuRegister()); 3367 summary->set_in(0, Location::RequiresFpuRegister());
3180 summary->set_in(1, Location::RequiresFpuRegister()); 3368 summary->set_in(1, Location::RequiresFpuRegister());
3181 summary->set_out(Location::SameAsFirstInput()); 3369 summary->set_out(Location::SameAsFirstInput());
3182 return summary; 3370 return summary;
3183 } 3371 }
3184 3372
3185 3373
3186 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3374 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3187 XmmRegister left = locs()->in(0).fpu_reg(); 3375 XmmRegister left = locs()->in(0).fpu_reg();
3188 XmmRegister right = locs()->in(1).fpu_reg(); 3376 XmmRegister right = locs()->in(1).fpu_reg();
3189 3377
3190 ASSERT(locs()->out().fpu_reg() == left); 3378 ASSERT(locs()->out().fpu_reg() == left);
3191 3379
3192 switch (op_kind()) { 3380 switch (op_kind()) {
3193 case MethodRecognizer::kFloat32x4Scale: 3381 case MethodRecognizer::kFloat32x4Scale:
3194 __ cvtsd2ss(left, left); 3382 __ cvtsd2ss(left, left);
3195 __ shufps(left, left, Immediate(0x00)); 3383 __ shufps(left, left, Immediate(0x00));
3196 __ mulps(left, right); 3384 __ mulps(left, right);
3197 break; 3385 break;
3198 default: UNREACHABLE(); 3386 default: UNREACHABLE();
3199 } 3387 }
3200 } 3388 }
3201 3389
3202 3390
3203 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { 3391 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const {
3204 const intptr_t kNumInputs = 1; 3392 const intptr_t kNumInputs = 1;
3205 const intptr_t kNumTemps = 0; 3393 const intptr_t kNumTemps = 0;
3206 LocationSummary* summary = 3394 LocationSummary* summary =
3207 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3395 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3208 summary->set_in(0, Location::RequiresFpuRegister()); 3396 summary->set_in(0, Location::RequiresFpuRegister());
3209 summary->set_out(Location::SameAsFirstInput()); 3397 summary->set_out(Location::SameAsFirstInput());
3210 return summary; 3398 return summary;
3211 } 3399 }
3212 3400
3213 3401
(...skipping 10 matching lines...) Expand all
3224 __ reciprocalps(left); 3412 __ reciprocalps(left);
3225 break; 3413 break;
3226 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 3414 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3227 __ rsqrtps(left); 3415 __ rsqrtps(left);
3228 break; 3416 break;
3229 default: UNREACHABLE(); 3417 default: UNREACHABLE();
3230 } 3418 }
3231 } 3419 }
3232 3420
3233 3421
3234 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { 3422 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const {
3235 const intptr_t kNumInputs = 1; 3423 const intptr_t kNumInputs = 1;
3236 const intptr_t kNumTemps = 0; 3424 const intptr_t kNumTemps = 0;
3237 LocationSummary* summary = 3425 LocationSummary* summary =
3238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3426 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3239 summary->set_in(0, Location::RequiresFpuRegister()); 3427 summary->set_in(0, Location::RequiresFpuRegister());
3240 summary->set_out(Location::SameAsFirstInput()); 3428 summary->set_out(Location::SameAsFirstInput());
3241 return summary; 3429 return summary;
3242 } 3430 }
3243 3431
3244 3432
3245 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3433 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3246 XmmRegister left = locs()->in(0).fpu_reg(); 3434 XmmRegister left = locs()->in(0).fpu_reg();
3247 3435
3248 ASSERT(locs()->out().fpu_reg() == left); 3436 ASSERT(locs()->out().fpu_reg() == left);
3249 switch (op_kind()) { 3437 switch (op_kind()) {
3250 case MethodRecognizer::kFloat32x4Negate: 3438 case MethodRecognizer::kFloat32x4Negate:
3251 __ negateps(left); 3439 __ negateps(left);
3252 break; 3440 break;
3253 case MethodRecognizer::kFloat32x4Absolute: 3441 case MethodRecognizer::kFloat32x4Absolute:
3254 __ absps(left); 3442 __ absps(left);
3255 break; 3443 break;
3256 default: UNREACHABLE(); 3444 default: UNREACHABLE();
3257 } 3445 }
3258 } 3446 }
3259 3447
3260 3448
3261 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { 3449 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const {
3262 const intptr_t kNumInputs = 3; 3450 const intptr_t kNumInputs = 3;
3263 const intptr_t kNumTemps = 0; 3451 const intptr_t kNumTemps = 0;
3264 LocationSummary* summary = 3452 LocationSummary* summary =
3265 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3453 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3266 summary->set_in(0, Location::RequiresFpuRegister()); 3454 summary->set_in(0, Location::RequiresFpuRegister());
3267 summary->set_in(1, Location::RequiresFpuRegister()); 3455 summary->set_in(1, Location::RequiresFpuRegister());
3268 summary->set_in(2, Location::RequiresFpuRegister()); 3456 summary->set_in(2, Location::RequiresFpuRegister());
3269 summary->set_out(Location::SameAsFirstInput()); 3457 summary->set_out(Location::SameAsFirstInput());
3270 return summary; 3458 return summary;
3271 } 3459 }
3272 3460
3273 3461
3274 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3462 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3275 XmmRegister left = locs()->in(0).fpu_reg(); 3463 XmmRegister left = locs()->in(0).fpu_reg();
3276 XmmRegister lower = locs()->in(1).fpu_reg(); 3464 XmmRegister lower = locs()->in(1).fpu_reg();
3277 XmmRegister upper = locs()->in(2).fpu_reg(); 3465 XmmRegister upper = locs()->in(2).fpu_reg();
3278 ASSERT(locs()->out().fpu_reg() == left); 3466 ASSERT(locs()->out().fpu_reg() == left);
3279 __ minps(left, upper); 3467 __ minps(left, upper);
3280 __ maxps(left, lower); 3468 __ maxps(left, lower);
3281 } 3469 }
3282 3470
3283 3471
3284 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { 3472 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const {
3285 const intptr_t kNumInputs = 2; 3473 const intptr_t kNumInputs = 2;
3286 const intptr_t kNumTemps = 0; 3474 const intptr_t kNumTemps = 0;
3287 LocationSummary* summary = 3475 LocationSummary* summary =
3288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3476 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3289 summary->set_in(0, Location::RequiresFpuRegister()); 3477 summary->set_in(0, Location::RequiresFpuRegister());
3290 summary->set_in(1, Location::RequiresFpuRegister()); 3478 summary->set_in(1, Location::RequiresFpuRegister());
3291 summary->set_out(Location::SameAsFirstInput()); 3479 summary->set_out(Location::SameAsFirstInput());
3292 return summary; 3480 return summary;
3293 } 3481 }
3294 3482
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 __ movss(Address(RSP, 12), replacement); 3530 __ movss(Address(RSP, 12), replacement);
3343 // Move updated value into output register. 3531 // Move updated value into output register.
3344 __ movups(replacement, Address(RSP, 0)); 3532 __ movups(replacement, Address(RSP, 0));
3345 __ AddImmediate(RSP, Immediate(16), PP); 3533 __ AddImmediate(RSP, Immediate(16), PP);
3346 break; 3534 break;
3347 default: UNREACHABLE(); 3535 default: UNREACHABLE();
3348 } 3536 }
3349 } 3537 }
3350 3538
3351 3539
3352 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { 3540 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const {
3353 const intptr_t kNumInputs = 1; 3541 const intptr_t kNumInputs = 1;
3354 const intptr_t kNumTemps = 0; 3542 const intptr_t kNumTemps = 0;
3355 LocationSummary* summary = 3543 LocationSummary* summary =
3356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3544 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3357 summary->set_in(0, Location::RequiresFpuRegister()); 3545 summary->set_in(0, Location::RequiresFpuRegister());
3358 summary->set_out(Location::SameAsFirstInput()); 3546 summary->set_out(Location::SameAsFirstInput());
3359 return summary; 3547 return summary;
3360 } 3548 }
3361 3549
3362 3550
3363 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3551 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3364 // NOP. 3552 // NOP.
3365 } 3553 }
3366 3554
3367 3555
3368 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { 3556 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
3557 bool opt) const {
3369 const intptr_t kNumInputs = 4; 3558 const intptr_t kNumInputs = 4;
3370 const intptr_t kNumTemps = 1; 3559 const intptr_t kNumTemps = 1;
3371 LocationSummary* summary = 3560 LocationSummary* summary =
3372 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3561 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3373 summary->set_in(0, Location::RequiresRegister()); 3562 summary->set_in(0, Location::RequiresRegister());
3374 summary->set_in(1, Location::RequiresRegister()); 3563 summary->set_in(1, Location::RequiresRegister());
3375 summary->set_in(2, Location::RequiresRegister()); 3564 summary->set_in(2, Location::RequiresRegister());
3376 summary->set_in(3, Location::RequiresRegister()); 3565 summary->set_in(3, Location::RequiresRegister());
3377 summary->set_temp(0, Location::RequiresRegister()); 3566 summary->set_temp(0, Location::RequiresRegister());
3378 summary->set_out(Location::RequiresFpuRegister()); 3567 summary->set_out(Location::RequiresFpuRegister());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 __ Bind(&w_false); 3616 __ Bind(&w_false);
3428 __ LoadImmediate(temp, Immediate(0x0), PP); 3617 __ LoadImmediate(temp, Immediate(0x0), PP);
3429 __ Bind(&w_done); 3618 __ Bind(&w_done);
3430 __ movl(Address(RSP, 12), temp); 3619 __ movl(Address(RSP, 12), temp);
3431 3620
3432 __ movups(result, Address(RSP, 0)); 3621 __ movups(result, Address(RSP, 0));
3433 __ AddImmediate(RSP, Immediate(16), PP); 3622 __ AddImmediate(RSP, Immediate(16), PP);
3434 } 3623 }
3435 3624
3436 3625
3437 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { 3626 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const {
3438 const intptr_t kNumInputs = 1; 3627 const intptr_t kNumInputs = 1;
3439 const intptr_t kNumTemps = 0; 3628 const intptr_t kNumTemps = 0;
3440 LocationSummary* summary = 3629 LocationSummary* summary =
3441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3630 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3442 summary->set_in(0, Location::RequiresFpuRegister()); 3631 summary->set_in(0, Location::RequiresFpuRegister());
3443 summary->set_out(Location::RequiresRegister()); 3632 summary->set_out(Location::RequiresRegister());
3444 return summary; 3633 return summary;
3445 } 3634 }
3446 3635
3447 3636
(...skipping 24 matching lines...) Expand all
3472 __ testl(result, result); 3661 __ testl(result, result);
3473 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); 3662 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
3474 __ LoadObject(result, Bool::False(), PP); 3663 __ LoadObject(result, Bool::False(), PP);
3475 __ jmp(&done); 3664 __ jmp(&done);
3476 __ Bind(&non_zero); 3665 __ Bind(&non_zero);
3477 __ LoadObject(result, Bool::True(), PP); 3666 __ LoadObject(result, Bool::True(), PP);
3478 __ Bind(&done); 3667 __ Bind(&done);
3479 } 3668 }
3480 3669
3481 3670
3482 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { 3671 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const {
3483 const intptr_t kNumInputs = 3; 3672 const intptr_t kNumInputs = 3;
3484 const intptr_t kNumTemps = 1; 3673 const intptr_t kNumTemps = 1;
3485 LocationSummary* summary = 3674 LocationSummary* summary =
3486 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3487 summary->set_in(0, Location::RequiresFpuRegister()); 3676 summary->set_in(0, Location::RequiresFpuRegister());
3488 summary->set_in(1, Location::RequiresFpuRegister()); 3677 summary->set_in(1, Location::RequiresFpuRegister());
3489 summary->set_in(2, Location::RequiresFpuRegister()); 3678 summary->set_in(2, Location::RequiresFpuRegister());
3490 summary->set_temp(0, Location::RequiresFpuRegister()); 3679 summary->set_temp(0, Location::RequiresFpuRegister());
3491 summary->set_out(Location::SameAsFirstInput()); 3680 summary->set_out(Location::SameAsFirstInput());
3492 return summary; 3681 return summary;
(...skipping 13 matching lines...) Expand all
3506 __ notps(temp); 3695 __ notps(temp);
3507 // mask = mask & trueValue. 3696 // mask = mask & trueValue.
3508 __ andps(mask, trueValue); 3697 __ andps(mask, trueValue);
3509 // temp = temp & falseValue. 3698 // temp = temp & falseValue.
3510 __ andps(temp, falseValue); 3699 __ andps(temp, falseValue);
3511 // out = mask | temp. 3700 // out = mask | temp.
3512 __ orps(mask, temp); 3701 __ orps(mask, temp);
3513 } 3702 }
3514 3703
3515 3704
3516 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { 3705 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const {
3517 const intptr_t kNumInputs = 2; 3706 const intptr_t kNumInputs = 2;
3518 const intptr_t kNumTemps = 1; 3707 const intptr_t kNumTemps = 1;
3519 LocationSummary* summary = 3708 LocationSummary* summary =
3520 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3709 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3521 summary->set_in(0, Location::RequiresFpuRegister()); 3710 summary->set_in(0, Location::RequiresFpuRegister());
3522 summary->set_in(1, Location::RequiresRegister()); 3711 summary->set_in(1, Location::RequiresRegister());
3523 summary->set_temp(0, Location::RequiresRegister()); 3712 summary->set_temp(0, Location::RequiresRegister());
3524 summary->set_out(Location::SameAsFirstInput()); 3713 summary->set_out(Location::SameAsFirstInput());
3525 return summary; 3714 return summary;
3526 } 3715 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3572 break; 3761 break;
3573 default: UNREACHABLE(); 3762 default: UNREACHABLE();
3574 } 3763 }
3575 __ Bind(&exitPath); 3764 __ Bind(&exitPath);
3576 // Copy mask back to register. 3765 // Copy mask back to register.
3577 __ movups(mask, Address(RSP, 0)); 3766 __ movups(mask, Address(RSP, 0));
3578 __ AddImmediate(RSP, Immediate(16), PP); 3767 __ AddImmediate(RSP, Immediate(16), PP);
3579 } 3768 }
3580 3769
3581 3770
3582 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { 3771 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const {
3583 const intptr_t kNumInputs = 1; 3772 const intptr_t kNumInputs = 1;
3584 const intptr_t kNumTemps = 0; 3773 const intptr_t kNumTemps = 0;
3585 LocationSummary* summary = 3774 LocationSummary* summary =
3586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3775 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3587 summary->set_in(0, Location::RequiresFpuRegister()); 3776 summary->set_in(0, Location::RequiresFpuRegister());
3588 summary->set_out(Location::SameAsFirstInput()); 3777 summary->set_out(Location::SameAsFirstInput());
3589 return summary; 3778 return summary;
3590 } 3779 }
3591 3780
3592 3781
3593 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3782 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3594 // NOP. 3783 // NOP.
3595 } 3784 }
3596 3785
3597 3786
3598 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { 3787 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const {
3599 const intptr_t kNumInputs = 2; 3788 const intptr_t kNumInputs = 2;
3600 const intptr_t kNumTemps = 0; 3789 const intptr_t kNumTemps = 0;
3601 LocationSummary* summary = 3790 LocationSummary* summary =
3602 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3603 summary->set_in(0, Location::RequiresFpuRegister()); 3792 summary->set_in(0, Location::RequiresFpuRegister());
3604 summary->set_in(1, Location::RequiresFpuRegister()); 3793 summary->set_in(1, Location::RequiresFpuRegister());
3605 summary->set_out(Location::SameAsFirstInput()); 3794 summary->set_out(Location::SameAsFirstInput());
3606 return summary; 3795 return summary;
3607 } 3796 }
3608 3797
(...skipping 19 matching lines...) Expand all
3628 __ addpl(left, right); 3817 __ addpl(left, right);
3629 break; 3818 break;
3630 case Token::kSUB: 3819 case Token::kSUB:
3631 __ subpl(left, right); 3820 __ subpl(left, right);
3632 break; 3821 break;
3633 default: UNREACHABLE(); 3822 default: UNREACHABLE();
3634 } 3823 }
3635 } 3824 }
3636 3825
3637 3826
3638 LocationSummary* MathUnaryInstr::MakeLocationSummary() const { 3827 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
3639 if ((kind() == MethodRecognizer::kMathSin) || 3828 if ((kind() == MethodRecognizer::kMathSin) ||
3640 (kind() == MethodRecognizer::kMathCos)) { 3829 (kind() == MethodRecognizer::kMathCos)) {
3641 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 3830 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
3642 // double arguments and XMM0 to return the result. Unfortunately 3831 // double arguments and XMM0 to return the result. Unfortunately
3643 // currently we can't specify these registers because ParallelMoveResolver 3832 // currently we can't specify these registers because ParallelMoveResolver
3644 // assumes that XMM0 is free at all times. 3833 // assumes that XMM0 is free at all times.
3645 // TODO(vegorov): allow XMM0 to be used. 3834 // TODO(vegorov): allow XMM0 to be used.
3646 const intptr_t kNumTemps = 0; 3835 const intptr_t kNumTemps = 0;
3647 LocationSummary* summary = 3836 LocationSummary* summary =
3648 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3837 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
(...skipping 18 matching lines...) Expand all
3667 __ EnterFrame(0); 3856 __ EnterFrame(0);
3668 __ ReserveAlignedFrameSpace(0); 3857 __ ReserveAlignedFrameSpace(0);
3669 __ movaps(XMM0, locs()->in(0).fpu_reg()); 3858 __ movaps(XMM0, locs()->in(0).fpu_reg());
3670 __ CallRuntime(TargetFunction(), InputCount()); 3859 __ CallRuntime(TargetFunction(), InputCount());
3671 __ movaps(locs()->out().fpu_reg(), XMM0); 3860 __ movaps(locs()->out().fpu_reg(), XMM0);
3672 __ leave(); 3861 __ leave();
3673 } 3862 }
3674 } 3863 }
3675 3864
3676 3865
3677 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3866 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
3678 const intptr_t kNumInputs = 1; 3867 const intptr_t kNumInputs = 1;
3679 return LocationSummary::Make(kNumInputs, 3868 return LocationSummary::Make(kNumInputs,
3680 Location::SameAsFirstInput(), 3869 Location::SameAsFirstInput(),
3681 LocationSummary::kNoCall); 3870 LocationSummary::kNoCall);
3682 } 3871 }
3683 3872
3684 3873
3685 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3874 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3686 Register value = locs()->in(0).reg(); 3875 Register value = locs()->in(0).reg();
3687 ASSERT(value == locs()->out().reg()); 3876 ASSERT(value == locs()->out().reg());
(...skipping 12 matching lines...) Expand all
3700 __ notq(value); 3889 __ notq(value);
3701 // Remove inverted smi-tag. 3890 // Remove inverted smi-tag.
3702 __ AndImmediate(value, Immediate(~kSmiTagMask), PP); 3891 __ AndImmediate(value, Immediate(~kSmiTagMask), PP);
3703 break; 3892 break;
3704 default: 3893 default:
3705 UNREACHABLE(); 3894 UNREACHABLE();
3706 } 3895 }
3707 } 3896 }
3708 3897
3709 3898
3710 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary() const { 3899 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3711 const intptr_t kNumInputs = 1; 3900 const intptr_t kNumInputs = 1;
3712 const intptr_t kNumTemps = 0; 3901 const intptr_t kNumTemps = 0;
3713 LocationSummary* summary = 3902 LocationSummary* summary =
3714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3903 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3715 summary->set_in(0, Location::RequiresFpuRegister()); 3904 summary->set_in(0, Location::RequiresFpuRegister());
3716 summary->set_out(Location::SameAsFirstInput()); 3905 summary->set_out(Location::SameAsFirstInput());
3717 return summary; 3906 return summary;
3718 } 3907 }
3719 3908
3720 3909
3721 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3910 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3722 XmmRegister value = locs()->in(0).fpu_reg(); 3911 XmmRegister value = locs()->in(0).fpu_reg();
3723 ASSERT(locs()->out().fpu_reg() == value); 3912 ASSERT(locs()->out().fpu_reg() == value);
3724 __ DoubleNegate(value); 3913 __ DoubleNegate(value);
3725 } 3914 }
3726 3915
3727 3916
3728 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3917 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
3729 if (result_cid() == kDoubleCid) { 3918 if (result_cid() == kDoubleCid) {
3730 const intptr_t kNumInputs = 2; 3919 const intptr_t kNumInputs = 2;
3731 const intptr_t kNumTemps = 1; 3920 const intptr_t kNumTemps = 1;
3732 LocationSummary* summary = 3921 LocationSummary* summary =
3733 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3922 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3734 summary->set_in(0, Location::RequiresFpuRegister()); 3923 summary->set_in(0, Location::RequiresFpuRegister());
3735 summary->set_in(1, Location::RequiresFpuRegister()); 3924 summary->set_in(1, Location::RequiresFpuRegister());
3736 // Reuse the left register so that code can be made shorter. 3925 // Reuse the left register so that code can be made shorter.
3737 summary->set_out(Location::SameAsFirstInput()); 3926 summary->set_out(Location::SameAsFirstInput());
3738 summary->set_temp(0, Location::RequiresRegister()); 3927 summary->set_temp(0, Location::RequiresRegister());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 __ cmpq(left, right); 3996 __ cmpq(left, right);
3808 ASSERT(result == left); 3997 ASSERT(result == left);
3809 if (is_min) { 3998 if (is_min) {
3810 __ cmovgeq(result, right); 3999 __ cmovgeq(result, right);
3811 } else { 4000 } else {
3812 __ cmovlessq(result, right); 4001 __ cmovlessq(result, right);
3813 } 4002 }
3814 } 4003 }
3815 4004
3816 4005
3817 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { 4006 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
3818 const intptr_t kNumInputs = 1; 4007 const intptr_t kNumInputs = 1;
3819 const intptr_t kNumTemps = 0; 4008 const intptr_t kNumTemps = 0;
3820 LocationSummary* result = 4009 LocationSummary* result =
3821 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4010 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3822 result->set_in(0, Location::WritableRegister()); 4011 result->set_in(0, Location::WritableRegister());
3823 result->set_out(Location::RequiresFpuRegister()); 4012 result->set_out(Location::RequiresFpuRegister());
3824 return result; 4013 return result;
3825 } 4014 }
3826 4015
3827 4016
3828 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4017 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3829 Register value = locs()->in(0).reg(); 4018 Register value = locs()->in(0).reg();
3830 FpuRegister result = locs()->out().fpu_reg(); 4019 FpuRegister result = locs()->out().fpu_reg();
3831 __ SmiUntag(value); 4020 __ SmiUntag(value);
3832 __ cvtsi2sd(result, value); 4021 __ cvtsi2sd(result, value);
3833 } 4022 }
3834 4023
3835 4024
3836 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 4025 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
3837 const intptr_t kNumInputs = 1; 4026 const intptr_t kNumInputs = 1;
3838 const intptr_t kNumTemps = 1; 4027 const intptr_t kNumTemps = 1;
3839 LocationSummary* result = 4028 LocationSummary* result =
3840 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4029 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3841 result->set_in(0, Location::RegisterLocation(RCX)); 4030 result->set_in(0, Location::RegisterLocation(RCX));
3842 result->set_out(Location::RegisterLocation(RAX)); 4031 result->set_out(Location::RegisterLocation(RAX));
3843 result->set_temp(0, Location::RegisterLocation(RBX)); 4032 result->set_temp(0, Location::RegisterLocation(RBX));
3844 return result; 4033 return result;
3845 } 4034 }
3846 4035
(...skipping 30 matching lines...) Expand all
3877 compiler->GenerateStaticCall(deopt_id(), 4066 compiler->GenerateStaticCall(deopt_id(),
3878 instance_call()->token_pos(), 4067 instance_call()->token_pos(),
3879 target, 4068 target,
3880 kNumberOfArguments, 4069 kNumberOfArguments,
3881 Object::null_array(), // No argument names. 4070 Object::null_array(), // No argument names.
3882 locs()); 4071 locs());
3883 __ Bind(&done); 4072 __ Bind(&done);
3884 } 4073 }
3885 4074
3886 4075
3887 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 4076 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
3888 const intptr_t kNumInputs = 1; 4077 const intptr_t kNumInputs = 1;
3889 const intptr_t kNumTemps = 1; 4078 const intptr_t kNumTemps = 1;
3890 LocationSummary* result = new LocationSummary( 4079 LocationSummary* result = new LocationSummary(
3891 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4080 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3892 result->set_in(0, Location::RequiresFpuRegister()); 4081 result->set_in(0, Location::RequiresFpuRegister());
3893 result->set_out(Location:: Location::RequiresRegister()); 4082 result->set_out(Location:: Location::RequiresRegister());
3894 result->set_temp(0, Location::RequiresRegister()); 4083 result->set_temp(0, Location::RequiresRegister());
3895 return result; 4084 return result;
3896 } 4085 }
3897 4086
(...skipping 11 matching lines...) Expand all
3909 __ movq(temp, result); 4098 __ movq(temp, result);
3910 __ shlq(temp, Immediate(1)); 4099 __ shlq(temp, Immediate(1));
3911 __ j(OVERFLOW, deopt); 4100 __ j(OVERFLOW, deopt);
3912 __ SmiTag(result); 4101 __ SmiTag(result);
3913 if (FLAG_throw_on_javascript_int_overflow) { 4102 if (FLAG_throw_on_javascript_int_overflow) {
3914 EmitJavascriptOverflowCheck(compiler, range(), deopt, result); 4103 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
3915 } 4104 }
3916 } 4105 }
3917 4106
3918 4107
3919 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 4108 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
3920 const intptr_t kNumInputs = 1; 4109 const intptr_t kNumInputs = 1;
3921 const intptr_t kNumTemps = 0; 4110 const intptr_t kNumTemps = 0;
3922 LocationSummary* result = 4111 LocationSummary* result =
3923 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4112 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3924 result->set_in(0, Location::RequiresFpuRegister()); 4113 result->set_in(0, Location::RequiresFpuRegister());
3925 result->set_out(Location::RequiresFpuRegister()); 4114 result->set_out(Location::RequiresFpuRegister());
3926 return result; 4115 return result;
3927 } 4116 }
3928 4117
3929 4118
3930 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4119 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3931 XmmRegister value = locs()->in(0).fpu_reg(); 4120 XmmRegister value = locs()->in(0).fpu_reg();
3932 XmmRegister result = locs()->out().fpu_reg(); 4121 XmmRegister result = locs()->out().fpu_reg();
3933 switch (recognized_kind()) { 4122 switch (recognized_kind()) {
3934 case MethodRecognizer::kDoubleTruncate: 4123 case MethodRecognizer::kDoubleTruncate:
3935 __ roundsd(result, value, Assembler::kRoundToZero); 4124 __ roundsd(result, value, Assembler::kRoundToZero);
3936 break; 4125 break;
3937 case MethodRecognizer::kDoubleFloor: 4126 case MethodRecognizer::kDoubleFloor:
3938 __ roundsd(result, value, Assembler::kRoundDown); 4127 __ roundsd(result, value, Assembler::kRoundDown);
3939 break; 4128 break;
3940 case MethodRecognizer::kDoubleCeil: 4129 case MethodRecognizer::kDoubleCeil:
3941 __ roundsd(result, value, Assembler::kRoundUp); 4130 __ roundsd(result, value, Assembler::kRoundUp);
3942 break; 4131 break;
3943 default: 4132 default:
3944 UNREACHABLE(); 4133 UNREACHABLE();
3945 } 4134 }
3946 } 4135 }
3947 4136
3948 4137
3949 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { 4138 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
3950 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 4139 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
3951 // double arguments and XMM0 to return the result. Unfortunately 4140 // double arguments and XMM0 to return the result. Unfortunately
3952 // currently we can't specify these registers because ParallelMoveResolver 4141 // currently we can't specify these registers because ParallelMoveResolver
3953 // assumes that XMM0 is free at all times. 4142 // assumes that XMM0 is free at all times.
3954 // TODO(vegorov): allow XMM0 to be used. 4143 // TODO(vegorov): allow XMM0 to be used.
3955 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4144 ASSERT((InputCount() == 1) || (InputCount() == 2));
3956 const intptr_t kNumTemps = 0; 4145 const intptr_t kNumTemps = 0;
3957 LocationSummary* result = 4146 LocationSummary* result =
3958 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4147 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3959 result->set_in(0, Location::FpuRegisterLocation(XMM2)); 4148 result->set_in(0, Location::FpuRegisterLocation(XMM2));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4023 __ jmp(&skip_call, Assembler::kNearJump); 4212 __ jmp(&skip_call, Assembler::kNearJump);
4024 } 4213 }
4025 __ Bind(&do_call); 4214 __ Bind(&do_call);
4026 __ CallRuntime(TargetFunction(), InputCount()); 4215 __ CallRuntime(TargetFunction(), InputCount());
4027 __ movaps(locs()->out().fpu_reg(), XMM0); 4216 __ movaps(locs()->out().fpu_reg(), XMM0);
4028 __ Bind(&skip_call); 4217 __ Bind(&skip_call);
4029 __ leave(); 4218 __ leave();
4030 } 4219 }
4031 4220
4032 4221
4033 LocationSummary* MergedMathInstr::MakeLocationSummary() const { 4222 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4034 if (kind() == MergedMathInstr::kTruncDivMod) { 4223 if (kind() == MergedMathInstr::kTruncDivMod) {
4035 const intptr_t kNumInputs = 2; 4224 const intptr_t kNumInputs = 2;
4036 const intptr_t kNumTemps = 1; 4225 const intptr_t kNumTemps = 1;
4037 LocationSummary* summary = 4226 LocationSummary* summary =
4038 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4227 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4039 // Both inputs must be writable because they will be untagged. 4228 // Both inputs must be writable because they will be untagged.
4040 summary->set_in(0, Location::RegisterLocation(RAX)); 4229 summary->set_in(0, Location::RegisterLocation(RAX));
4041 summary->set_in(1, Location::WritableRegister()); 4230 summary->set_in(1, Location::WritableRegister());
4042 summary->set_out(Location::RequiresRegister()); 4231 summary->set_out(Location::RequiresRegister());
4043 // Will be used for sign extension and division. 4232 // Will be used for sign extension and division.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 kTypedDataFloat64ArrayCid, index_scale, result, 4401 kTypedDataFloat64ArrayCid, index_scale, result,
4213 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos))); 4402 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathCos)));
4214 __ movsd(sin_address, XMM0); 4403 __ movsd(sin_address, XMM0);
4215 __ movsd(cos_address, XMM1); 4404 __ movsd(cos_address, XMM1);
4216 return; 4405 return;
4217 } 4406 }
4218 UNIMPLEMENTED(); 4407 UNIMPLEMENTED();
4219 } 4408 }
4220 4409
4221 4410
4222 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 4411 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
4412 bool opt) const {
4223 return MakeCallSummary(); 4413 return MakeCallSummary();
4224 } 4414 }
4225 4415
4226 4416
4227 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4417 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4228 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4418 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4229 kDeoptPolymorphicInstanceCallTestFail); 4419 kDeoptPolymorphicInstanceCallTestFail);
4230 if (ic_data().NumberOfChecks() == 0) { 4420 if (ic_data().NumberOfChecks() == 0) {
4231 __ jmp(deopt); 4421 __ jmp(deopt);
4232 return; 4422 return;
(...skipping 20 matching lines...) Expand all
4253 RDI, // Class id register. 4443 RDI, // Class id register.
4254 instance_call()->ArgumentCount(), 4444 instance_call()->ArgumentCount(),
4255 instance_call()->argument_names(), 4445 instance_call()->argument_names(),
4256 deopt, 4446 deopt,
4257 deopt_id(), 4447 deopt_id(),
4258 instance_call()->token_pos(), 4448 instance_call()->token_pos(),
4259 locs()); 4449 locs());
4260 } 4450 }
4261 4451
4262 4452
4263 LocationSummary* BranchInstr::MakeLocationSummary() const { 4453 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
4264 UNREACHABLE(); 4454 comparison()->InitializeLocationSummary(opt);
4265 return NULL; 4455 // Branches don't produce a result.
4456 comparison()->locs()->set_out(Location::NoLocation());
4457 return comparison()->locs();
4266 } 4458 }
4267 4459
4268 4460
4269 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4461 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4270 comparison()->EmitBranchCode(compiler, this); 4462 comparison()->EmitBranchCode(compiler, this);
4271 } 4463 }
4272 4464
4273 4465
4274 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 4466 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
4275 const intptr_t kNumInputs = 1; 4467 const intptr_t kNumInputs = 1;
4276 const intptr_t kNumTemps = 0; 4468 const intptr_t kNumTemps = 0;
4277 LocationSummary* summary = 4469 LocationSummary* summary =
4278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4470 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4279 summary->set_in(0, Location::RequiresRegister()); 4471 summary->set_in(0, Location::RequiresRegister());
4280 if (!IsNullCheck()) { 4472 if (!IsNullCheck()) {
4281 summary->AddTemp(Location::RequiresRegister()); 4473 summary->AddTemp(Location::RequiresRegister());
4282 } 4474 }
4283 return summary; 4475 return summary;
4284 } 4476 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4323 __ j(EQUAL, &is_ok, Assembler::kNearJump); 4515 __ j(EQUAL, &is_ok, Assembler::kNearJump);
4324 } else { 4516 } else {
4325 __ j(EQUAL, &is_ok); 4517 __ j(EQUAL, &is_ok);
4326 } 4518 }
4327 } 4519 }
4328 } 4520 }
4329 __ Bind(&is_ok); 4521 __ Bind(&is_ok);
4330 } 4522 }
4331 4523
4332 4524
4333 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { 4525 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const {
4334 const intptr_t kNumInputs = 1; 4526 const intptr_t kNumInputs = 1;
4335 const intptr_t kNumTemps = 0; 4527 const intptr_t kNumTemps = 0;
4336 LocationSummary* summary = 4528 LocationSummary* summary =
4337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4529 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4338 summary->set_in(0, Location::RequiresRegister()); 4530 summary->set_in(0, Location::RequiresRegister());
4339 return summary; 4531 return summary;
4340 } 4532 }
4341 4533
4342 4534
4343 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4535 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4344 Register value = locs()->in(0).reg(); 4536 Register value = locs()->in(0).reg();
4345 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4537 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4346 kDeoptCheckSmi); 4538 kDeoptCheckSmi);
4347 __ testq(value, Immediate(kSmiTagMask)); 4539 __ testq(value, Immediate(kSmiTagMask));
4348 __ j(NOT_ZERO, deopt); 4540 __ j(NOT_ZERO, deopt);
4349 } 4541 }
4350 4542
4351 4543
4352 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 4544 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const {
4353 const intptr_t kNumInputs = 2; 4545 const intptr_t kNumInputs = 2;
4354 const intptr_t kNumTemps = 0; 4546 const intptr_t kNumTemps = 0;
4355 LocationSummary* locs = 4547 LocationSummary* locs =
4356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4548 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4357 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 4549 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
4358 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); 4550 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
4359 return locs; 4551 return locs;
4360 } 4552 }
4361 4553
4362 4554
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 __ j(ABOVE_EQUAL, deopt); 4589 __ j(ABOVE_EQUAL, deopt);
4398 } else { 4590 } else {
4399 Register length = length_loc.reg(); 4591 Register length = length_loc.reg();
4400 Register index = index_loc.reg(); 4592 Register index = index_loc.reg();
4401 __ cmpq(index, length); 4593 __ cmpq(index, length);
4402 __ j(ABOVE_EQUAL, deopt); 4594 __ j(ABOVE_EQUAL, deopt);
4403 } 4595 }
4404 } 4596 }
4405 4597
4406 4598
4407 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { 4599 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const {
4408 UNIMPLEMENTED(); 4600 UNIMPLEMENTED();
4409 return NULL; 4601 return NULL;
4410 } 4602 }
4411 4603
4412 4604
4413 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4605 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4414 UNIMPLEMENTED(); 4606 UNIMPLEMENTED();
4415 } 4607 }
4416 4608
4417 4609
4418 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { 4610 LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const {
4419 UNIMPLEMENTED(); 4611 UNIMPLEMENTED();
4420 return NULL; 4612 return NULL;
4421 } 4613 }
4422 4614
4423 4615
4424 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4616 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4425 UNIMPLEMENTED(); 4617 UNIMPLEMENTED();
4426 } 4618 }
4427 4619
4428 4620
4429 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 4621 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const {
4430 UNIMPLEMENTED(); 4622 UNIMPLEMENTED();
4431 return NULL; 4623 return NULL;
4432 } 4624 }
4433 4625
4434 4626
4435 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4627 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4436 UNIMPLEMENTED(); 4628 UNIMPLEMENTED();
4437 } 4629 }
4438 4630
4439 4631
4440 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { 4632 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const {
4441 UNIMPLEMENTED(); 4633 UNIMPLEMENTED();
4442 return NULL; 4634 return NULL;
4443 } 4635 }
4444 4636
4445 4637
4446 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4638 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4447 UNIMPLEMENTED(); 4639 UNIMPLEMENTED();
4448 } 4640 }
4449 4641
4450 4642
4451 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { 4643 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const {
4452 UNIMPLEMENTED(); 4644 UNIMPLEMENTED();
4453 return NULL; 4645 return NULL;
4454 } 4646 }
4455 4647
4456 4648
4457 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4649 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4458 UNIMPLEMENTED(); 4650 UNIMPLEMENTED();
4459 } 4651 }
4460 4652
4461 4653
4462 LocationSummary* ThrowInstr::MakeLocationSummary() const { 4654 LocationSummary* ThrowInstr::MakeLocationSummary(bool opt) const {
4463 return new LocationSummary(0, 0, LocationSummary::kCall); 4655 return new LocationSummary(0, 0, LocationSummary::kCall);
4464 } 4656 }
4465 4657
4466 4658
4467 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4659 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4468 compiler->GenerateRuntimeCall(token_pos(), 4660 compiler->GenerateRuntimeCall(token_pos(),
4469 deopt_id(), 4661 deopt_id(),
4470 kThrowRuntimeEntry, 4662 kThrowRuntimeEntry,
4471 1, 4663 1,
4472 locs()); 4664 locs());
4473 __ int3(); 4665 __ int3();
4474 } 4666 }
4475 4667
4476 4668
4477 LocationSummary* ReThrowInstr::MakeLocationSummary() const { 4669 LocationSummary* ReThrowInstr::MakeLocationSummary(bool opt) const {
4478 return new LocationSummary(0, 0, LocationSummary::kCall); 4670 return new LocationSummary(0, 0, LocationSummary::kCall);
4479 } 4671 }
4480 4672
4481 4673
4482 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4674 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4483 compiler->SetNeedsStacktrace(catch_try_index()); 4675 compiler->SetNeedsStacktrace(catch_try_index());
4484 compiler->GenerateRuntimeCall(token_pos(), 4676 compiler->GenerateRuntimeCall(token_pos(),
4485 deopt_id(), 4677 deopt_id(),
4486 kReThrowRuntimeEntry, 4678 kReThrowRuntimeEntry,
4487 2, 4679 2,
(...skipping 19 matching lines...) Expand all
4507 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4699 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4508 deopt_id_, 4700 deopt_id_,
4509 Scanner::kDummyTokenIndex); 4701 Scanner::kDummyTokenIndex);
4510 } 4702 }
4511 if (HasParallelMove()) { 4703 if (HasParallelMove()) {
4512 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4704 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4513 } 4705 }
4514 } 4706 }
4515 4707
4516 4708
4517 LocationSummary* GotoInstr::MakeLocationSummary() const { 4709 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const {
4518 return new LocationSummary(0, 0, LocationSummary::kNoCall); 4710 return new LocationSummary(0, 0, LocationSummary::kNoCall);
4519 } 4711 }
4520 4712
4521 4713
4522 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4714 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4523 if (!compiler->is_optimizing()) { 4715 if (!compiler->is_optimizing()) {
4524 compiler->EmitEdgeCounter(); 4716 compiler->EmitEdgeCounter();
4525 // Add a deoptimization descriptor for deoptimizing instructions that 4717 // Add a deoptimization descriptor for deoptimizing instructions that
4526 // may be inserted before this instruction. This descriptor points 4718 // may be inserted before this instruction. This descriptor points
4527 // after the edge counter for uniformity with ARM and MIPS, where we can 4719 // after the edge counter for uniformity with ARM and MIPS, where we can
4528 // reuse pattern matching that matches backwards from the end of the 4720 // reuse pattern matching that matches backwards from the end of the
4529 // pattern. 4721 // pattern.
4530 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4722 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4531 GetDeoptId(), 4723 GetDeoptId(),
4532 Scanner::kDummyTokenIndex); 4724 Scanner::kDummyTokenIndex);
4533 } 4725 }
4534 if (HasParallelMove()) { 4726 if (HasParallelMove()) {
4535 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4727 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4536 } 4728 }
4537 4729
4538 // We can fall through if the successor is the next block in the list. 4730 // We can fall through if the successor is the next block in the list.
4539 // Otherwise, we need a jump. 4731 // Otherwise, we need a jump.
4540 if (!compiler->CanFallThroughTo(successor())) { 4732 if (!compiler->CanFallThroughTo(successor())) {
4541 __ jmp(compiler->GetJumpLabel(successor())); 4733 __ jmp(compiler->GetJumpLabel(successor()));
4542 } 4734 }
4543 } 4735 }
4544 4736
4545 4737
4546 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 4738 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
4547 return LocationSummary::Make(0, 4739 return LocationSummary::Make(0,
4548 Location::RequiresRegister(), 4740 Location::RequiresRegister(),
4549 LocationSummary::kNoCall); 4741 LocationSummary::kNoCall);
4550 } 4742 }
4551 4743
4552 4744
4553 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4745 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4554 __ MoveRegister(locs()->out().reg(), CTX); 4746 __ MoveRegister(locs()->out().reg(), CTX);
4555 } 4747 }
4556 4748
4557 4749
4558 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 4750 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
4559 const intptr_t kNumInputs = 2; 4751 const intptr_t kNumInputs = 2;
4560 const intptr_t kNumTemps = 0; 4752 const intptr_t kNumTemps = 0;
4561 if (needs_number_check()) { 4753 if (needs_number_check()) {
4562 LocationSummary* locs = 4754 LocationSummary* locs =
4563 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4755 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4564 locs->set_in(0, Location::RegisterLocation(RAX)); 4756 locs->set_in(0, Location::RegisterLocation(RAX));
4565 locs->set_in(1, Location::RegisterLocation(RCX)); 4757 locs->set_in(1, Location::RegisterLocation(RCX));
4566 locs->set_out(Location::RegisterLocation(RAX)); 4758 locs->set_out(Location::RegisterLocation(RAX));
4567 return locs; 4759 return locs;
4568 } 4760 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4629 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 4821 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4630 BranchInstr* branch) { 4822 BranchInstr* branch) {
4631 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4823 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4632 4824
4633 BranchLabels labels = compiler->CreateBranchLabels(branch); 4825 BranchLabels labels = compiler->CreateBranchLabels(branch);
4634 Condition true_condition = EmitComparisonCode(compiler, labels); 4826 Condition true_condition = EmitComparisonCode(compiler, labels);
4635 EmitBranchOnCondition(compiler, true_condition, labels); 4827 EmitBranchOnCondition(compiler, true_condition, labels);
4636 } 4828 }
4637 4829
4638 4830
4639 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 4831 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
4640 const intptr_t kNumInputs = 0; 4832 const intptr_t kNumInputs = 0;
4641 const intptr_t kNumTemps = 1; 4833 const intptr_t kNumTemps = 1;
4642 LocationSummary* result = 4834 LocationSummary* result =
4643 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4835 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4644 result->set_out(Location::RegisterLocation(RAX)); 4836 result->set_out(Location::RegisterLocation(RAX));
4645 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 4837 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
4646 return result; 4838 return result;
4647 } 4839 }
4648 4840
4649 4841
4650 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4842 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4651 // The arguments to the stub include the closure, as does the arguments 4843 // The arguments to the stub include the closure, as does the arguments
4652 // descriptor. 4844 // descriptor.
4653 Register temp_reg = locs()->temp(0).reg(); 4845 Register temp_reg = locs()->temp(0).reg();
4654 int argument_count = ArgumentCount(); 4846 int argument_count = ArgumentCount();
4655 const Array& arguments_descriptor = 4847 const Array& arguments_descriptor =
4656 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 4848 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
4657 argument_names())); 4849 argument_names()));
4658 __ LoadObject(temp_reg, arguments_descriptor, PP); 4850 __ LoadObject(temp_reg, arguments_descriptor, PP);
4659 ASSERT(temp_reg == R10); 4851 ASSERT(temp_reg == R10);
4660 compiler->GenerateDartCall(deopt_id(), 4852 compiler->GenerateDartCall(deopt_id(),
4661 token_pos(), 4853 token_pos(),
4662 &StubCode::CallClosureFunctionLabel(), 4854 &StubCode::CallClosureFunctionLabel(),
4663 PcDescriptors::kClosureCall, 4855 PcDescriptors::kClosureCall,
4664 locs()); 4856 locs());
4665 __ Drop(argument_count); 4857 __ Drop(argument_count);
4666 } 4858 }
4667 4859
4668 4860
4669 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 4861 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
4670 return LocationSummary::Make(1, 4862 return LocationSummary::Make(1,
4671 Location::RequiresRegister(), 4863 Location::RequiresRegister(),
4672 LocationSummary::kNoCall); 4864 LocationSummary::kNoCall);
4673 } 4865 }
4674 4866
4675 4867
4676 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4868 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4677 Register value = locs()->in(0).reg(); 4869 Register value = locs()->in(0).reg();
4678 Register result = locs()->out().reg(); 4870 Register result = locs()->out().reg();
4679 4871
4680 Label done; 4872 Label done;
4681 __ LoadObject(result, Bool::True(), PP); 4873 __ LoadObject(result, Bool::True(), PP);
4682 __ CompareRegisters(result, value); 4874 __ CompareRegisters(result, value);
4683 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 4875 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
4684 __ LoadObject(result, Bool::False(), PP); 4876 __ LoadObject(result, Bool::False(), PP);
4685 __ Bind(&done); 4877 __ Bind(&done);
4686 } 4878 }
4687 4879
4688 4880
4689 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { 4881 LocationSummary* StoreVMFieldInstr::MakeLocationSummary(bool opt) const {
4690 const intptr_t kNumInputs = 2; 4882 const intptr_t kNumInputs = 2;
4691 const intptr_t kNumTemps = 0; 4883 const intptr_t kNumTemps = 0;
4692 LocationSummary* locs = 4884 LocationSummary* locs =
4693 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4885 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4694 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 4886 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
4695 : Location::RequiresRegister()); 4887 : Location::RequiresRegister());
4696 locs->set_in(1, Location::RequiresRegister()); 4888 locs->set_in(1, Location::RequiresRegister());
4697 return locs; 4889 return locs;
4698 } 4890 }
4699 4891
4700 4892
4701 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4893 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4702 Register value_reg = locs()->in(0).reg(); 4894 Register value_reg = locs()->in(0).reg();
4703 Register dest_reg = locs()->in(1).reg(); 4895 Register dest_reg = locs()->in(1).reg();
4704 4896
4705 if (value()->NeedsStoreBuffer()) { 4897 if (value()->NeedsStoreBuffer()) {
4706 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 4898 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
4707 value_reg); 4899 value_reg);
4708 } else { 4900 } else {
4709 __ StoreIntoObjectNoBarrier( 4901 __ StoreIntoObjectNoBarrier(
4710 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); 4902 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
4711 } 4903 }
4712 } 4904 }
4713 4905
4714 4906
4715 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 4907 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const {
4716 return MakeCallSummary(); 4908 return MakeCallSummary();
4717 } 4909 }
4718 4910
4719 4911
4720 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4912 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4721 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); 4913 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls()));
4722 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); 4914 const ExternalLabel label(cls().ToCString(), stub.EntryPoint());
4723 compiler->GenerateCall(token_pos(), 4915 compiler->GenerateCall(token_pos(),
4724 &label, 4916 &label,
4725 PcDescriptors::kOther, 4917 PcDescriptors::kOther,
4726 locs()); 4918 locs());
4727 __ Drop(ArgumentCount()); // Discard arguments. 4919 __ Drop(ArgumentCount()); // Discard arguments.
4728 } 4920 }
4729 4921
4730 4922
4731 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 4923 LocationSummary* CreateClosureInstr::MakeLocationSummary(bool opt) const {
4732 return MakeCallSummary(); 4924 return MakeCallSummary();
4733 } 4925 }
4734 4926
4735 4927
4736 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4928 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4737 const Function& closure_function = function(); 4929 const Function& closure_function = function();
4738 ASSERT(!closure_function.IsImplicitStaticClosureFunction()); 4930 ASSERT(!closure_function.IsImplicitStaticClosureFunction());
4739 const Code& stub = Code::Handle( 4931 const Code& stub = Code::Handle(
4740 StubCode::GetAllocationStubForClosure(closure_function)); 4932 StubCode::GetAllocationStubForClosure(closure_function));
4741 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); 4933 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
4742 compiler->GenerateCall(token_pos(), 4934 compiler->GenerateCall(token_pos(),
4743 &label, 4935 &label,
4744 PcDescriptors::kOther, 4936 PcDescriptors::kOther,
4745 locs()); 4937 locs());
4746 __ Drop(2); // Discard type arguments and receiver. 4938 __ Drop(2); // Discard type arguments and receiver.
4747 } 4939 }
4748 4940
4749 } // namespace dart 4941 } // namespace dart
4750 4942
4751 #undef __ 4943 #undef __
4752 4944
4753 #endif // defined TARGET_ARCH_X64 4945 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698