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

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

Issue 207063002: Refactor to support multiple outputs in location summary (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months 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
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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 12 matching lines...) Expand all
23 DECLARE_FLAG(int, optimization_counter_threshold); 23 DECLARE_FLAG(int, optimization_counter_threshold);
24 DECLARE_FLAG(bool, propagate_ic_data); 24 DECLARE_FLAG(bool, propagate_ic_data);
25 DECLARE_FLAG(bool, use_osr); 25 DECLARE_FLAG(bool, use_osr);
26 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 26 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
27 DECLARE_FLAG(bool, use_slow_path); 27 DECLARE_FLAG(bool, use_slow_path);
28 28
29 // Generic summary for call instructions that have all arguments pushed 29 // Generic summary for call instructions that have all arguments pushed
30 // on the stack and return the result in a fixed register EAX. 30 // on the stack and return the result in a fixed register EAX.
31 LocationSummary* Instruction::MakeCallSummary() { 31 LocationSummary* Instruction::MakeCallSummary() {
32 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 32 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
33 result->set_out(Location::RegisterLocation(EAX)); 33 result->set_out(0, Location::RegisterLocation(EAX));
34 return result; 34 return result;
35 } 35 }
36 36
37 37
38 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { 38 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const {
39 const intptr_t kNumInputs = 1; 39 const intptr_t kNumInputs = 1;
40 const intptr_t kNumTemps= 0; 40 const intptr_t kNumTemps= 0;
41 LocationSummary* locs = 41 LocationSummary* locs =
42 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 42 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
43 locs->set_in(0, Location::AnyOrConstant(value())); 43 locs->set_in(0, Location::AnyOrConstant(value()));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { 116 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
117 const intptr_t kNumInputs = 1; 117 const intptr_t kNumInputs = 1;
118 return LocationSummary::Make(kNumInputs, 118 return LocationSummary::Make(kNumInputs,
119 Location::SameAsFirstInput(), 119 Location::SameAsFirstInput(),
120 LocationSummary::kNoCall); 120 LocationSummary::kNoCall);
121 } 121 }
122 122
123 123
124 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 124 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
125 Register value = locs()->in(0).reg(); 125 Register value = locs()->in(0).reg();
126 Register result = locs()->out().reg(); 126 Register result = locs()->out(0).reg();
127 ASSERT(result == value); // Assert that register assignment is correct. 127 ASSERT(result == value); // Assert that register assignment is correct.
128 __ movl(Address(EBP, local().index() * kWordSize), value); 128 __ movl(Address(EBP, local().index() * kWordSize), value);
129 } 129 }
130 130
131 131
132 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { 132 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
133 const intptr_t kNumInputs = 0; 133 const intptr_t kNumInputs = 0;
134 return LocationSummary::Make(kNumInputs, 134 return LocationSummary::Make(kNumInputs,
135 Location::RequiresRegister(), 135 Location::RequiresRegister(),
136 LocationSummary::kNoCall); 136 LocationSummary::kNoCall);
137 } 137 }
138 138
139 139
140 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 140 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
141 // The register allocator drops constant definitions that have no uses. 141 // The register allocator drops constant definitions that have no uses.
142 if (!locs()->out().IsInvalid()) { 142 if (!locs()->out(0).IsInvalid()) {
143 Register result = locs()->out().reg(); 143 Register result = locs()->out(0).reg();
144 __ LoadObjectSafely(result, value()); 144 __ LoadObjectSafely(result, value());
145 } 145 }
146 } 146 }
147 147
148 148
149 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { 149 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
150 const intptr_t kNumInputs = 3; 150 const intptr_t kNumInputs = 3;
151 const intptr_t kNumTemps = 0; 151 const intptr_t kNumTemps = 0;
152 LocationSummary* summary = 152 LocationSummary* summary =
153 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 153 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
154 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. 154 summary->set_in(0, Location::RegisterLocation(EAX)); // Value.
155 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. 155 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator.
156 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. 156 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments.
157 summary->set_out(Location::RegisterLocation(EAX)); 157 summary->set_out(0, Location::RegisterLocation(EAX));
158 return summary; 158 return summary;
159 } 159 }
160 160
161 161
162 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { 162 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
163 const intptr_t kNumInputs = 1; 163 const intptr_t kNumInputs = 1;
164 const intptr_t kNumTemps = 0; 164 const intptr_t kNumTemps = 0;
165 LocationSummary* locs = 165 LocationSummary* locs =
166 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 166 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
167 locs->set_in(0, Location::RegisterLocation(EAX)); 167 locs->set_in(0, Location::RegisterLocation(EAX));
168 locs->set_out(Location::RegisterLocation(EAX)); 168 locs->set_out(0, Location::RegisterLocation(EAX));
169 return locs; 169 return locs;
170 } 170 }
171 171
172 172
173 static void EmitAssertBoolean(Register reg, 173 static void EmitAssertBoolean(Register reg,
174 intptr_t token_pos, 174 intptr_t token_pos,
175 intptr_t deopt_id, 175 intptr_t deopt_id,
176 LocationSummary* locs, 176 LocationSummary* locs,
177 FlowGraphCompiler* compiler) { 177 FlowGraphCompiler* compiler) {
178 // Check that the type of the value is allowed in conditional context. 178 // Check that the type of the value is allowed in conditional context.
(...skipping 12 matching lines...) Expand all
191 1, 191 1,
192 locs); 192 locs);
193 // We should never return here. 193 // We should never return here.
194 __ int3(); 194 __ int3();
195 __ Bind(&done); 195 __ Bind(&done);
196 } 196 }
197 197
198 198
199 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 199 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
200 Register obj = locs()->in(0).reg(); 200 Register obj = locs()->in(0).reg();
201 Register result = locs()->out().reg(); 201 Register result = locs()->out(0).reg();
202 202
203 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 203 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
204 ASSERT(obj == result); 204 ASSERT(obj == result);
205 } 205 }
206 206
207 207
208 static Condition TokenKindToSmiCondition(Token::Kind kind) { 208 static Condition TokenKindToSmiCondition(Token::Kind kind) {
209 switch (kind) { 209 switch (kind) {
210 case Token::kEQ: return EQUAL; 210 case Token::kEQ: return EQUAL;
211 case Token::kNE: return NOT_EQUAL; 211 case Token::kNE: return NOT_EQUAL;
(...skipping 10 matching lines...) Expand all
222 222
223 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { 223 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
224 const intptr_t kNumInputs = 2; 224 const intptr_t kNumInputs = 2;
225 if (operation_cid() == kMintCid) { 225 if (operation_cid() == kMintCid) {
226 const intptr_t kNumTemps = 1; 226 const intptr_t kNumTemps = 1;
227 LocationSummary* locs = 227 LocationSummary* locs =
228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
229 locs->set_in(0, Location::RequiresFpuRegister()); 229 locs->set_in(0, Location::RequiresFpuRegister());
230 locs->set_in(1, Location::RequiresFpuRegister()); 230 locs->set_in(1, Location::RequiresFpuRegister());
231 locs->set_temp(0, Location::RequiresRegister()); 231 locs->set_temp(0, Location::RequiresRegister());
232 locs->set_out(Location::RequiresRegister()); 232 locs->set_out(0, Location::RequiresRegister());
233 return locs; 233 return locs;
234 } 234 }
235 if (operation_cid() == kDoubleCid) { 235 if (operation_cid() == kDoubleCid) {
236 const intptr_t kNumTemps = 0; 236 const intptr_t kNumTemps = 0;
237 LocationSummary* locs = 237 LocationSummary* locs =
238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
239 locs->set_in(0, Location::RequiresFpuRegister()); 239 locs->set_in(0, Location::RequiresFpuRegister());
240 locs->set_in(1, Location::RequiresFpuRegister()); 240 locs->set_in(1, Location::RequiresFpuRegister());
241 locs->set_out(Location::RequiresRegister()); 241 locs->set_out(0, Location::RequiresRegister());
242 return locs; 242 return locs;
243 } 243 }
244 if (operation_cid() == kSmiCid) { 244 if (operation_cid() == kSmiCid) {
245 const intptr_t kNumTemps = 0; 245 const intptr_t kNumTemps = 0;
246 LocationSummary* locs = 246 LocationSummary* locs =
247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
248 locs->set_in(0, Location::RegisterOrConstant(left())); 248 locs->set_in(0, Location::RegisterOrConstant(left()));
249 // Only one input can be a constant operand. The case of two constant 249 // Only one input can be a constant operand. The case of two constant
250 // operands should be handled by constant propagation. 250 // operands should be handled by constant propagation.
251 // Only right can be a stack slot. 251 // Only right can be a stack slot.
252 locs->set_in(1, locs->in(0).IsConstant() 252 locs->set_in(1, locs->in(0).IsConstant()
253 ? Location::RequiresRegister() 253 ? Location::RequiresRegister()
254 : Location::RegisterOrConstant(right())); 254 : Location::RegisterOrConstant(right()));
255 locs->set_out(Location::RequiresRegister()); 255 locs->set_out(0, Location::RequiresRegister());
256 return locs; 256 return locs;
257 } 257 }
258 UNREACHABLE(); 258 UNREACHABLE();
259 return NULL; 259 return NULL;
260 } 260 }
261 261
262 262
263 static void LoadValueCid(FlowGraphCompiler* compiler, 263 static void LoadValueCid(FlowGraphCompiler* compiler,
264 Register value_cid_reg, 264 Register value_cid_reg,
265 Register value_reg, 265 Register value_reg,
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 512
513 513
514 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 514 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
515 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 515 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
516 516
517 Label is_true, is_false; 517 Label is_true, is_false;
518 BranchLabels labels = { &is_true, &is_false, &is_false }; 518 BranchLabels labels = { &is_true, &is_false, &is_false };
519 Condition true_condition = EmitComparisonCode(compiler, labels); 519 Condition true_condition = EmitComparisonCode(compiler, labels);
520 EmitBranchOnCondition(compiler, true_condition, labels); 520 EmitBranchOnCondition(compiler, true_condition, labels);
521 521
522 Register result = locs()->out().reg(); 522 Register result = locs()->out(0).reg();
523 Label done; 523 Label done;
524 __ Bind(&is_false); 524 __ Bind(&is_false);
525 __ LoadObject(result, Bool::False()); 525 __ LoadObject(result, Bool::False());
526 __ jmp(&done, Assembler::kNearJump); 526 __ jmp(&done, Assembler::kNearJump);
527 __ Bind(&is_true); 527 __ Bind(&is_true);
528 __ LoadObject(result, Bool::True()); 528 __ LoadObject(result, Bool::True());
529 __ Bind(&done); 529 __ Bind(&done);
530 } 530 }
531 531
532 532
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 const intptr_t kNumInputs = 2; 588 const intptr_t kNumInputs = 2;
589 const intptr_t kNumTemps = 0; 589 const intptr_t kNumTemps = 0;
590 if (operation_cid() == kMintCid) { 590 if (operation_cid() == kMintCid) {
591 const intptr_t kNumTemps = 2; 591 const intptr_t kNumTemps = 2;
592 LocationSummary* locs = 592 LocationSummary* locs =
593 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 593 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
594 locs->set_in(0, Location::RequiresFpuRegister()); 594 locs->set_in(0, Location::RequiresFpuRegister());
595 locs->set_in(1, Location::RequiresFpuRegister()); 595 locs->set_in(1, Location::RequiresFpuRegister());
596 locs->set_temp(0, Location::RequiresRegister()); 596 locs->set_temp(0, Location::RequiresRegister());
597 locs->set_temp(1, Location::RequiresRegister()); 597 locs->set_temp(1, Location::RequiresRegister());
598 locs->set_out(Location::RequiresRegister()); 598 locs->set_out(0, Location::RequiresRegister());
599 return locs; 599 return locs;
600 } 600 }
601 if (operation_cid() == kDoubleCid) { 601 if (operation_cid() == kDoubleCid) {
602 LocationSummary* summary = 602 LocationSummary* summary =
603 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 603 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
604 summary->set_in(0, Location::RequiresFpuRegister()); 604 summary->set_in(0, Location::RequiresFpuRegister());
605 summary->set_in(1, Location::RequiresFpuRegister()); 605 summary->set_in(1, Location::RequiresFpuRegister());
606 summary->set_out(Location::RequiresRegister()); 606 summary->set_out(0, Location::RequiresRegister());
607 return summary; 607 return summary;
608 } 608 }
609 ASSERT(operation_cid() == kSmiCid); 609 ASSERT(operation_cid() == kSmiCid);
610 LocationSummary* summary = 610 LocationSummary* summary =
611 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 611 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
612 summary->set_in(0, Location::RegisterOrConstant(left())); 612 summary->set_in(0, Location::RegisterOrConstant(left()));
613 // Only one input can be a constant operand. The case of two constant 613 // Only one input can be a constant operand. The case of two constant
614 // operands should be handled by constant propagation. 614 // operands should be handled by constant propagation.
615 summary->set_in(1, summary->in(0).IsConstant() 615 summary->set_in(1, summary->in(0).IsConstant()
616 ? Location::RequiresRegister() 616 ? Location::RequiresRegister()
617 : Location::RegisterOrConstant(right())); 617 : Location::RegisterOrConstant(right()));
618 summary->set_out(Location::RequiresRegister()); 618 summary->set_out(0, Location::RequiresRegister());
619 return summary; 619 return summary;
620 } 620 }
621 621
622 622
623 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 623 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
624 BranchLabels labels) { 624 BranchLabels labels) {
625 if (operation_cid() == kSmiCid) { 625 if (operation_cid() == kSmiCid) {
626 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 626 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
627 } else if (operation_cid() == kMintCid) { 627 } else if (operation_cid() == kMintCid) {
628 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); 628 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
629 } else { 629 } else {
630 ASSERT(operation_cid() == kDoubleCid); 630 ASSERT(operation_cid() == kDoubleCid);
631 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 631 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
632 } 632 }
633 } 633 }
634 634
635 635
636 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 636 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
637 Label is_true, is_false; 637 Label is_true, is_false;
638 BranchLabels labels = { &is_true, &is_false, &is_false }; 638 BranchLabels labels = { &is_true, &is_false, &is_false };
639 Condition true_condition = EmitComparisonCode(compiler, labels); 639 Condition true_condition = EmitComparisonCode(compiler, labels);
640 EmitBranchOnCondition(compiler, true_condition, labels); 640 EmitBranchOnCondition(compiler, true_condition, labels);
641 641
642 Register result = locs()->out().reg(); 642 Register result = locs()->out(0).reg();
643 Label done; 643 Label done;
644 __ Bind(&is_false); 644 __ Bind(&is_false);
645 __ LoadObject(result, Bool::False()); 645 __ LoadObject(result, Bool::False());
646 __ jmp(&done, Assembler::kNearJump); 646 __ jmp(&done, Assembler::kNearJump);
647 __ Bind(&is_true); 647 __ Bind(&is_true);
648 __ LoadObject(result, Bool::True()); 648 __ LoadObject(result, Bool::True());
649 __ Bind(&done); 649 __ Bind(&done);
650 } 650 }
651 651
652 652
653 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 653 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
654 BranchInstr* branch) { 654 BranchInstr* branch) {
655 BranchLabels labels = compiler->CreateBranchLabels(branch); 655 BranchLabels labels = compiler->CreateBranchLabels(branch);
656 Condition true_condition = EmitComparisonCode(compiler, labels); 656 Condition true_condition = EmitComparisonCode(compiler, labels);
657 EmitBranchOnCondition(compiler, true_condition, labels); 657 EmitBranchOnCondition(compiler, true_condition, labels);
658 } 658 }
659 659
660 660
661 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 661 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
662 const intptr_t kNumInputs = 0; 662 const intptr_t kNumInputs = 0;
663 const intptr_t kNumTemps = 3; 663 const intptr_t kNumTemps = 3;
664 LocationSummary* locs = 664 LocationSummary* locs =
665 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 665 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
666 locs->set_temp(0, Location::RegisterLocation(EAX)); 666 locs->set_temp(0, Location::RegisterLocation(EAX));
667 locs->set_temp(1, Location::RegisterLocation(ECX)); 667 locs->set_temp(1, Location::RegisterLocation(ECX));
668 locs->set_temp(2, Location::RegisterLocation(EDX)); 668 locs->set_temp(2, Location::RegisterLocation(EDX));
669 locs->set_out(Location::RegisterLocation(EAX)); 669 locs->set_out(0, Location::RegisterLocation(EAX));
670 return locs; 670 return locs;
671 } 671 }
672 672
673 673
674 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 674 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
675 ASSERT(locs()->temp(0).reg() == EAX); 675 ASSERT(locs()->temp(0).reg() == EAX);
676 ASSERT(locs()->temp(1).reg() == ECX); 676 ASSERT(locs()->temp(1).reg() == ECX);
677 ASSERT(locs()->temp(2).reg() == EDX); 677 ASSERT(locs()->temp(2).reg() == EDX);
678 Register result = locs()->out().reg(); 678 Register result = locs()->out(0).reg();
679 679
680 // Push the result place holder initialized to NULL. 680 // Push the result place holder initialized to NULL.
681 __ PushObject(Object::ZoneHandle()); 681 __ PushObject(Object::ZoneHandle());
682 // Pass a pointer to the first argument in EAX. 682 // Pass a pointer to the first argument in EAX.
683 if (!function().HasOptionalParameters()) { 683 if (!function().HasOptionalParameters()) {
684 __ leal(EAX, Address(EBP, (kParamEndSlotFromFp + 684 __ leal(EAX, Address(EBP, (kParamEndSlotFromFp +
685 function().NumParameters()) * kWordSize)); 685 function().NumParameters()) * kWordSize));
686 } else { 686 } else {
687 __ leal(EAX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); 687 __ leal(EAX, Address(EBP, kFirstLocalSlotFromFp * kWordSize));
688 } 688 }
(...skipping 27 matching lines...) Expand all
716 const intptr_t kNumInputs = 1; 716 const intptr_t kNumInputs = 1;
717 // TODO(fschneider): Allow immediate operands for the char code. 717 // TODO(fschneider): Allow immediate operands for the char code.
718 return LocationSummary::Make(kNumInputs, 718 return LocationSummary::Make(kNumInputs,
719 Location::RequiresRegister(), 719 Location::RequiresRegister(),
720 LocationSummary::kNoCall); 720 LocationSummary::kNoCall);
721 } 721 }
722 722
723 723
724 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 724 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
725 Register char_code = locs()->in(0).reg(); 725 Register char_code = locs()->in(0).reg();
726 Register result = locs()->out().reg(); 726 Register result = locs()->out(0).reg();
727 __ movl(result, 727 __ movl(result,
728 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 728 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
729 __ movl(result, Address(result, 729 __ movl(result, Address(result,
730 char_code, 730 char_code,
731 TIMES_HALF_WORD_SIZE, // Char code is a smi. 731 TIMES_HALF_WORD_SIZE, // Char code is a smi.
732 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 732 Symbols::kNullCharCodeSymbolOffset * kWordSize));
733 } 733 }
734 734
735 735
736 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { 736 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const {
737 const intptr_t kNumInputs = 1; 737 const intptr_t kNumInputs = 1;
738 return LocationSummary::Make(kNumInputs, 738 return LocationSummary::Make(kNumInputs,
739 Location::RequiresRegister(), 739 Location::RequiresRegister(),
740 LocationSummary::kNoCall); 740 LocationSummary::kNoCall);
741 } 741 }
742 742
743 743
744 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 744 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
745 ASSERT(cid_ == kOneByteStringCid); 745 ASSERT(cid_ == kOneByteStringCid);
746 Register str = locs()->in(0).reg(); 746 Register str = locs()->in(0).reg();
747 Register result = locs()->out().reg(); 747 Register result = locs()->out(0).reg();
748 Label is_one, done; 748 Label is_one, done;
749 __ movl(result, FieldAddress(str, String::length_offset())); 749 __ movl(result, FieldAddress(str, String::length_offset()));
750 __ cmpl(result, Immediate(Smi::RawValue(1))); 750 __ cmpl(result, Immediate(Smi::RawValue(1)));
751 __ j(EQUAL, &is_one, Assembler::kNearJump); 751 __ j(EQUAL, &is_one, Assembler::kNearJump);
752 __ movl(result, Immediate(Smi::RawValue(-1))); 752 __ movl(result, Immediate(Smi::RawValue(-1)));
753 __ jmp(&done); 753 __ jmp(&done);
754 __ Bind(&is_one); 754 __ Bind(&is_one);
755 __ movzxb(result, FieldAddress(str, OneByteString::data_offset())); 755 __ movzxb(result, FieldAddress(str, OneByteString::data_offset()));
756 __ SmiTag(result); 756 __ SmiTag(result);
757 __ Bind(&done); 757 __ Bind(&done);
758 } 758 }
759 759
760 760
761 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { 761 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
762 const intptr_t kNumInputs = 1; 762 const intptr_t kNumInputs = 1;
763 const intptr_t kNumTemps = 0; 763 const intptr_t kNumTemps = 0;
764 LocationSummary* summary = 764 LocationSummary* summary =
765 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 765 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
766 summary->set_in(0, Location::RegisterLocation(EAX)); 766 summary->set_in(0, Location::RegisterLocation(EAX));
767 summary->set_out(Location::RegisterLocation(EAX)); 767 summary->set_out(0, Location::RegisterLocation(EAX));
768 return summary; 768 return summary;
769 } 769 }
770 770
771 771
772 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 772 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
773 Register array = locs()->in(0).reg(); 773 Register array = locs()->in(0).reg();
774 __ pushl(array); 774 __ pushl(array);
775 const int kNumberOfArguments = 1; 775 const int kNumberOfArguments = 1;
776 const Array& kNoArgumentNames = Object::null_array(); 776 const Array& kNoArgumentNames = Object::null_array();
777 compiler->GenerateStaticCall(deopt_id(), 777 compiler->GenerateStaticCall(deopt_id(),
778 token_pos(), 778 token_pos(),
779 CallFunction(), 779 CallFunction(),
780 kNumberOfArguments, 780 kNumberOfArguments,
781 kNoArgumentNames, 781 kNoArgumentNames,
782 locs()); 782 locs());
783 ASSERT(locs()->out().reg() == EAX); 783 ASSERT(locs()->out(0).reg() == EAX);
784 } 784 }
785 785
786 786
787 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { 787 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
788 const intptr_t kNumInputs = 1; 788 const intptr_t kNumInputs = 1;
789 return LocationSummary::Make(kNumInputs, 789 return LocationSummary::Make(kNumInputs,
790 Location::RequiresRegister(), 790 Location::RequiresRegister(),
791 LocationSummary::kNoCall); 791 LocationSummary::kNoCall);
792 } 792 }
793 793
794 794
795 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 795 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
796 Register object = locs()->in(0).reg(); 796 Register object = locs()->in(0).reg();
797 Register result = locs()->out().reg(); 797 Register result = locs()->out(0).reg();
798 __ movl(result, FieldAddress(object, offset())); 798 __ movl(result, FieldAddress(object, offset()));
799 } 799 }
800 800
801 801
802 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { 802 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const {
803 const intptr_t kNumInputs = 1; 803 const intptr_t kNumInputs = 1;
804 return LocationSummary::Make(kNumInputs, 804 return LocationSummary::Make(kNumInputs,
805 Location::RequiresRegister(), 805 Location::RequiresRegister(),
806 LocationSummary::kNoCall); 806 LocationSummary::kNoCall);
807 } 807 }
808 808
809 809
810 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 810 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
811 Register object = locs()->in(0).reg(); 811 Register object = locs()->in(0).reg();
812 Register result = locs()->out().reg(); 812 Register result = locs()->out(0).reg();
813 Label load, done; 813 Label load, done;
814 __ testl(object, Immediate(kSmiTagMask)); 814 __ testl(object, Immediate(kSmiTagMask));
815 __ j(NOT_ZERO, &load, Assembler::kNearJump); 815 __ j(NOT_ZERO, &load, Assembler::kNearJump);
816 __ movl(result, Immediate(Smi::RawValue(kSmiCid))); 816 __ movl(result, Immediate(Smi::RawValue(kSmiCid)));
817 __ jmp(&done); 817 __ jmp(&done);
818 __ Bind(&load); 818 __ Bind(&load);
819 __ LoadClassId(result, object); 819 __ LoadClassId(result, object);
820 __ SmiTag(result); 820 __ SmiTag(result);
821 __ Bind(&done); 821 __ Bind(&done);
822 } 822 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 // The index is either untagged (element size == 1) or a smi (for all 912 // The index is either untagged (element size == 1) or a smi (for all
913 // element sizes > 1). 913 // element sizes > 1).
914 locs->set_in(1, (index_scale() == 1) 914 locs->set_in(1, (index_scale() == 1)
915 ? Location::WritableRegister() 915 ? Location::WritableRegister()
916 : Location::RequiresRegister()); 916 : Location::RequiresRegister());
917 } 917 }
918 if ((representation() == kUnboxedDouble) || 918 if ((representation() == kUnboxedDouble) ||
919 (representation() == kUnboxedFloat32x4) || 919 (representation() == kUnboxedFloat32x4) ||
920 (representation() == kUnboxedInt32x4) || 920 (representation() == kUnboxedInt32x4) ||
921 (representation() == kUnboxedFloat64x2)) { 921 (representation() == kUnboxedFloat64x2)) {
922 locs->set_out(Location::RequiresFpuRegister()); 922 locs->set_out(0, Location::RequiresFpuRegister());
923 } else { 923 } else {
924 locs->set_out(Location::RequiresRegister()); 924 locs->set_out(0, Location::RequiresRegister());
925 } 925 }
926 return locs; 926 return locs;
927 } 927 }
928 928
929 929
930 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 930 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
931 Register array = locs()->in(0).reg(); 931 Register array = locs()->in(0).reg();
932 Location index = locs()->in(1); 932 Location index = locs()->in(1);
933 933
934 Address element_address(kNoRegister, 0); 934 Address element_address(kNoRegister, 0);
(...skipping 11 matching lines...) Expand all
946 : FlowGraphCompiler::ElementAddressForIntIndex( 946 : FlowGraphCompiler::ElementAddressForIntIndex(
947 class_id(), index_scale(), array, 947 class_id(), index_scale(), array,
948 Smi::Cast(index.constant()).Value()); 948 Smi::Cast(index.constant()).Value());
949 } 949 }
950 950
951 if ((representation() == kUnboxedDouble) || 951 if ((representation() == kUnboxedDouble) ||
952 (representation() == kUnboxedMint) || 952 (representation() == kUnboxedMint) ||
953 (representation() == kUnboxedFloat32x4) || 953 (representation() == kUnboxedFloat32x4) ||
954 (representation() == kUnboxedInt32x4) || 954 (representation() == kUnboxedInt32x4) ||
955 (representation() == kUnboxedFloat64x2)) { 955 (representation() == kUnboxedFloat64x2)) {
956 XmmRegister result = locs()->out().fpu_reg(); 956 XmmRegister result = locs()->out(0).fpu_reg();
957 if ((index_scale() == 1) && index.IsRegister()) { 957 if ((index_scale() == 1) && index.IsRegister()) {
958 __ SmiUntag(index.reg()); 958 __ SmiUntag(index.reg());
959 } 959 }
960 switch (class_id()) { 960 switch (class_id()) {
961 case kTypedDataInt32ArrayCid: 961 case kTypedDataInt32ArrayCid:
962 __ movss(result, element_address); 962 __ movss(result, element_address);
963 __ pmovsxdq(result, result); 963 __ pmovsxdq(result, result);
964 break; 964 break;
965 case kTypedDataUint32ArrayCid: 965 case kTypedDataUint32ArrayCid:
966 __ xorpd(result, result); 966 __ xorpd(result, result);
967 __ movss(result, element_address); 967 __ movss(result, element_address);
968 break; 968 break;
969 case kTypedDataFloat32ArrayCid: 969 case kTypedDataFloat32ArrayCid:
970 __ movss(result, element_address); 970 __ movss(result, element_address);
971 break; 971 break;
972 case kTypedDataFloat64ArrayCid: 972 case kTypedDataFloat64ArrayCid:
973 __ movsd(result, element_address); 973 __ movsd(result, element_address);
974 break; 974 break;
975 case kTypedDataInt32x4ArrayCid: 975 case kTypedDataInt32x4ArrayCid:
976 case kTypedDataFloat32x4ArrayCid: 976 case kTypedDataFloat32x4ArrayCid:
977 case kTypedDataFloat64x2ArrayCid: 977 case kTypedDataFloat64x2ArrayCid:
978 __ movups(result, element_address); 978 __ movups(result, element_address);
979 break; 979 break;
980 } 980 }
981 return; 981 return;
982 } 982 }
983 983
984 Register result = locs()->out().reg(); 984 Register result = locs()->out(0).reg();
985 if ((index_scale() == 1) && index.IsRegister()) { 985 if ((index_scale() == 1) && index.IsRegister()) {
986 __ SmiUntag(index.reg()); 986 __ SmiUntag(index.reg());
987 } 987 }
988 switch (class_id()) { 988 switch (class_id()) {
989 case kTypedDataInt8ArrayCid: 989 case kTypedDataInt8ArrayCid:
990 ASSERT(index_scale() == 1); 990 ASSERT(index_scale() == 1);
991 __ movsxb(result, element_address); 991 __ movsxb(result, element_address);
992 __ SmiTag(result); 992 __ SmiTag(result);
993 break; 993 break;
994 case kTypedDataUint8ArrayCid: 994 case kTypedDataUint8ArrayCid:
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 : instruction_(instruction), cls_(cls) { } 1601 : instruction_(instruction), cls_(cls) { }
1602 1602
1603 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1603 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1604 __ Comment("StoreInstanceFieldSlowPath"); 1604 __ Comment("StoreInstanceFieldSlowPath");
1605 __ Bind(entry_label()); 1605 __ Bind(entry_label());
1606 const Code& stub = 1606 const Code& stub =
1607 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1607 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1608 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1608 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1609 1609
1610 LocationSummary* locs = instruction_->locs(); 1610 LocationSummary* locs = instruction_->locs();
1611 locs->live_registers()->Remove(locs->out()); 1611 locs->live_registers()->Remove(locs->out(0));
1612 compiler->SaveLiveRegisters(locs); 1612 compiler->SaveLiveRegisters(locs);
1613 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1613 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1614 &label, 1614 &label,
1615 PcDescriptors::kOther, 1615 PcDescriptors::kOther,
1616 locs); 1616 locs);
1617 __ MoveRegister(locs->temp(0).reg(), EAX); 1617 __ MoveRegister(locs->temp(0).reg(), EAX);
1618 compiler->RestoreLiveRegisters(locs); 1618 compiler->RestoreLiveRegisters(locs);
1619 __ jmp(exit_label()); 1619 __ jmp(exit_label());
1620 } 1620 }
1621 1621
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 1881
1882 1882
1883 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { 1883 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1884 const intptr_t kNumInputs = 1; 1884 const intptr_t kNumInputs = 1;
1885 const intptr_t kNumTemps = 0; 1885 const intptr_t kNumTemps = 0;
1886 LocationSummary* summary = 1886 LocationSummary* summary =
1887 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1887 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1888 summary->set_in(0, Location::RequiresRegister()); 1888 summary->set_in(0, Location::RequiresRegister());
1889 // By specifying same register as input, our simple register allocator can 1889 // By specifying same register as input, our simple register allocator can
1890 // generate better code. 1890 // generate better code.
1891 summary->set_out(Location::SameAsFirstInput()); 1891 summary->set_out(0, Location::SameAsFirstInput());
1892 return summary; 1892 return summary;
1893 } 1893 }
1894 1894
1895 1895
1896 // When the parser is building an implicit static getter for optimization, 1896 // When the parser is building an implicit static getter for optimization,
1897 // it can generate a function body where deoptimization ids do not line up 1897 // it can generate a function body where deoptimization ids do not line up
1898 // with the unoptimized code. 1898 // with the unoptimized code.
1899 // 1899 //
1900 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1900 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1901 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1901 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1902 Register field = locs()->in(0).reg(); 1902 Register field = locs()->in(0).reg();
1903 Register result = locs()->out().reg(); 1903 Register result = locs()->out(0).reg();
1904 __ movl(result, FieldAddress(field, Field::value_offset())); 1904 __ movl(result, FieldAddress(field, Field::value_offset()));
1905 } 1905 }
1906 1906
1907 1907
1908 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { 1908 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1909 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1909 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1910 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1910 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1911 : Location::RequiresRegister()); 1911 : Location::RequiresRegister());
1912 locs->set_temp(0, Location::RequiresRegister()); 1912 locs->set_temp(0, Location::RequiresRegister());
1913 return locs; 1913 return locs;
(...skipping 16 matching lines...) Expand all
1930 1930
1931 1931
1932 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { 1932 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1933 const intptr_t kNumInputs = 3; 1933 const intptr_t kNumInputs = 3;
1934 const intptr_t kNumTemps = 0; 1934 const intptr_t kNumTemps = 0;
1935 LocationSummary* summary = 1935 LocationSummary* summary =
1936 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1936 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1937 summary->set_in(0, Location::RegisterLocation(EAX)); 1937 summary->set_in(0, Location::RegisterLocation(EAX));
1938 summary->set_in(1, Location::RegisterLocation(ECX)); 1938 summary->set_in(1, Location::RegisterLocation(ECX));
1939 summary->set_in(2, Location::RegisterLocation(EDX)); 1939 summary->set_in(2, Location::RegisterLocation(EDX));
1940 summary->set_out(Location::RegisterLocation(EAX)); 1940 summary->set_out(0, Location::RegisterLocation(EAX));
1941 return summary; 1941 return summary;
1942 } 1942 }
1943 1943
1944 1944
1945 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1945 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1946 ASSERT(locs()->in(0).reg() == EAX); // Value. 1946 ASSERT(locs()->in(0).reg() == EAX); // Value.
1947 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1947 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1948 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1948 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1949 1949
1950 compiler->GenerateInstanceOf(token_pos(), 1950 compiler->GenerateInstanceOf(token_pos(),
1951 deopt_id(), 1951 deopt_id(),
1952 type(), 1952 type(),
1953 negate_result(), 1953 negate_result(),
1954 locs()); 1954 locs());
1955 ASSERT(locs()->out().reg() == EAX); 1955 ASSERT(locs()->out(0).reg() == EAX);
1956 } 1956 }
1957 1957
1958 1958
1959 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { 1959 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1960 const intptr_t kNumInputs = 2; 1960 const intptr_t kNumInputs = 2;
1961 const intptr_t kNumTemps = 0; 1961 const intptr_t kNumTemps = 0;
1962 LocationSummary* locs = 1962 LocationSummary* locs =
1963 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1963 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1964 locs->set_in(0, Location::RegisterLocation(ECX)); 1964 locs->set_in(0, Location::RegisterLocation(ECX));
1965 locs->set_in(1, Location::RegisterLocation(EDX)); 1965 locs->set_in(1, Location::RegisterLocation(EDX));
1966 locs->set_out(Location::RegisterLocation(EAX)); 1966 locs->set_out(0, Location::RegisterLocation(EAX));
1967 return locs; 1967 return locs;
1968 } 1968 }
1969 1969
1970 1970
1971 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1971 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1972 // Allocate the array. EDX = length, ECX = element type. 1972 // Allocate the array. EDX = length, ECX = element type.
1973 ASSERT(locs()->in(0).reg() == ECX); 1973 ASSERT(locs()->in(0).reg() == ECX);
1974 ASSERT(locs()->in(1).reg() == EDX); 1974 ASSERT(locs()->in(1).reg() == EDX);
1975 compiler->GenerateCall(token_pos(), 1975 compiler->GenerateCall(token_pos(),
1976 &StubCode::AllocateArrayLabel(), 1976 &StubCode::AllocateArrayLabel(),
1977 PcDescriptors::kOther, 1977 PcDescriptors::kOther,
1978 locs()); 1978 locs());
1979 ASSERT(locs()->out().reg() == EAX); 1979 ASSERT(locs()->out(0).reg() == EAX);
1980 } 1980 }
1981 1981
1982 1982
1983 class BoxDoubleSlowPath : public SlowPathCode { 1983 class BoxDoubleSlowPath : public SlowPathCode {
1984 public: 1984 public:
1985 explicit BoxDoubleSlowPath(Instruction* instruction) 1985 explicit BoxDoubleSlowPath(Instruction* instruction)
1986 : instruction_(instruction) { } 1986 : instruction_(instruction) { }
1987 1987
1988 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1988 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1989 __ Comment("BoxDoubleSlowPath"); 1989 __ Comment("BoxDoubleSlowPath");
1990 __ Bind(entry_label()); 1990 __ Bind(entry_label());
1991 const Class& double_class = compiler->double_class(); 1991 const Class& double_class = compiler->double_class();
1992 const Code& stub = 1992 const Code& stub =
1993 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1993 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1994 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1994 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1995 1995
1996 LocationSummary* locs = instruction_->locs(); 1996 LocationSummary* locs = instruction_->locs();
1997 locs->live_registers()->Remove(locs->out()); 1997 locs->live_registers()->Remove(locs->out(0));
1998 1998
1999 compiler->SaveLiveRegisters(locs); 1999 compiler->SaveLiveRegisters(locs);
2000 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2000 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2001 &label, 2001 &label,
2002 PcDescriptors::kOther, 2002 PcDescriptors::kOther,
2003 locs); 2003 locs);
2004 __ MoveRegister(locs->out().reg(), EAX); 2004 __ MoveRegister(locs->out(0).reg(), EAX);
2005 compiler->RestoreLiveRegisters(locs); 2005 compiler->RestoreLiveRegisters(locs);
2006 2006
2007 __ jmp(exit_label()); 2007 __ jmp(exit_label());
2008 } 2008 }
2009 2009
2010 private: 2010 private:
2011 Instruction* instruction_; 2011 Instruction* instruction_;
2012 }; 2012 };
2013 2013
2014 2014
2015 class BoxFloat32x4SlowPath : public SlowPathCode { 2015 class BoxFloat32x4SlowPath : public SlowPathCode {
2016 public: 2016 public:
2017 explicit BoxFloat32x4SlowPath(Instruction* instruction) 2017 explicit BoxFloat32x4SlowPath(Instruction* instruction)
2018 : instruction_(instruction) { } 2018 : instruction_(instruction) { }
2019 2019
2020 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2020 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2021 __ Comment("BoxFloat32x4SlowPath"); 2021 __ Comment("BoxFloat32x4SlowPath");
2022 __ Bind(entry_label()); 2022 __ Bind(entry_label());
2023 const Class& float32x4_class = compiler->float32x4_class(); 2023 const Class& float32x4_class = compiler->float32x4_class();
2024 const Code& stub = 2024 const Code& stub =
2025 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); 2025 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2026 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); 2026 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2027 2027
2028 LocationSummary* locs = instruction_->locs(); 2028 LocationSummary* locs = instruction_->locs();
2029 locs->live_registers()->Remove(locs->out()); 2029 locs->live_registers()->Remove(locs->out(0));
2030 2030
2031 compiler->SaveLiveRegisters(locs); 2031 compiler->SaveLiveRegisters(locs);
2032 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2032 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2033 &label, 2033 &label,
2034 PcDescriptors::kOther, 2034 PcDescriptors::kOther,
2035 locs); 2035 locs);
2036 __ MoveRegister(locs->out().reg(), EAX); 2036 __ MoveRegister(locs->out(0).reg(), EAX);
2037 compiler->RestoreLiveRegisters(locs); 2037 compiler->RestoreLiveRegisters(locs);
2038 2038
2039 __ jmp(exit_label()); 2039 __ jmp(exit_label());
2040 } 2040 }
2041 2041
2042 private: 2042 private:
2043 Instruction* instruction_; 2043 Instruction* instruction_;
2044 }; 2044 };
2045 2045
2046 2046
2047 class BoxFloat64x2SlowPath : public SlowPathCode { 2047 class BoxFloat64x2SlowPath : public SlowPathCode {
2048 public: 2048 public:
2049 explicit BoxFloat64x2SlowPath(Instruction* instruction) 2049 explicit BoxFloat64x2SlowPath(Instruction* instruction)
2050 : instruction_(instruction) { } 2050 : instruction_(instruction) { }
2051 2051
2052 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2052 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2053 __ Comment("BoxFloat64x2SlowPath"); 2053 __ Comment("BoxFloat64x2SlowPath");
2054 __ Bind(entry_label()); 2054 __ Bind(entry_label());
2055 const Class& float64x2_class = compiler->float64x2_class(); 2055 const Class& float64x2_class = compiler->float64x2_class();
2056 const Code& stub = 2056 const Code& stub =
2057 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); 2057 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
2058 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); 2058 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
2059 2059
2060 LocationSummary* locs = instruction_->locs(); 2060 LocationSummary* locs = instruction_->locs();
2061 locs->live_registers()->Remove(locs->out()); 2061 locs->live_registers()->Remove(locs->out(0));
2062 2062
2063 compiler->SaveLiveRegisters(locs); 2063 compiler->SaveLiveRegisters(locs);
2064 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2064 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2065 &label, 2065 &label,
2066 PcDescriptors::kOther, 2066 PcDescriptors::kOther,
2067 locs); 2067 locs);
2068 __ MoveRegister(locs->out().reg(), EAX); 2068 __ MoveRegister(locs->out(0).reg(), EAX);
2069 compiler->RestoreLiveRegisters(locs); 2069 compiler->RestoreLiveRegisters(locs);
2070 2070
2071 __ jmp(exit_label()); 2071 __ jmp(exit_label());
2072 } 2072 }
2073 2073
2074 private: 2074 private:
2075 Instruction* instruction_; 2075 Instruction* instruction_;
2076 }; 2076 };
2077 2077
2078 2078
2079 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2079 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
2080 const intptr_t kNumInputs = 1; 2080 const intptr_t kNumInputs = 1;
2081 const intptr_t kNumTemps = 0; 2081 const intptr_t kNumTemps = 0;
2082 LocationSummary* locs = 2082 LocationSummary* locs =
2083 new LocationSummary( 2083 new LocationSummary(
2084 kNumInputs, kNumTemps, 2084 kNumInputs, kNumTemps,
2085 (opt && !IsPotentialUnboxedLoad()) 2085 (opt && !IsPotentialUnboxedLoad())
2086 ? LocationSummary::kNoCall 2086 ? LocationSummary::kNoCall
2087 : LocationSummary::kCallOnSlowPath); 2087 : LocationSummary::kCallOnSlowPath);
2088 2088
2089 locs->set_in(0, Location::RequiresRegister()); 2089 locs->set_in(0, Location::RequiresRegister());
2090 2090
2091 if (IsUnboxedLoad() && opt) { 2091 if (IsUnboxedLoad() && opt) {
2092 locs->AddTemp(Location::RequiresRegister()); 2092 locs->AddTemp(Location::RequiresRegister());
2093 } else if (IsPotentialUnboxedLoad()) { 2093 } else if (IsPotentialUnboxedLoad()) {
2094 locs->AddTemp(opt ? Location::RequiresFpuRegister() 2094 locs->AddTemp(opt ? Location::RequiresFpuRegister()
2095 : Location::FpuRegisterLocation(XMM1)); 2095 : Location::FpuRegisterLocation(XMM1));
2096 locs->AddTemp(Location::RequiresRegister()); 2096 locs->AddTemp(Location::RequiresRegister());
2097 } 2097 }
2098 locs->set_out(Location::RequiresRegister()); 2098 locs->set_out(0, Location::RequiresRegister());
2099 return locs; 2099 return locs;
2100 } 2100 }
2101 2101
2102 2102
2103 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2103 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2104 Register instance_reg = locs()->in(0).reg(); 2104 Register instance_reg = locs()->in(0).reg();
2105 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2105 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2106 XmmRegister result = locs()->out().fpu_reg(); 2106 XmmRegister result = locs()->out(0).fpu_reg();
2107 Register temp = locs()->temp(0).reg(); 2107 Register temp = locs()->temp(0).reg();
2108 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); 2108 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
2109 const intptr_t cid = field()->UnboxedFieldCid(); 2109 const intptr_t cid = field()->UnboxedFieldCid();
2110 switch (cid) { 2110 switch (cid) {
2111 case kDoubleCid: 2111 case kDoubleCid:
2112 __ Comment("UnboxedDoubleLoadFieldInstr"); 2112 __ Comment("UnboxedDoubleLoadFieldInstr");
2113 __ movsd(result, FieldAddress(temp, Double::value_offset())); 2113 __ movsd(result, FieldAddress(temp, Double::value_offset()));
2114 break; 2114 break;
2115 case kFloat32x4Cid: 2115 case kFloat32x4Cid:
2116 __ Comment("UnboxedFloat32x4LoadFieldInstr"); 2116 __ Comment("UnboxedFloat32x4LoadFieldInstr");
2117 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); 2117 __ movups(result, FieldAddress(temp, Float32x4::value_offset()));
2118 break; 2118 break;
2119 case kFloat64x2Cid: 2119 case kFloat64x2Cid:
2120 __ Comment("UnboxedFloat64x2LoadFieldInstr"); 2120 __ Comment("UnboxedFloat64x2LoadFieldInstr");
2121 __ movups(result, FieldAddress(temp, Float64x2::value_offset())); 2121 __ movups(result, FieldAddress(temp, Float64x2::value_offset()));
2122 break; 2122 break;
2123 default: 2123 default:
2124 UNREACHABLE(); 2124 UNREACHABLE();
2125 } 2125 }
2126 return; 2126 return;
2127 } 2127 }
2128 2128
2129 Label done; 2129 Label done;
2130 Register result = locs()->out().reg(); 2130 Register result = locs()->out(0).reg();
2131 if (IsPotentialUnboxedLoad()) { 2131 if (IsPotentialUnboxedLoad()) {
2132 Register temp = locs()->temp(1).reg(); 2132 Register temp = locs()->temp(1).reg();
2133 XmmRegister value = locs()->temp(0).fpu_reg(); 2133 XmmRegister value = locs()->temp(0).fpu_reg();
2134 2134
2135 2135
2136 Label load_pointer; 2136 Label load_pointer;
2137 Label load_double; 2137 Label load_double;
2138 Label load_float32x4; 2138 Label load_float32x4;
2139 Label load_float64x2; 2139 Label load_float64x2;
2140 2140
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 __ Bind(&done); 2221 __ Bind(&done);
2222 } 2222 }
2223 2223
2224 2224
2225 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2225 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2226 const intptr_t kNumInputs = 1; 2226 const intptr_t kNumInputs = 1;
2227 const intptr_t kNumTemps = 0; 2227 const intptr_t kNumTemps = 0;
2228 LocationSummary* locs = 2228 LocationSummary* locs =
2229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2230 locs->set_in(0, Location::RegisterLocation(EAX)); 2230 locs->set_in(0, Location::RegisterLocation(EAX));
2231 locs->set_out(Location::RegisterLocation(EAX)); 2231 locs->set_out(0, Location::RegisterLocation(EAX));
2232 return locs; 2232 return locs;
2233 } 2233 }
2234 2234
2235 2235
2236 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2236 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2237 Register instantiator_reg = locs()->in(0).reg(); 2237 Register instantiator_reg = locs()->in(0).reg();
2238 Register result_reg = locs()->out().reg(); 2238 Register result_reg = locs()->out(0).reg();
2239 2239
2240 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2240 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2241 // A runtime call to instantiate the type is required. 2241 // A runtime call to instantiate the type is required.
2242 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2242 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2243 __ PushObject(type()); 2243 __ PushObject(type());
2244 __ pushl(instantiator_reg); // Push instantiator type arguments. 2244 __ pushl(instantiator_reg); // Push instantiator type arguments.
2245 compiler->GenerateRuntimeCall(token_pos(), 2245 compiler->GenerateRuntimeCall(token_pos(),
2246 deopt_id(), 2246 deopt_id(),
2247 kInstantiateTypeRuntimeEntry, 2247 kInstantiateTypeRuntimeEntry,
2248 2, 2248 2,
2249 locs()); 2249 locs());
2250 __ Drop(2); // Drop instantiator and uninstantiated type. 2250 __ Drop(2); // Drop instantiator and uninstantiated type.
2251 __ popl(result_reg); // Pop instantiated type. 2251 __ popl(result_reg); // Pop instantiated type.
2252 ASSERT(instantiator_reg == result_reg); 2252 ASSERT(instantiator_reg == result_reg);
2253 } 2253 }
2254 2254
2255 2255
2256 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2256 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2257 bool opt) const { 2257 bool opt) const {
2258 const intptr_t kNumInputs = 1; 2258 const intptr_t kNumInputs = 1;
2259 const intptr_t kNumTemps = 0; 2259 const intptr_t kNumTemps = 0;
2260 LocationSummary* locs = 2260 LocationSummary* locs =
2261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2262 locs->set_in(0, Location::RegisterLocation(EAX)); 2262 locs->set_in(0, Location::RegisterLocation(EAX));
2263 locs->set_out(Location::RegisterLocation(EAX)); 2263 locs->set_out(0, Location::RegisterLocation(EAX));
2264 return locs; 2264 return locs;
2265 } 2265 }
2266 2266
2267 2267
2268 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2268 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2269 FlowGraphCompiler* compiler) { 2269 FlowGraphCompiler* compiler) {
2270 Register instantiator_reg = locs()->in(0).reg(); 2270 Register instantiator_reg = locs()->in(0).reg();
2271 Register result_reg = locs()->out().reg(); 2271 Register result_reg = locs()->out(0).reg();
2272 ASSERT(instantiator_reg == EAX); 2272 ASSERT(instantiator_reg == EAX);
2273 ASSERT(instantiator_reg == result_reg); 2273 ASSERT(instantiator_reg == result_reg);
2274 2274
2275 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2275 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2276 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2276 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2277 !type_arguments().CanShareInstantiatorTypeArguments( 2277 !type_arguments().CanShareInstantiatorTypeArguments(
2278 instantiator_class())); 2278 instantiator_class()));
2279 // If the instantiator is null and if the type argument vector 2279 // If the instantiator is null and if the type argument vector
2280 // instantiated from null becomes a vector of dynamic, then use null as 2280 // instantiated from null becomes a vector of dynamic, then use null as
2281 // the type arguments. 2281 // the type arguments.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2326 2326
2327 2327
2328 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { 2328 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
2329 if (opt) { 2329 if (opt) {
2330 const intptr_t kNumInputs = 0; 2330 const intptr_t kNumInputs = 0;
2331 const intptr_t kNumTemps = 2; 2331 const intptr_t kNumTemps = 2;
2332 LocationSummary* locs = new LocationSummary( 2332 LocationSummary* locs = new LocationSummary(
2333 kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2333 kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2334 locs->set_temp(0, Location::RegisterLocation(ECX)); 2334 locs->set_temp(0, Location::RegisterLocation(ECX));
2335 locs->set_temp(1, Location::RegisterLocation(EBX)); 2335 locs->set_temp(1, Location::RegisterLocation(EBX));
2336 locs->set_out(Location::RegisterLocation(EAX)); 2336 locs->set_out(0, Location::RegisterLocation(EAX));
2337 return locs; 2337 return locs;
2338 } 2338 }
2339 const intptr_t kNumInputs = 0; 2339 const intptr_t kNumInputs = 0;
2340 const intptr_t kNumTemps = 1; 2340 const intptr_t kNumTemps = 1;
2341 LocationSummary* locs = 2341 LocationSummary* locs =
2342 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2342 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2343 locs->set_temp(0, Location::RegisterLocation(EDX)); 2343 locs->set_temp(0, Location::RegisterLocation(EDX));
2344 locs->set_out(Location::RegisterLocation(EAX)); 2344 locs->set_out(0, Location::RegisterLocation(EAX));
2345 return locs; 2345 return locs;
2346 } 2346 }
2347 2347
2348 2348
2349 class AllocateContextSlowPath : public SlowPathCode { 2349 class AllocateContextSlowPath : public SlowPathCode {
2350 public: 2350 public:
2351 explicit AllocateContextSlowPath(AllocateContextInstr* instruction) 2351 explicit AllocateContextSlowPath(AllocateContextInstr* instruction)
2352 : instruction_(instruction) { } 2352 : instruction_(instruction) { }
2353 2353
2354 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2354 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2355 __ Comment("AllocateContextSlowPath"); 2355 __ Comment("AllocateContextSlowPath");
2356 __ Bind(entry_label()); 2356 __ Bind(entry_label());
2357 2357
2358 LocationSummary* locs = instruction_->locs(); 2358 LocationSummary* locs = instruction_->locs();
2359 locs->live_registers()->Remove(locs->out()); 2359 locs->live_registers()->Remove(locs->out(0));
2360 2360
2361 compiler->SaveLiveRegisters(locs); 2361 compiler->SaveLiveRegisters(locs);
2362 2362
2363 __ movl(EDX, Immediate(instruction_->num_context_variables())); 2363 __ movl(EDX, Immediate(instruction_->num_context_variables()));
2364 const ExternalLabel label("alloc_context", 2364 const ExternalLabel label("alloc_context",
2365 StubCode::AllocateContextEntryPoint()); 2365 StubCode::AllocateContextEntryPoint());
2366 compiler->GenerateCall(instruction_->token_pos(), 2366 compiler->GenerateCall(instruction_->token_pos(),
2367 &label, 2367 &label,
2368 PcDescriptors::kOther, 2368 PcDescriptors::kOther,
2369 locs); 2369 locs);
2370 ASSERT(instruction_->locs()->out().reg() == EAX); 2370 ASSERT(instruction_->locs()->out(0).reg() == EAX);
2371 compiler->RestoreLiveRegisters(instruction_->locs()); 2371 compiler->RestoreLiveRegisters(instruction_->locs());
2372 __ jmp(exit_label()); 2372 __ jmp(exit_label());
2373 } 2373 }
2374 2374
2375 private: 2375 private:
2376 AllocateContextInstr* instruction_; 2376 AllocateContextInstr* instruction_;
2377 }; 2377 };
2378 2378
2379 2379
2380 2380
2381 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2381 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2382 if (compiler->is_optimizing()) { 2382 if (compiler->is_optimizing()) {
2383 Register temp0 = locs()->temp(0).reg(); 2383 Register temp0 = locs()->temp(0).reg();
2384 Register temp1 = locs()->temp(1).reg(); 2384 Register temp1 = locs()->temp(1).reg();
2385 Register result = locs()->out().reg(); 2385 Register result = locs()->out(0).reg();
2386 // Try allocate the object. 2386 // Try allocate the object.
2387 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); 2387 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2388 compiler->AddSlowPathCode(slow_path); 2388 compiler->AddSlowPathCode(slow_path);
2389 intptr_t instance_size = Context::InstanceSize(num_context_variables()); 2389 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2390 __ movl(temp1, Immediate(instance_size)); 2390 __ movl(temp1, Immediate(instance_size));
2391 Isolate* isolate = Isolate::Current(); 2391 Isolate* isolate = Isolate::Current();
2392 Heap* heap = isolate->heap(); 2392 Heap* heap = isolate->heap();
2393 __ movl(result, Address::Absolute(heap->TopAddress())); 2393 __ movl(result, Address::Absolute(heap->TopAddress()));
2394 __ addl(temp1, result); 2394 __ addl(temp1, result);
2395 // Check if the allocation fits into the remaining space. 2395 // Check if the allocation fits into the remaining space.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 __ decl(temp0); 2442 __ decl(temp0);
2443 __ movl(Address(temp1, temp0, TIMES_4, 0), raw_null); 2443 __ movl(Address(temp1, temp0, TIMES_4, 0), raw_null);
2444 __ j(NOT_ZERO, &loop, Assembler::kNearJump); 2444 __ j(NOT_ZERO, &loop, Assembler::kNearJump);
2445 } 2445 }
2446 // EAX: new object. 2446 // EAX: new object.
2447 __ Bind(slow_path->exit_label()); 2447 __ Bind(slow_path->exit_label());
2448 return; 2448 return;
2449 } 2449 }
2450 2450
2451 ASSERT(locs()->temp(0).reg() == EDX); 2451 ASSERT(locs()->temp(0).reg() == EDX);
2452 ASSERT(locs()->out().reg() == EAX); 2452 ASSERT(locs()->out(0).reg() == EAX);
2453 2453
2454 __ movl(EDX, Immediate(num_context_variables())); 2454 __ movl(EDX, Immediate(num_context_variables()));
2455 const ExternalLabel label("alloc_context", 2455 const ExternalLabel label("alloc_context",
2456 StubCode::AllocateContextEntryPoint()); 2456 StubCode::AllocateContextEntryPoint());
2457 compiler->GenerateCall(token_pos(), 2457 compiler->GenerateCall(token_pos(),
2458 &label, 2458 &label,
2459 PcDescriptors::kOther, 2459 PcDescriptors::kOther,
2460 locs()); 2460 locs());
2461 } 2461 }
2462 2462
2463 2463
2464 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { 2464 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
2465 const intptr_t kNumInputs = 1; 2465 const intptr_t kNumInputs = 1;
2466 const intptr_t kNumTemps = 0; 2466 const intptr_t kNumTemps = 0;
2467 LocationSummary* locs = 2467 LocationSummary* locs =
2468 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2468 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2469 locs->set_in(0, Location::RegisterLocation(EAX)); 2469 locs->set_in(0, Location::RegisterLocation(EAX));
2470 locs->set_out(Location::RegisterLocation(EAX)); 2470 locs->set_out(0, Location::RegisterLocation(EAX));
2471 return locs; 2471 return locs;
2472 } 2472 }
2473 2473
2474 2474
2475 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2475 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2476 Register context_value = locs()->in(0).reg(); 2476 Register context_value = locs()->in(0).reg();
2477 Register result = locs()->out().reg(); 2477 Register result = locs()->out(0).reg();
2478 2478
2479 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2479 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2480 __ pushl(context_value); 2480 __ pushl(context_value);
2481 compiler->GenerateRuntimeCall(token_pos(), 2481 compiler->GenerateRuntimeCall(token_pos(),
2482 deopt_id(), 2482 deopt_id(),
2483 kCloneContextRuntimeEntry, 2483 kCloneContextRuntimeEntry,
2484 1, 2484 1,
2485 locs()); 2485 locs());
2486 __ popl(result); // Remove argument. 2486 __ popl(result); // Remove argument.
2487 __ popl(result); // Get result (cloned context). 2487 __ popl(result); // Get result (cloned context).
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 } 2588 }
2589 __ Bind(slow_path->exit_label()); 2589 __ Bind(slow_path->exit_label());
2590 } 2590 }
2591 2591
2592 2592
2593 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2593 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2594 BinarySmiOpInstr* shift_left) { 2594 BinarySmiOpInstr* shift_left) {
2595 const bool is_truncating = shift_left->is_truncating(); 2595 const bool is_truncating = shift_left->is_truncating();
2596 const LocationSummary& locs = *shift_left->locs(); 2596 const LocationSummary& locs = *shift_left->locs();
2597 Register left = locs.in(0).reg(); 2597 Register left = locs.in(0).reg();
2598 Register result = locs.out().reg(); 2598 Register result = locs.out(0).reg();
2599 ASSERT(left == result); 2599 ASSERT(left == result);
2600 Label* deopt = shift_left->CanDeoptimize() ? 2600 Label* deopt = shift_left->CanDeoptimize() ?
2601 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; 2601 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL;
2602 if (locs.in(1).IsConstant()) { 2602 if (locs.in(1).IsConstant()) {
2603 const Object& constant = locs.in(1).constant(); 2603 const Object& constant = locs.in(1).constant();
2604 ASSERT(constant.IsSmi()); 2604 ASSERT(constant.IsSmi());
2605 // shll operation masks the count to 5 bits. 2605 // shll operation masks the count to 5 bits.
2606 const intptr_t kCountLimit = 0x1F; 2606 const intptr_t kCountLimit = 0x1F;
2607 const intptr_t value = Smi::Cast(constant).Value(); 2607 const intptr_t value = Smi::Cast(constant).Value();
2608 if (value == 0) { 2608 if (value == 0) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 if (op_kind() == Token::kTRUNCDIV) { 2716 if (op_kind() == Token::kTRUNCDIV) {
2717 const intptr_t kNumTemps = 1; 2717 const intptr_t kNumTemps = 1;
2718 LocationSummary* summary = 2718 LocationSummary* summary =
2719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2720 if (RightIsPowerOfTwoConstant()) { 2720 if (RightIsPowerOfTwoConstant()) {
2721 summary->set_in(0, Location::RequiresRegister()); 2721 summary->set_in(0, Location::RequiresRegister());
2722 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2722 ConstantInstr* right_constant = right()->definition()->AsConstant();
2723 // The programmer only controls one bit, so the constant is safe. 2723 // The programmer only controls one bit, so the constant is safe.
2724 summary->set_in(1, Location::Constant(right_constant->value())); 2724 summary->set_in(1, Location::Constant(right_constant->value()));
2725 summary->set_temp(0, Location::RequiresRegister()); 2725 summary->set_temp(0, Location::RequiresRegister());
2726 summary->set_out(Location::SameAsFirstInput()); 2726 summary->set_out(0, Location::SameAsFirstInput());
2727 } else { 2727 } else {
2728 // Both inputs must be writable because they will be untagged. 2728 // Both inputs must be writable because they will be untagged.
2729 summary->set_in(0, Location::RegisterLocation(EAX)); 2729 summary->set_in(0, Location::RegisterLocation(EAX));
2730 summary->set_in(1, Location::WritableRegister()); 2730 summary->set_in(1, Location::WritableRegister());
2731 summary->set_out(Location::SameAsFirstInput()); 2731 summary->set_out(0, Location::SameAsFirstInput());
2732 // Will be used for sign extension and division. 2732 // Will be used for sign extension and division.
2733 summary->set_temp(0, Location::RegisterLocation(EDX)); 2733 summary->set_temp(0, Location::RegisterLocation(EDX));
2734 } 2734 }
2735 return summary; 2735 return summary;
2736 } else if (op_kind() == Token::kMOD) { 2736 } else if (op_kind() == Token::kMOD) {
2737 const intptr_t kNumTemps = 1; 2737 const intptr_t kNumTemps = 1;
2738 LocationSummary* summary = 2738 LocationSummary* summary =
2739 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2739 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2740 // Both inputs must be writable because they will be untagged. 2740 // Both inputs must be writable because they will be untagged.
2741 summary->set_in(0, Location::RegisterLocation(EDX)); 2741 summary->set_in(0, Location::RegisterLocation(EDX));
2742 summary->set_in(1, Location::WritableRegister()); 2742 summary->set_in(1, Location::WritableRegister());
2743 summary->set_out(Location::SameAsFirstInput()); 2743 summary->set_out(0, Location::SameAsFirstInput());
2744 // Will be used for sign extension and division. 2744 // Will be used for sign extension and division.
2745 summary->set_temp(0, Location::RegisterLocation(EAX)); 2745 summary->set_temp(0, Location::RegisterLocation(EAX));
2746 return summary; 2746 return summary;
2747 } else if (op_kind() == Token::kSHR) { 2747 } else if (op_kind() == Token::kSHR) {
2748 const intptr_t kNumTemps = 0; 2748 const intptr_t kNumTemps = 0;
2749 LocationSummary* summary = 2749 LocationSummary* summary =
2750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2751 summary->set_in(0, Location::RequiresRegister()); 2751 summary->set_in(0, Location::RequiresRegister());
2752 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); 2752 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
2753 summary->set_out(Location::SameAsFirstInput()); 2753 summary->set_out(0, Location::SameAsFirstInput());
2754 return summary; 2754 return summary;
2755 } else if (op_kind() == Token::kSHL) { 2755 } else if (op_kind() == Token::kSHL) {
2756 const intptr_t kNumTemps = 0; 2756 const intptr_t kNumTemps = 0;
2757 LocationSummary* summary = 2757 LocationSummary* summary =
2758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2759 summary->set_in(0, Location::RequiresRegister()); 2759 summary->set_in(0, Location::RequiresRegister());
2760 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); 2760 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
2761 if (!is_truncating()) { 2761 if (!is_truncating()) {
2762 summary->AddTemp(Location::RequiresRegister()); 2762 summary->AddTemp(Location::RequiresRegister());
2763 } 2763 }
2764 summary->set_out(Location::SameAsFirstInput()); 2764 summary->set_out(0, Location::SameAsFirstInput());
2765 return summary; 2765 return summary;
2766 } else { 2766 } else {
2767 const intptr_t kNumTemps = 0; 2767 const intptr_t kNumTemps = 0;
2768 LocationSummary* summary = 2768 LocationSummary* summary =
2769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2770 summary->set_in(0, Location::RequiresRegister()); 2770 summary->set_in(0, Location::RequiresRegister());
2771 ConstantInstr* constant = right()->definition()->AsConstant(); 2771 ConstantInstr* constant = right()->definition()->AsConstant();
2772 if (constant != NULL) { 2772 if (constant != NULL) {
2773 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2773 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2774 } else { 2774 } else {
2775 summary->set_in(1, Location::PrefersRegister()); 2775 summary->set_in(1, Location::PrefersRegister());
2776 } 2776 }
2777 summary->set_out(Location::SameAsFirstInput()); 2777 summary->set_out(0, Location::SameAsFirstInput());
2778 return summary; 2778 return summary;
2779 } 2779 }
2780 } 2780 }
2781 2781
2782 2782
2783 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2783 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2784 if (op_kind() == Token::kSHL) { 2784 if (op_kind() == Token::kSHL) {
2785 EmitSmiShiftLeft(compiler, this); 2785 EmitSmiShiftLeft(compiler, this);
2786 return; 2786 return;
2787 } 2787 }
2788 2788
2789 ASSERT(!is_truncating()); 2789 ASSERT(!is_truncating());
2790 Register left = locs()->in(0).reg(); 2790 Register left = locs()->in(0).reg();
2791 Register result = locs()->out().reg(); 2791 Register result = locs()->out(0).reg();
2792 ASSERT(left == result); 2792 ASSERT(left == result);
2793 Label* deopt = NULL; 2793 Label* deopt = NULL;
2794 if (CanDeoptimize()) { 2794 if (CanDeoptimize()) {
2795 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 2795 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
2796 } 2796 }
2797 2797
2798 if (locs()->in(1).IsConstant()) { 2798 if (locs()->in(1).IsConstant()) {
2799 const Object& constant = locs()->in(1).constant(); 2799 const Object& constant = locs()->in(1).constant();
2800 ASSERT(constant.IsSmi()); 2800 ASSERT(constant.IsSmi());
2801 const int32_t imm = 2801 const int32_t imm =
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 3121
3122 3122
3123 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 3123 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
3124 const intptr_t kNumInputs = 1; 3124 const intptr_t kNumInputs = 1;
3125 const intptr_t kNumTemps = 0; 3125 const intptr_t kNumTemps = 0;
3126 LocationSummary* summary = 3126 LocationSummary* summary =
3127 new LocationSummary(kNumInputs, 3127 new LocationSummary(kNumInputs,
3128 kNumTemps, 3128 kNumTemps,
3129 LocationSummary::kCallOnSlowPath); 3129 LocationSummary::kCallOnSlowPath);
3130 summary->set_in(0, Location::RequiresFpuRegister()); 3130 summary->set_in(0, Location::RequiresFpuRegister());
3131 summary->set_out(Location::RequiresRegister()); 3131 summary->set_out(0, Location::RequiresRegister());
3132 return summary; 3132 return summary;
3133 } 3133 }
3134 3134
3135 3135
3136 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3136 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3137 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 3137 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
3138 compiler->AddSlowPathCode(slow_path); 3138 compiler->AddSlowPathCode(slow_path);
3139 3139
3140 Register out_reg = locs()->out().reg(); 3140 Register out_reg = locs()->out(0).reg();
3141 XmmRegister value = locs()->in(0).fpu_reg(); 3141 XmmRegister value = locs()->in(0).fpu_reg();
3142 3142
3143 __ TryAllocate(compiler->double_class(), 3143 __ TryAllocate(compiler->double_class(),
3144 slow_path->entry_label(), 3144 slow_path->entry_label(),
3145 Assembler::kFarJump, 3145 Assembler::kFarJump,
3146 out_reg, 3146 out_reg,
3147 kNoRegister); 3147 kNoRegister);
3148 __ Bind(slow_path->exit_label()); 3148 __ Bind(slow_path->exit_label());
3149 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 3149 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
3150 } 3150 }
3151 3151
3152 3152
3153 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { 3153 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
3154 const intptr_t kNumInputs = 1; 3154 const intptr_t kNumInputs = 1;
3155 const intptr_t value_cid = value()->Type()->ToCid(); 3155 const intptr_t value_cid = value()->Type()->ToCid();
3156 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); 3156 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
3157 const bool needs_writable_input = (value_cid == kSmiCid); 3157 const bool needs_writable_input = (value_cid == kSmiCid);
3158 const intptr_t kNumTemps = needs_temp ? 1 : 0; 3158 const intptr_t kNumTemps = needs_temp ? 1 : 0;
3159 LocationSummary* summary = 3159 LocationSummary* summary =
3160 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3160 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3161 summary->set_in(0, needs_writable_input 3161 summary->set_in(0, needs_writable_input
3162 ? Location::WritableRegister() 3162 ? Location::WritableRegister()
3163 : Location::RequiresRegister()); 3163 : Location::RequiresRegister());
3164 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); 3164 if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
3165 summary->set_out(Location::RequiresFpuRegister()); 3165 summary->set_out(0, Location::RequiresFpuRegister());
3166 return summary; 3166 return summary;
3167 } 3167 }
3168 3168
3169 3169
3170 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3170 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3171 const intptr_t value_cid = value()->Type()->ToCid(); 3171 const intptr_t value_cid = value()->Type()->ToCid();
3172 const Register value = locs()->in(0).reg(); 3172 const Register value = locs()->in(0).reg();
3173 const XmmRegister result = locs()->out().fpu_reg(); 3173 const XmmRegister result = locs()->out(0).fpu_reg();
3174 3174
3175 if (value_cid == kDoubleCid) { 3175 if (value_cid == kDoubleCid) {
3176 __ movsd(result, FieldAddress(value, Double::value_offset())); 3176 __ movsd(result, FieldAddress(value, Double::value_offset()));
3177 } else if (value_cid == kSmiCid) { 3177 } else if (value_cid == kSmiCid) {
3178 __ SmiUntag(value); // Untag input before conversion. 3178 __ SmiUntag(value); // Untag input before conversion.
3179 __ cvtsi2sd(result, value); 3179 __ cvtsi2sd(result, value);
3180 } else { 3180 } else {
3181 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 3181 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
3182 Register temp = locs()->temp(0).reg(); 3182 Register temp = locs()->temp(0).reg();
3183 Label is_smi, done; 3183 Label is_smi, done;
(...skipping 13 matching lines...) Expand all
3197 3197
3198 3198
3199 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3199 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3200 const intptr_t kNumInputs = 1; 3200 const intptr_t kNumInputs = 1;
3201 const intptr_t kNumTemps = 0; 3201 const intptr_t kNumTemps = 0;
3202 LocationSummary* summary = 3202 LocationSummary* summary =
3203 new LocationSummary(kNumInputs, 3203 new LocationSummary(kNumInputs,
3204 kNumTemps, 3204 kNumTemps,
3205 LocationSummary::kCallOnSlowPath); 3205 LocationSummary::kCallOnSlowPath);
3206 summary->set_in(0, Location::RequiresFpuRegister()); 3206 summary->set_in(0, Location::RequiresFpuRegister());
3207 summary->set_out(Location::RequiresRegister()); 3207 summary->set_out(0, Location::RequiresRegister());
3208 return summary; 3208 return summary;
3209 } 3209 }
3210 3210
3211 3211
3212 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3212 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3213 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); 3213 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
3214 compiler->AddSlowPathCode(slow_path); 3214 compiler->AddSlowPathCode(slow_path);
3215 3215
3216 Register out_reg = locs()->out().reg(); 3216 Register out_reg = locs()->out(0).reg();
3217 XmmRegister value = locs()->in(0).fpu_reg(); 3217 XmmRegister value = locs()->in(0).fpu_reg();
3218 3218
3219 __ TryAllocate(compiler->float32x4_class(), 3219 __ TryAllocate(compiler->float32x4_class(),
3220 slow_path->entry_label(), 3220 slow_path->entry_label(),
3221 Assembler::kFarJump, 3221 Assembler::kFarJump,
3222 out_reg, 3222 out_reg,
3223 kNoRegister); 3223 kNoRegister);
3224 __ Bind(slow_path->exit_label()); 3224 __ Bind(slow_path->exit_label());
3225 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); 3225 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
3226 } 3226 }
3227 3227
3228 3228
3229 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3229 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3230 const intptr_t value_cid = value()->Type()->ToCid(); 3230 const intptr_t value_cid = value()->Type()->ToCid();
3231 const intptr_t kNumInputs = 1; 3231 const intptr_t kNumInputs = 1;
3232 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; 3232 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
3233 LocationSummary* summary = 3233 LocationSummary* summary =
3234 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3234 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3235 summary->set_in(0, Location::RequiresRegister()); 3235 summary->set_in(0, Location::RequiresRegister());
3236 if (kNumTemps > 0) { 3236 if (kNumTemps > 0) {
3237 ASSERT(kNumTemps == 1); 3237 ASSERT(kNumTemps == 1);
3238 summary->set_temp(0, Location::RequiresRegister()); 3238 summary->set_temp(0, Location::RequiresRegister());
3239 } 3239 }
3240 summary->set_out(Location::RequiresFpuRegister()); 3240 summary->set_out(0, Location::RequiresFpuRegister());
3241 return summary; 3241 return summary;
3242 } 3242 }
3243 3243
3244 3244
3245 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3245 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3246 const intptr_t value_cid = value()->Type()->ToCid(); 3246 const intptr_t value_cid = value()->Type()->ToCid();
3247 const Register value = locs()->in(0).reg(); 3247 const Register value = locs()->in(0).reg();
3248 const XmmRegister result = locs()->out().fpu_reg(); 3248 const XmmRegister result = locs()->out(0).fpu_reg();
3249 3249
3250 if (value_cid != kFloat32x4Cid) { 3250 if (value_cid != kFloat32x4Cid) {
3251 const Register temp = locs()->temp(0).reg(); 3251 const Register temp = locs()->temp(0).reg();
3252 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3252 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3253 __ testl(value, Immediate(kSmiTagMask)); 3253 __ testl(value, Immediate(kSmiTagMask));
3254 __ j(ZERO, deopt); 3254 __ j(ZERO, deopt);
3255 __ CompareClassId(value, kFloat32x4Cid, temp); 3255 __ CompareClassId(value, kFloat32x4Cid, temp);
3256 __ j(NOT_EQUAL, deopt); 3256 __ j(NOT_EQUAL, deopt);
3257 } 3257 }
3258 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3258 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3259 } 3259 }
3260 3260
3261 3261
3262 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3262 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3263 const intptr_t kNumInputs = 1; 3263 const intptr_t kNumInputs = 1;
3264 const intptr_t kNumTemps = 0; 3264 const intptr_t kNumTemps = 0;
3265 LocationSummary* summary = 3265 LocationSummary* summary =
3266 new LocationSummary(kNumInputs, 3266 new LocationSummary(kNumInputs,
3267 kNumTemps, 3267 kNumTemps,
3268 LocationSummary::kCallOnSlowPath); 3268 LocationSummary::kCallOnSlowPath);
3269 summary->set_in(0, Location::RequiresFpuRegister()); 3269 summary->set_in(0, Location::RequiresFpuRegister());
3270 summary->set_out(Location::RequiresRegister()); 3270 summary->set_out(0, Location::RequiresRegister());
3271 return summary; 3271 return summary;
3272 } 3272 }
3273 3273
3274 3274
3275 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3275 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3276 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); 3276 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3277 compiler->AddSlowPathCode(slow_path); 3277 compiler->AddSlowPathCode(slow_path);
3278 3278
3279 Register out_reg = locs()->out().reg(); 3279 Register out_reg = locs()->out(0).reg();
3280 XmmRegister value = locs()->in(0).fpu_reg(); 3280 XmmRegister value = locs()->in(0).fpu_reg();
3281 3281
3282 __ TryAllocate(compiler->float64x2_class(), 3282 __ TryAllocate(compiler->float64x2_class(),
3283 slow_path->entry_label(), 3283 slow_path->entry_label(),
3284 Assembler::kFarJump, 3284 Assembler::kFarJump,
3285 out_reg, 3285 out_reg,
3286 kNoRegister); 3286 kNoRegister);
3287 __ Bind(slow_path->exit_label()); 3287 __ Bind(slow_path->exit_label());
3288 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); 3288 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
3289 } 3289 }
3290 3290
3291 3291
3292 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3292 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3293 const intptr_t value_cid = value()->Type()->ToCid(); 3293 const intptr_t value_cid = value()->Type()->ToCid();
3294 const intptr_t kNumInputs = 1; 3294 const intptr_t kNumInputs = 1;
3295 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; 3295 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3296 LocationSummary* summary = 3296 LocationSummary* summary =
3297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3298 summary->set_in(0, Location::RequiresRegister()); 3298 summary->set_in(0, Location::RequiresRegister());
3299 if (kNumTemps > 0) { 3299 if (kNumTemps > 0) {
3300 ASSERT(kNumTemps == 1); 3300 ASSERT(kNumTemps == 1);
3301 summary->set_temp(0, Location::RequiresRegister()); 3301 summary->set_temp(0, Location::RequiresRegister());
3302 } 3302 }
3303 summary->set_out(Location::RequiresFpuRegister()); 3303 summary->set_out(0, Location::RequiresFpuRegister());
3304 return summary; 3304 return summary;
3305 } 3305 }
3306 3306
3307 3307
3308 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3308 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3309 const intptr_t value_cid = value()->Type()->ToCid(); 3309 const intptr_t value_cid = value()->Type()->ToCid();
3310 const Register value = locs()->in(0).reg(); 3310 const Register value = locs()->in(0).reg();
3311 const XmmRegister result = locs()->out().fpu_reg(); 3311 const XmmRegister result = locs()->out(0).fpu_reg();
3312 3312
3313 if (value_cid != kFloat64x2Cid) { 3313 if (value_cid != kFloat64x2Cid) {
3314 const Register temp = locs()->temp(0).reg(); 3314 const Register temp = locs()->temp(0).reg();
3315 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3315 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3316 __ testl(value, Immediate(kSmiTagMask)); 3316 __ testl(value, Immediate(kSmiTagMask));
3317 __ j(ZERO, deopt); 3317 __ j(ZERO, deopt);
3318 __ CompareClassId(value, kFloat64x2Cid, temp); 3318 __ CompareClassId(value, kFloat64x2Cid, temp);
3319 __ j(NOT_EQUAL, deopt); 3319 __ j(NOT_EQUAL, deopt);
3320 } 3320 }
3321 __ movups(result, FieldAddress(value, Float64x2::value_offset())); 3321 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3322 } 3322 }
3323 3323
3324 3324
3325 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3325 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3326 const intptr_t kNumInputs = 1; 3326 const intptr_t kNumInputs = 1;
3327 const intptr_t kNumTemps = 0; 3327 const intptr_t kNumTemps = 0;
3328 LocationSummary* summary = 3328 LocationSummary* summary =
3329 new LocationSummary(kNumInputs, 3329 new LocationSummary(kNumInputs,
3330 kNumTemps, 3330 kNumTemps,
3331 LocationSummary::kCallOnSlowPath); 3331 LocationSummary::kCallOnSlowPath);
3332 summary->set_in(0, Location::RequiresFpuRegister()); 3332 summary->set_in(0, Location::RequiresFpuRegister());
3333 summary->set_out(Location::RequiresRegister()); 3333 summary->set_out(0, Location::RequiresRegister());
3334 return summary; 3334 return summary;
3335 } 3335 }
3336 3336
3337 3337
3338 class BoxInt32x4SlowPath : public SlowPathCode { 3338 class BoxInt32x4SlowPath : public SlowPathCode {
3339 public: 3339 public:
3340 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) 3340 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction)
3341 : instruction_(instruction) { } 3341 : instruction_(instruction) { }
3342 3342
3343 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 3343 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3344 __ Comment("BoxInt32x4SlowPath"); 3344 __ Comment("BoxInt32x4SlowPath");
3345 __ Bind(entry_label()); 3345 __ Bind(entry_label());
3346 const Class& int32x4_class = compiler->int32x4_class(); 3346 const Class& int32x4_class = compiler->int32x4_class();
3347 const Code& stub = 3347 const Code& stub =
3348 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); 3348 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class));
3349 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); 3349 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint());
3350 3350
3351 LocationSummary* locs = instruction_->locs(); 3351 LocationSummary* locs = instruction_->locs();
3352 locs->live_registers()->Remove(locs->out()); 3352 locs->live_registers()->Remove(locs->out(0));
3353 3353
3354 compiler->SaveLiveRegisters(locs); 3354 compiler->SaveLiveRegisters(locs);
3355 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 3355 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
3356 &label, 3356 &label,
3357 PcDescriptors::kOther, 3357 PcDescriptors::kOther,
3358 locs); 3358 locs);
3359 __ MoveRegister(locs->out().reg(), EAX); 3359 __ MoveRegister(locs->out(0).reg(), EAX);
3360 compiler->RestoreLiveRegisters(locs); 3360 compiler->RestoreLiveRegisters(locs);
3361 3361
3362 __ jmp(exit_label()); 3362 __ jmp(exit_label());
3363 } 3363 }
3364 3364
3365 private: 3365 private:
3366 BoxInt32x4Instr* instruction_; 3366 BoxInt32x4Instr* instruction_;
3367 }; 3367 };
3368 3368
3369 3369
3370 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3370 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3371 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); 3371 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this);
3372 compiler->AddSlowPathCode(slow_path); 3372 compiler->AddSlowPathCode(slow_path);
3373 3373
3374 Register out_reg = locs()->out().reg(); 3374 Register out_reg = locs()->out(0).reg();
3375 XmmRegister value = locs()->in(0).fpu_reg(); 3375 XmmRegister value = locs()->in(0).fpu_reg();
3376 3376
3377 __ TryAllocate(compiler->int32x4_class(), 3377 __ TryAllocate(compiler->int32x4_class(),
3378 slow_path->entry_label(), 3378 slow_path->entry_label(),
3379 Assembler::kFarJump, 3379 Assembler::kFarJump,
3380 out_reg, 3380 out_reg,
3381 kNoRegister); 3381 kNoRegister);
3382 __ Bind(slow_path->exit_label()); 3382 __ Bind(slow_path->exit_label());
3383 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); 3383 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
3384 } 3384 }
3385 3385
3386 3386
3387 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { 3387 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const {
3388 const intptr_t value_cid = value()->Type()->ToCid(); 3388 const intptr_t value_cid = value()->Type()->ToCid();
3389 const intptr_t kNumInputs = 1; 3389 const intptr_t kNumInputs = 1;
3390 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; 3390 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1;
3391 LocationSummary* summary = 3391 LocationSummary* summary =
3392 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3392 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3393 summary->set_in(0, Location::RequiresRegister()); 3393 summary->set_in(0, Location::RequiresRegister());
3394 if (kNumTemps > 0) { 3394 if (kNumTemps > 0) {
3395 ASSERT(kNumTemps == 1); 3395 ASSERT(kNumTemps == 1);
3396 summary->set_temp(0, Location::RequiresRegister()); 3396 summary->set_temp(0, Location::RequiresRegister());
3397 } 3397 }
3398 summary->set_out(Location::RequiresFpuRegister()); 3398 summary->set_out(0, Location::RequiresFpuRegister());
3399 return summary; 3399 return summary;
3400 } 3400 }
3401 3401
3402 3402
3403 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3403 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3404 const intptr_t value_cid = value()->Type()->ToCid(); 3404 const intptr_t value_cid = value()->Type()->ToCid();
3405 const Register value = locs()->in(0).reg(); 3405 const Register value = locs()->in(0).reg();
3406 const XmmRegister result = locs()->out().fpu_reg(); 3406 const XmmRegister result = locs()->out(0).fpu_reg();
3407 3407
3408 if (value_cid != kInt32x4Cid) { 3408 if (value_cid != kInt32x4Cid) {
3409 const Register temp = locs()->temp(0).reg(); 3409 const Register temp = locs()->temp(0).reg();
3410 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3410 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3411 __ testl(value, Immediate(kSmiTagMask)); 3411 __ testl(value, Immediate(kSmiTagMask));
3412 __ j(ZERO, deopt); 3412 __ j(ZERO, deopt);
3413 __ CompareClassId(value, kInt32x4Cid, temp); 3413 __ CompareClassId(value, kInt32x4Cid, temp);
3414 __ j(NOT_EQUAL, deopt); 3414 __ j(NOT_EQUAL, deopt);
3415 } 3415 }
3416 __ movups(result, FieldAddress(value, Int32x4::value_offset())); 3416 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
3417 } 3417 }
3418 3418
3419 3419
3420 3420
3421 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 3421 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3422 const intptr_t kNumInputs = 2; 3422 const intptr_t kNumInputs = 2;
3423 const intptr_t kNumTemps = 0; 3423 const intptr_t kNumTemps = 0;
3424 LocationSummary* summary = 3424 LocationSummary* summary =
3425 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3425 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3426 summary->set_in(0, Location::RequiresFpuRegister()); 3426 summary->set_in(0, Location::RequiresFpuRegister());
3427 summary->set_in(1, Location::RequiresFpuRegister()); 3427 summary->set_in(1, Location::RequiresFpuRegister());
3428 summary->set_out(Location::SameAsFirstInput()); 3428 summary->set_out(0, Location::SameAsFirstInput());
3429 return summary; 3429 return summary;
3430 } 3430 }
3431 3431
3432 3432
3433 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3433 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3434 XmmRegister left = locs()->in(0).fpu_reg(); 3434 XmmRegister left = locs()->in(0).fpu_reg();
3435 XmmRegister right = locs()->in(1).fpu_reg(); 3435 XmmRegister right = locs()->in(1).fpu_reg();
3436 3436
3437 ASSERT(locs()->out().fpu_reg() == left); 3437 ASSERT(locs()->out(0).fpu_reg() == left);
3438 3438
3439 switch (op_kind()) { 3439 switch (op_kind()) {
3440 case Token::kADD: __ addsd(left, right); break; 3440 case Token::kADD: __ addsd(left, right); break;
3441 case Token::kSUB: __ subsd(left, right); break; 3441 case Token::kSUB: __ subsd(left, right); break;
3442 case Token::kMUL: __ mulsd(left, right); break; 3442 case Token::kMUL: __ mulsd(left, right); break;
3443 case Token::kDIV: __ divsd(left, right); break; 3443 case Token::kDIV: __ divsd(left, right); break;
3444 default: UNREACHABLE(); 3444 default: UNREACHABLE();
3445 } 3445 }
3446 } 3446 }
3447 3447
3448 3448
3449 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { 3449 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
3450 const intptr_t kNumInputs = 2; 3450 const intptr_t kNumInputs = 2;
3451 const intptr_t kNumTemps = 0; 3451 const intptr_t kNumTemps = 0;
3452 LocationSummary* summary = 3452 LocationSummary* summary =
3453 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3453 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3454 summary->set_in(0, Location::RequiresFpuRegister()); 3454 summary->set_in(0, Location::RequiresFpuRegister());
3455 summary->set_in(1, Location::RequiresFpuRegister()); 3455 summary->set_in(1, Location::RequiresFpuRegister());
3456 summary->set_out(Location::SameAsFirstInput()); 3456 summary->set_out(0, Location::SameAsFirstInput());
3457 return summary; 3457 return summary;
3458 } 3458 }
3459 3459
3460 3460
3461 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3461 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3462 XmmRegister left = locs()->in(0).fpu_reg(); 3462 XmmRegister left = locs()->in(0).fpu_reg();
3463 XmmRegister right = locs()->in(1).fpu_reg(); 3463 XmmRegister right = locs()->in(1).fpu_reg();
3464 3464
3465 ASSERT(locs()->out().fpu_reg() == left); 3465 ASSERT(locs()->out(0).fpu_reg() == left);
3466 3466
3467 switch (op_kind()) { 3467 switch (op_kind()) {
3468 case Token::kADD: __ addps(left, right); break; 3468 case Token::kADD: __ addps(left, right); break;
3469 case Token::kSUB: __ subps(left, right); break; 3469 case Token::kSUB: __ subps(left, right); break;
3470 case Token::kMUL: __ mulps(left, right); break; 3470 case Token::kMUL: __ mulps(left, right); break;
3471 case Token::kDIV: __ divps(left, right); break; 3471 case Token::kDIV: __ divps(left, right); break;
3472 default: UNREACHABLE(); 3472 default: UNREACHABLE();
3473 } 3473 }
3474 } 3474 }
3475 3475
3476 3476
3477 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { 3477 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const {
3478 const intptr_t kNumInputs = 2; 3478 const intptr_t kNumInputs = 2;
3479 const intptr_t kNumTemps = 0; 3479 const intptr_t kNumTemps = 0;
3480 LocationSummary* summary = 3480 LocationSummary* summary =
3481 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3481 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3482 summary->set_in(0, Location::RequiresFpuRegister()); 3482 summary->set_in(0, Location::RequiresFpuRegister());
3483 summary->set_in(1, Location::RequiresFpuRegister()); 3483 summary->set_in(1, Location::RequiresFpuRegister());
3484 summary->set_out(Location::SameAsFirstInput()); 3484 summary->set_out(0, Location::SameAsFirstInput());
3485 return summary; 3485 return summary;
3486 } 3486 }
3487 3487
3488 3488
3489 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3489 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3490 XmmRegister left = locs()->in(0).fpu_reg(); 3490 XmmRegister left = locs()->in(0).fpu_reg();
3491 XmmRegister right = locs()->in(1).fpu_reg(); 3491 XmmRegister right = locs()->in(1).fpu_reg();
3492 3492
3493 ASSERT(locs()->out().fpu_reg() == left); 3493 ASSERT(locs()->out(0).fpu_reg() == left);
3494 3494
3495 switch (op_kind()) { 3495 switch (op_kind()) {
3496 case Token::kADD: __ addpd(left, right); break; 3496 case Token::kADD: __ addpd(left, right); break;
3497 case Token::kSUB: __ subpd(left, right); break; 3497 case Token::kSUB: __ subpd(left, right); break;
3498 case Token::kMUL: __ mulpd(left, right); break; 3498 case Token::kMUL: __ mulpd(left, right); break;
3499 case Token::kDIV: __ divpd(left, right); break; 3499 case Token::kDIV: __ divpd(left, right); break;
3500 default: UNREACHABLE(); 3500 default: UNREACHABLE();
3501 } 3501 }
3502 } 3502 }
3503 3503
3504 3504
3505 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { 3505 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const {
3506 const intptr_t kNumInputs = 1; 3506 const intptr_t kNumInputs = 1;
3507 const intptr_t kNumTemps = 0; 3507 const intptr_t kNumTemps = 0;
3508 LocationSummary* summary = 3508 LocationSummary* summary =
3509 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3509 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3510 summary->set_in(0, Location::RequiresFpuRegister()); 3510 summary->set_in(0, Location::RequiresFpuRegister());
3511 summary->set_out(Location::SameAsFirstInput()); 3511 summary->set_out(0, Location::SameAsFirstInput());
3512 return summary; 3512 return summary;
3513 } 3513 }
3514 3514
3515 3515
3516 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3516 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3517 XmmRegister value = locs()->in(0).fpu_reg(); 3517 XmmRegister value = locs()->in(0).fpu_reg();
3518 3518
3519 ASSERT(locs()->out().fpu_reg() == value); 3519 ASSERT(locs()->out(0).fpu_reg() == value);
3520 3520
3521 switch (op_kind()) { 3521 switch (op_kind()) {
3522 case MethodRecognizer::kFloat32x4ShuffleX: 3522 case MethodRecognizer::kFloat32x4ShuffleX:
3523 // Shuffle not necessary. 3523 // Shuffle not necessary.
3524 __ cvtss2sd(value, value); 3524 __ cvtss2sd(value, value);
3525 break; 3525 break;
3526 case MethodRecognizer::kFloat32x4ShuffleY: 3526 case MethodRecognizer::kFloat32x4ShuffleY:
3527 __ shufps(value, value, Immediate(0x55)); 3527 __ shufps(value, value, Immediate(0x55));
3528 __ cvtss2sd(value, value); 3528 __ cvtss2sd(value, value);
3529 break; 3529 break;
(...skipping 14 matching lines...) Expand all
3544 } 3544 }
3545 3545
3546 3546
3547 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { 3547 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const {
3548 const intptr_t kNumInputs = 2; 3548 const intptr_t kNumInputs = 2;
3549 const intptr_t kNumTemps = 0; 3549 const intptr_t kNumTemps = 0;
3550 LocationSummary* summary = 3550 LocationSummary* summary =
3551 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3551 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3552 summary->set_in(0, Location::RequiresFpuRegister()); 3552 summary->set_in(0, Location::RequiresFpuRegister());
3553 summary->set_in(1, Location::RequiresFpuRegister()); 3553 summary->set_in(1, Location::RequiresFpuRegister());
3554 summary->set_out(Location::SameAsFirstInput()); 3554 summary->set_out(0, Location::SameAsFirstInput());
3555 return summary; 3555 return summary;
3556 } 3556 }
3557 3557
3558 3558
3559 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3559 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3560 XmmRegister left = locs()->in(0).fpu_reg(); 3560 XmmRegister left = locs()->in(0).fpu_reg();
3561 XmmRegister right = locs()->in(1).fpu_reg(); 3561 XmmRegister right = locs()->in(1).fpu_reg();
3562 3562
3563 ASSERT(locs()->out().fpu_reg() == left); 3563 ASSERT(locs()->out(0).fpu_reg() == left);
3564 switch (op_kind()) { 3564 switch (op_kind()) {
3565 case MethodRecognizer::kFloat32x4ShuffleMix: 3565 case MethodRecognizer::kFloat32x4ShuffleMix:
3566 case MethodRecognizer::kInt32x4ShuffleMix: 3566 case MethodRecognizer::kInt32x4ShuffleMix:
3567 __ shufps(left, right, Immediate(mask_)); 3567 __ shufps(left, right, Immediate(mask_));
3568 break; 3568 break;
3569 default: UNREACHABLE(); 3569 default: UNREACHABLE();
3570 } 3570 }
3571 } 3571 }
3572 3572
3573 3573
3574 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { 3574 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const {
3575 const intptr_t kNumInputs = 1; 3575 const intptr_t kNumInputs = 1;
3576 const intptr_t kNumTemps = 0; 3576 const intptr_t kNumTemps = 0;
3577 LocationSummary* summary = 3577 LocationSummary* summary =
3578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3579 summary->set_in(0, Location::RequiresFpuRegister()); 3579 summary->set_in(0, Location::RequiresFpuRegister());
3580 summary->set_out(Location::RequiresRegister()); 3580 summary->set_out(0, Location::RequiresRegister());
3581 return summary; 3581 return summary;
3582 } 3582 }
3583 3583
3584 3584
3585 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3585 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3586 XmmRegister value = locs()->in(0).fpu_reg(); 3586 XmmRegister value = locs()->in(0).fpu_reg();
3587 Register out = locs()->out().reg(); 3587 Register out = locs()->out(0).reg();
3588 3588
3589 __ movmskps(out, value); 3589 __ movmskps(out, value);
3590 __ SmiTag(out); 3590 __ SmiTag(out);
3591 } 3591 }
3592 3592
3593 3593
3594 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( 3594 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
3595 bool opt) const { 3595 bool opt) const {
3596 const intptr_t kNumInputs = 4; 3596 const intptr_t kNumInputs = 4;
3597 const intptr_t kNumTemps = 0; 3597 const intptr_t kNumTemps = 0;
3598 LocationSummary* summary = 3598 LocationSummary* summary =
3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3600 summary->set_in(0, Location::RequiresFpuRegister()); 3600 summary->set_in(0, Location::RequiresFpuRegister());
3601 summary->set_in(1, Location::RequiresFpuRegister()); 3601 summary->set_in(1, Location::RequiresFpuRegister());
3602 summary->set_in(2, Location::RequiresFpuRegister()); 3602 summary->set_in(2, Location::RequiresFpuRegister());
3603 summary->set_in(3, Location::RequiresFpuRegister()); 3603 summary->set_in(3, Location::RequiresFpuRegister());
3604 summary->set_out(Location::SameAsFirstInput()); 3604 summary->set_out(0, Location::SameAsFirstInput());
3605 return summary; 3605 return summary;
3606 } 3606 }
3607 3607
3608 3608
3609 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3609 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3610 XmmRegister v0 = locs()->in(0).fpu_reg(); 3610 XmmRegister v0 = locs()->in(0).fpu_reg();
3611 XmmRegister v1 = locs()->in(1).fpu_reg(); 3611 XmmRegister v1 = locs()->in(1).fpu_reg();
3612 XmmRegister v2 = locs()->in(2).fpu_reg(); 3612 XmmRegister v2 = locs()->in(2).fpu_reg();
3613 XmmRegister v3 = locs()->in(3).fpu_reg(); 3613 XmmRegister v3 = locs()->in(3).fpu_reg();
3614 ASSERT(v0 == locs()->out().fpu_reg()); 3614 ASSERT(v0 == locs()->out(0).fpu_reg());
3615 __ subl(ESP, Immediate(16)); 3615 __ subl(ESP, Immediate(16));
3616 __ cvtsd2ss(v0, v0); 3616 __ cvtsd2ss(v0, v0);
3617 __ movss(Address(ESP, 0), v0); 3617 __ movss(Address(ESP, 0), v0);
3618 __ movsd(v0, v1); 3618 __ movsd(v0, v1);
3619 __ cvtsd2ss(v0, v0); 3619 __ cvtsd2ss(v0, v0);
3620 __ movss(Address(ESP, 4), v0); 3620 __ movss(Address(ESP, 4), v0);
3621 __ movsd(v0, v2); 3621 __ movsd(v0, v2);
3622 __ cvtsd2ss(v0, v0); 3622 __ cvtsd2ss(v0, v0);
3623 __ movss(Address(ESP, 8), v0); 3623 __ movss(Address(ESP, 8), v0);
3624 __ movsd(v0, v3); 3624 __ movsd(v0, v3);
3625 __ cvtsd2ss(v0, v0); 3625 __ cvtsd2ss(v0, v0);
3626 __ movss(Address(ESP, 12), v0); 3626 __ movss(Address(ESP, 12), v0);
3627 __ movups(v0, Address(ESP, 0)); 3627 __ movups(v0, Address(ESP, 0));
3628 __ addl(ESP, Immediate(16)); 3628 __ addl(ESP, Immediate(16));
3629 } 3629 }
3630 3630
3631 3631
3632 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { 3632 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const {
3633 const intptr_t kNumInputs = 0; 3633 const intptr_t kNumInputs = 0;
3634 const intptr_t kNumTemps = 0; 3634 const intptr_t kNumTemps = 0;
3635 LocationSummary* summary = 3635 LocationSummary* summary =
3636 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3636 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3637 summary->set_out(Location::RequiresFpuRegister()); 3637 summary->set_out(0, Location::RequiresFpuRegister());
3638 return summary; 3638 return summary;
3639 } 3639 }
3640 3640
3641 3641
3642 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3642 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3643 XmmRegister value = locs()->out().fpu_reg(); 3643 XmmRegister value = locs()->out(0).fpu_reg();
3644 __ xorps(value, value); 3644 __ xorps(value, value);
3645 } 3645 }
3646 3646
3647 3647
3648 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { 3648 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const {
3649 const intptr_t kNumInputs = 1; 3649 const intptr_t kNumInputs = 1;
3650 const intptr_t kNumTemps = 0; 3650 const intptr_t kNumTemps = 0;
3651 LocationSummary* summary = 3651 LocationSummary* summary =
3652 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3652 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3653 summary->set_in(0, Location::RequiresFpuRegister()); 3653 summary->set_in(0, Location::RequiresFpuRegister());
3654 summary->set_out(Location::SameAsFirstInput()); 3654 summary->set_out(0, Location::SameAsFirstInput());
3655 return summary; 3655 return summary;
3656 } 3656 }
3657 3657
3658 3658
3659 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3659 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3660 XmmRegister value = locs()->out().fpu_reg(); 3660 XmmRegister value = locs()->out(0).fpu_reg();
3661 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); 3661 ASSERT(locs()->in(0).fpu_reg() == locs()->out(0).fpu_reg());
3662 // Convert to Float32. 3662 // Convert to Float32.
3663 __ cvtsd2ss(value, value); 3663 __ cvtsd2ss(value, value);
3664 // Splat across all lanes. 3664 // Splat across all lanes.
3665 __ shufps(value, value, Immediate(0x00)); 3665 __ shufps(value, value, Immediate(0x00));
3666 } 3666 }
3667 3667
3668 3668
3669 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { 3669 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const {
3670 const intptr_t kNumInputs = 2; 3670 const intptr_t kNumInputs = 2;
3671 const intptr_t kNumTemps = 0; 3671 const intptr_t kNumTemps = 0;
3672 LocationSummary* summary = 3672 LocationSummary* summary =
3673 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3673 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3674 summary->set_in(0, Location::RequiresFpuRegister()); 3674 summary->set_in(0, Location::RequiresFpuRegister());
3675 summary->set_in(1, Location::RequiresFpuRegister()); 3675 summary->set_in(1, Location::RequiresFpuRegister());
3676 summary->set_out(Location::SameAsFirstInput()); 3676 summary->set_out(0, Location::SameAsFirstInput());
3677 return summary; 3677 return summary;
3678 } 3678 }
3679 3679
3680 3680
3681 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3681 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3682 XmmRegister left = locs()->in(0).fpu_reg(); 3682 XmmRegister left = locs()->in(0).fpu_reg();
3683 XmmRegister right = locs()->in(1).fpu_reg(); 3683 XmmRegister right = locs()->in(1).fpu_reg();
3684 3684
3685 ASSERT(locs()->out().fpu_reg() == left); 3685 ASSERT(locs()->out(0).fpu_reg() == left);
3686 3686
3687 switch (op_kind()) { 3687 switch (op_kind()) {
3688 case MethodRecognizer::kFloat32x4Equal: 3688 case MethodRecognizer::kFloat32x4Equal:
3689 __ cmppseq(left, right); 3689 __ cmppseq(left, right);
3690 break; 3690 break;
3691 case MethodRecognizer::kFloat32x4NotEqual: 3691 case MethodRecognizer::kFloat32x4NotEqual:
3692 __ cmppsneq(left, right); 3692 __ cmppsneq(left, right);
3693 break; 3693 break;
3694 case MethodRecognizer::kFloat32x4GreaterThan: 3694 case MethodRecognizer::kFloat32x4GreaterThan:
3695 __ cmppsnle(left, right); 3695 __ cmppsnle(left, right);
(...skipping 13 matching lines...) Expand all
3709 } 3709 }
3710 3710
3711 3711
3712 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { 3712 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const {
3713 const intptr_t kNumInputs = 2; 3713 const intptr_t kNumInputs = 2;
3714 const intptr_t kNumTemps = 0; 3714 const intptr_t kNumTemps = 0;
3715 LocationSummary* summary = 3715 LocationSummary* summary =
3716 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3716 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3717 summary->set_in(0, Location::RequiresFpuRegister()); 3717 summary->set_in(0, Location::RequiresFpuRegister());
3718 summary->set_in(1, Location::RequiresFpuRegister()); 3718 summary->set_in(1, Location::RequiresFpuRegister());
3719 summary->set_out(Location::SameAsFirstInput()); 3719 summary->set_out(0, Location::SameAsFirstInput());
3720 return summary; 3720 return summary;
3721 } 3721 }
3722 3722
3723 3723
3724 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3724 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3725 XmmRegister left = locs()->in(0).fpu_reg(); 3725 XmmRegister left = locs()->in(0).fpu_reg();
3726 XmmRegister right = locs()->in(1).fpu_reg(); 3726 XmmRegister right = locs()->in(1).fpu_reg();
3727 3727
3728 ASSERT(locs()->out().fpu_reg() == left); 3728 ASSERT(locs()->out(0).fpu_reg() == left);
3729 3729
3730 switch (op_kind()) { 3730 switch (op_kind()) {
3731 case MethodRecognizer::kFloat32x4Min: 3731 case MethodRecognizer::kFloat32x4Min:
3732 __ minps(left, right); 3732 __ minps(left, right);
3733 break; 3733 break;
3734 case MethodRecognizer::kFloat32x4Max: 3734 case MethodRecognizer::kFloat32x4Max:
3735 __ maxps(left, right); 3735 __ maxps(left, right);
3736 break; 3736 break;
3737 default: UNREACHABLE(); 3737 default: UNREACHABLE();
3738 } 3738 }
3739 } 3739 }
3740 3740
3741 3741
3742 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { 3742 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const {
3743 const intptr_t kNumInputs = 2; 3743 const intptr_t kNumInputs = 2;
3744 const intptr_t kNumTemps = 0; 3744 const intptr_t kNumTemps = 0;
3745 LocationSummary* summary = 3745 LocationSummary* summary =
3746 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3746 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3747 summary->set_in(0, Location::RequiresFpuRegister()); 3747 summary->set_in(0, Location::RequiresFpuRegister());
3748 summary->set_in(1, Location::RequiresFpuRegister()); 3748 summary->set_in(1, Location::RequiresFpuRegister());
3749 summary->set_out(Location::SameAsFirstInput()); 3749 summary->set_out(0, Location::SameAsFirstInput());
3750 return summary; 3750 return summary;
3751 } 3751 }
3752 3752
3753 3753
3754 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3754 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3755 XmmRegister left = locs()->in(0).fpu_reg(); 3755 XmmRegister left = locs()->in(0).fpu_reg();
3756 XmmRegister right = locs()->in(1).fpu_reg(); 3756 XmmRegister right = locs()->in(1).fpu_reg();
3757 3757
3758 ASSERT(locs()->out().fpu_reg() == left); 3758 ASSERT(locs()->out(0).fpu_reg() == left);
3759 3759
3760 switch (op_kind()) { 3760 switch (op_kind()) {
3761 case MethodRecognizer::kFloat32x4Scale: 3761 case MethodRecognizer::kFloat32x4Scale:
3762 __ cvtsd2ss(left, left); 3762 __ cvtsd2ss(left, left);
3763 __ shufps(left, left, Immediate(0x00)); 3763 __ shufps(left, left, Immediate(0x00));
3764 __ mulps(left, right); 3764 __ mulps(left, right);
3765 break; 3765 break;
3766 default: UNREACHABLE(); 3766 default: UNREACHABLE();
3767 } 3767 }
3768 } 3768 }
3769 3769
3770 3770
3771 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { 3771 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const {
3772 const intptr_t kNumInputs = 1; 3772 const intptr_t kNumInputs = 1;
3773 const intptr_t kNumTemps = 0; 3773 const intptr_t kNumTemps = 0;
3774 LocationSummary* summary = 3774 LocationSummary* summary =
3775 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3775 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3776 summary->set_in(0, Location::RequiresFpuRegister()); 3776 summary->set_in(0, Location::RequiresFpuRegister());
3777 summary->set_out(Location::SameAsFirstInput()); 3777 summary->set_out(0, Location::SameAsFirstInput());
3778 return summary; 3778 return summary;
3779 } 3779 }
3780 3780
3781 3781
3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3783 XmmRegister left = locs()->in(0).fpu_reg(); 3783 XmmRegister left = locs()->in(0).fpu_reg();
3784 3784
3785 ASSERT(locs()->out().fpu_reg() == left); 3785 ASSERT(locs()->out(0).fpu_reg() == left);
3786 3786
3787 switch (op_kind()) { 3787 switch (op_kind()) {
3788 case MethodRecognizer::kFloat32x4Sqrt: 3788 case MethodRecognizer::kFloat32x4Sqrt:
3789 __ sqrtps(left); 3789 __ sqrtps(left);
3790 break; 3790 break;
3791 case MethodRecognizer::kFloat32x4Reciprocal: 3791 case MethodRecognizer::kFloat32x4Reciprocal:
3792 __ reciprocalps(left); 3792 __ reciprocalps(left);
3793 break; 3793 break;
3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3795 __ rsqrtps(left); 3795 __ rsqrtps(left);
3796 break; 3796 break;
3797 default: UNREACHABLE(); 3797 default: UNREACHABLE();
3798 } 3798 }
3799 } 3799 }
3800 3800
3801 3801
3802 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { 3802 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const {
3803 const intptr_t kNumInputs = 1; 3803 const intptr_t kNumInputs = 1;
3804 const intptr_t kNumTemps = 0; 3804 const intptr_t kNumTemps = 0;
3805 LocationSummary* summary = 3805 LocationSummary* summary =
3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3807 summary->set_in(0, Location::RequiresFpuRegister()); 3807 summary->set_in(0, Location::RequiresFpuRegister());
3808 summary->set_out(Location::SameAsFirstInput()); 3808 summary->set_out(0, Location::SameAsFirstInput());
3809 return summary; 3809 return summary;
3810 } 3810 }
3811 3811
3812 3812
3813 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3813 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3814 XmmRegister left = locs()->in(0).fpu_reg(); 3814 XmmRegister left = locs()->in(0).fpu_reg();
3815 3815
3816 ASSERT(locs()->out().fpu_reg() == left); 3816 ASSERT(locs()->out(0).fpu_reg() == left);
3817 switch (op_kind()) { 3817 switch (op_kind()) {
3818 case MethodRecognizer::kFloat32x4Negate: 3818 case MethodRecognizer::kFloat32x4Negate:
3819 __ negateps(left); 3819 __ negateps(left);
3820 break; 3820 break;
3821 case MethodRecognizer::kFloat32x4Absolute: 3821 case MethodRecognizer::kFloat32x4Absolute:
3822 __ absps(left); 3822 __ absps(left);
3823 break; 3823 break;
3824 default: UNREACHABLE(); 3824 default: UNREACHABLE();
3825 } 3825 }
3826 } 3826 }
3827 3827
3828 3828
3829 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { 3829 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const {
3830 const intptr_t kNumInputs = 3; 3830 const intptr_t kNumInputs = 3;
3831 const intptr_t kNumTemps = 0; 3831 const intptr_t kNumTemps = 0;
3832 LocationSummary* summary = 3832 LocationSummary* summary =
3833 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3833 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3834 summary->set_in(0, Location::RequiresFpuRegister()); 3834 summary->set_in(0, Location::RequiresFpuRegister());
3835 summary->set_in(1, Location::RequiresFpuRegister()); 3835 summary->set_in(1, Location::RequiresFpuRegister());
3836 summary->set_in(2, Location::RequiresFpuRegister()); 3836 summary->set_in(2, Location::RequiresFpuRegister());
3837 summary->set_out(Location::SameAsFirstInput()); 3837 summary->set_out(0, Location::SameAsFirstInput());
3838 return summary; 3838 return summary;
3839 } 3839 }
3840 3840
3841 3841
3842 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3842 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3843 XmmRegister left = locs()->in(0).fpu_reg(); 3843 XmmRegister left = locs()->in(0).fpu_reg();
3844 XmmRegister lower = locs()->in(1).fpu_reg(); 3844 XmmRegister lower = locs()->in(1).fpu_reg();
3845 XmmRegister upper = locs()->in(2).fpu_reg(); 3845 XmmRegister upper = locs()->in(2).fpu_reg();
3846 ASSERT(locs()->out().fpu_reg() == left); 3846 ASSERT(locs()->out(0).fpu_reg() == left);
3847 __ minps(left, upper); 3847 __ minps(left, upper);
3848 __ maxps(left, lower); 3848 __ maxps(left, lower);
3849 } 3849 }
3850 3850
3851 3851
3852 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { 3852 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const {
3853 const intptr_t kNumInputs = 2; 3853 const intptr_t kNumInputs = 2;
3854 const intptr_t kNumTemps = 0; 3854 const intptr_t kNumTemps = 0;
3855 LocationSummary* summary = 3855 LocationSummary* summary =
3856 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3856 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3857 summary->set_in(0, Location::RequiresFpuRegister()); 3857 summary->set_in(0, Location::RequiresFpuRegister());
3858 summary->set_in(1, Location::RequiresFpuRegister()); 3858 summary->set_in(1, Location::RequiresFpuRegister());
3859 summary->set_out(Location::SameAsFirstInput()); 3859 summary->set_out(0, Location::SameAsFirstInput());
3860 return summary; 3860 return summary;
3861 } 3861 }
3862 3862
3863 3863
3864 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3864 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3865 XmmRegister replacement = locs()->in(0).fpu_reg(); 3865 XmmRegister replacement = locs()->in(0).fpu_reg();
3866 XmmRegister value = locs()->in(1).fpu_reg(); 3866 XmmRegister value = locs()->in(1).fpu_reg();
3867 3867
3868 ASSERT(locs()->out().fpu_reg() == replacement); 3868 ASSERT(locs()->out(0).fpu_reg() == replacement);
3869 3869
3870 switch (op_kind()) { 3870 switch (op_kind()) {
3871 case MethodRecognizer::kFloat32x4WithX: 3871 case MethodRecognizer::kFloat32x4WithX:
3872 __ cvtsd2ss(replacement, replacement); 3872 __ cvtsd2ss(replacement, replacement);
3873 __ subl(ESP, Immediate(16)); 3873 __ subl(ESP, Immediate(16));
3874 // Move value to stack. 3874 // Move value to stack.
3875 __ movups(Address(ESP, 0), value); 3875 __ movups(Address(ESP, 0), value);
3876 // Write over X value. 3876 // Write over X value.
3877 __ movss(Address(ESP, 0), replacement); 3877 __ movss(Address(ESP, 0), replacement);
3878 // Move updated value into output register. 3878 // Move updated value into output register.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 } 3916 }
3917 } 3917 }
3918 3918
3919 3919
3920 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { 3920 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const {
3921 const intptr_t kNumInputs = 1; 3921 const intptr_t kNumInputs = 1;
3922 const intptr_t kNumTemps = 0; 3922 const intptr_t kNumTemps = 0;
3923 LocationSummary* summary = 3923 LocationSummary* summary =
3924 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3924 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3925 summary->set_in(0, Location::RequiresFpuRegister()); 3925 summary->set_in(0, Location::RequiresFpuRegister());
3926 summary->set_out(Location::SameAsFirstInput()); 3926 summary->set_out(0, Location::SameAsFirstInput());
3927 return summary; 3927 return summary;
3928 } 3928 }
3929 3929
3930 3930
3931 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3931 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3932 // NOP. 3932 // NOP.
3933 } 3933 }
3934 3934
3935 3935
3936 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { 3936 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const {
3937 const intptr_t kNumInputs = 1; 3937 const intptr_t kNumInputs = 1;
3938 const intptr_t kNumTemps = 0; 3938 const intptr_t kNumTemps = 0;
3939 LocationSummary* summary = 3939 LocationSummary* summary =
3940 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3940 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3941 summary->set_in(0, Location::RequiresFpuRegister()); 3941 summary->set_in(0, Location::RequiresFpuRegister());
3942 summary->set_out(Location::SameAsFirstInput()); 3942 summary->set_out(0, Location::SameAsFirstInput());
3943 return summary; 3943 return summary;
3944 } 3944 }
3945 3945
3946 3946
3947 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3947 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3948 XmmRegister value = locs()->in(0).fpu_reg(); 3948 XmmRegister value = locs()->in(0).fpu_reg();
3949 3949
3950 ASSERT(locs()->out().fpu_reg() == value); 3950 ASSERT(locs()->out(0).fpu_reg() == value);
3951 3951
3952 switch (op_kind()) { 3952 switch (op_kind()) {
3953 case MethodRecognizer::kFloat64x2GetX: 3953 case MethodRecognizer::kFloat64x2GetX:
3954 // nop. 3954 // nop.
3955 break; 3955 break;
3956 case MethodRecognizer::kFloat64x2GetY: 3956 case MethodRecognizer::kFloat64x2GetY:
3957 __ shufpd(value, value, Immediate(0x33)); 3957 __ shufpd(value, value, Immediate(0x33));
3958 break; 3958 break;
3959 default: UNREACHABLE(); 3959 default: UNREACHABLE();
3960 } 3960 }
3961 } 3961 }
3962 3962
3963 3963
3964 3964
3965 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { 3965 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const {
3966 const intptr_t kNumInputs = 0; 3966 const intptr_t kNumInputs = 0;
3967 const intptr_t kNumTemps = 0; 3967 const intptr_t kNumTemps = 0;
3968 LocationSummary* summary = 3968 LocationSummary* summary =
3969 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3969 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3970 summary->set_out(Location::RequiresFpuRegister()); 3970 summary->set_out(0, Location::RequiresFpuRegister());
3971 return summary; 3971 return summary;
3972 } 3972 }
3973 3973
3974 3974
3975 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3975 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3976 XmmRegister value = locs()->out().fpu_reg(); 3976 XmmRegister value = locs()->out(0).fpu_reg();
3977 __ xorpd(value, value); 3977 __ xorpd(value, value);
3978 } 3978 }
3979 3979
3980 3980
3981 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { 3981 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const {
3982 const intptr_t kNumInputs = 1; 3982 const intptr_t kNumInputs = 1;
3983 const intptr_t kNumTemps = 0; 3983 const intptr_t kNumTemps = 0;
3984 LocationSummary* summary = 3984 LocationSummary* summary =
3985 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3985 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3986 summary->set_in(0, Location::RequiresFpuRegister()); 3986 summary->set_in(0, Location::RequiresFpuRegister());
3987 summary->set_out(Location::SameAsFirstInput()); 3987 summary->set_out(0, Location::SameAsFirstInput());
3988 return summary; 3988 return summary;
3989 } 3989 }
3990 3990
3991 3991
3992 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3992 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3993 XmmRegister value = locs()->out().fpu_reg(); 3993 XmmRegister value = locs()->out(0).fpu_reg();
3994 __ shufpd(value, value, Immediate(0x0)); 3994 __ shufpd(value, value, Immediate(0x0));
3995 } 3995 }
3996 3996
3997 3997
3998 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( 3998 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary(
3999 bool opt) const { 3999 bool opt) const {
4000 const intptr_t kNumInputs = 2; 4000 const intptr_t kNumInputs = 2;
4001 const intptr_t kNumTemps = 0; 4001 const intptr_t kNumTemps = 0;
4002 LocationSummary* summary = 4002 LocationSummary* summary =
4003 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4003 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4004 summary->set_in(0, Location::RequiresFpuRegister()); 4004 summary->set_in(0, Location::RequiresFpuRegister());
4005 summary->set_in(1, Location::RequiresFpuRegister()); 4005 summary->set_in(1, Location::RequiresFpuRegister());
4006 summary->set_out(Location::SameAsFirstInput()); 4006 summary->set_out(0, Location::SameAsFirstInput());
4007 return summary; 4007 return summary;
4008 } 4008 }
4009 4009
4010 4010
4011 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4011 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4012 XmmRegister v0 = locs()->in(0).fpu_reg(); 4012 XmmRegister v0 = locs()->in(0).fpu_reg();
4013 XmmRegister v1 = locs()->in(1).fpu_reg(); 4013 XmmRegister v1 = locs()->in(1).fpu_reg();
4014 ASSERT(v0 == locs()->out().fpu_reg()); 4014 ASSERT(v0 == locs()->out(0).fpu_reg());
4015 __ subl(ESP, Immediate(16)); 4015 __ subl(ESP, Immediate(16));
4016 __ movsd(Address(ESP, 0), v0); 4016 __ movsd(Address(ESP, 0), v0);
4017 __ movsd(Address(ESP, 8), v1); 4017 __ movsd(Address(ESP, 8), v1);
4018 __ movups(v0, Address(ESP, 0)); 4018 __ movups(v0, Address(ESP, 0));
4019 __ addl(ESP, Immediate(16)); 4019 __ addl(ESP, Immediate(16));
4020 } 4020 }
4021 4021
4022 4022
4023 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( 4023 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary(
4024 bool opt) const { 4024 bool opt) const {
4025 const intptr_t kNumInputs = 1; 4025 const intptr_t kNumInputs = 1;
4026 const intptr_t kNumTemps = 0; 4026 const intptr_t kNumTemps = 0;
4027 LocationSummary* summary = 4027 LocationSummary* summary =
4028 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4028 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4029 summary->set_in(0, Location::RequiresFpuRegister()); 4029 summary->set_in(0, Location::RequiresFpuRegister());
4030 summary->set_out(Location::SameAsFirstInput()); 4030 summary->set_out(0, Location::SameAsFirstInput());
4031 return summary; 4031 return summary;
4032 } 4032 }
4033 4033
4034 4034
4035 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4035 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4036 XmmRegister value = locs()->out().fpu_reg(); 4036 XmmRegister value = locs()->out(0).fpu_reg();
4037 __ cvtpd2ps(value, value); 4037 __ cvtpd2ps(value, value);
4038 } 4038 }
4039 4039
4040 4040
4041 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( 4041 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary(
4042 bool opt) const { 4042 bool opt) const {
4043 const intptr_t kNumInputs = 1; 4043 const intptr_t kNumInputs = 1;
4044 const intptr_t kNumTemps = 0; 4044 const intptr_t kNumTemps = 0;
4045 LocationSummary* summary = 4045 LocationSummary* summary =
4046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4047 summary->set_in(0, Location::RequiresFpuRegister()); 4047 summary->set_in(0, Location::RequiresFpuRegister());
4048 summary->set_out(Location::SameAsFirstInput()); 4048 summary->set_out(0, Location::SameAsFirstInput());
4049 return summary; 4049 return summary;
4050 } 4050 }
4051 4051
4052 4052
4053 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4053 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4054 XmmRegister value = locs()->out().fpu_reg(); 4054 XmmRegister value = locs()->out(0).fpu_reg();
4055 __ cvtps2pd(value, value); 4055 __ cvtps2pd(value, value);
4056 } 4056 }
4057 4057
4058 4058
4059 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const { 4059 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const {
4060 const intptr_t kNumInputs = 1; 4060 const intptr_t kNumInputs = 1;
4061 const intptr_t kNumTemps = 0; 4061 const intptr_t kNumTemps = 0;
4062 LocationSummary* summary = 4062 LocationSummary* summary =
4063 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4063 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4064 summary->set_in(0, Location::RequiresFpuRegister()); 4064 summary->set_in(0, Location::RequiresFpuRegister());
4065 if (representation() == kTagged) { 4065 if (representation() == kTagged) {
4066 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); 4066 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask);
4067 summary->set_out(Location::RequiresRegister()); 4067 summary->set_out(0, Location::RequiresRegister());
4068 } else { 4068 } else {
4069 ASSERT(representation() == kUnboxedFloat64x2); 4069 ASSERT(representation() == kUnboxedFloat64x2);
4070 summary->set_out(Location::SameAsFirstInput()); 4070 summary->set_out(0, Location::SameAsFirstInput());
4071 } 4071 }
4072 return summary; 4072 return summary;
4073 } 4073 }
4074 4074
4075 4075
4076 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4076 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4077 XmmRegister left = locs()->in(0).fpu_reg(); 4077 XmmRegister left = locs()->in(0).fpu_reg();
4078 4078
4079 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) || 4079 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) ||
4080 (locs()->out().fpu_reg() == left)); 4080 (locs()->out(0).fpu_reg() == left));
4081 4081
4082 switch (op_kind()) { 4082 switch (op_kind()) {
4083 case MethodRecognizer::kFloat64x2Negate: 4083 case MethodRecognizer::kFloat64x2Negate:
4084 __ negatepd(left); 4084 __ negatepd(left);
4085 break; 4085 break;
4086 case MethodRecognizer::kFloat64x2Abs: 4086 case MethodRecognizer::kFloat64x2Abs:
4087 __ abspd(left); 4087 __ abspd(left);
4088 break; 4088 break;
4089 case MethodRecognizer::kFloat64x2Sqrt: 4089 case MethodRecognizer::kFloat64x2Sqrt:
4090 __ sqrtpd(left); 4090 __ sqrtpd(left);
4091 break; 4091 break;
4092 case MethodRecognizer::kFloat64x2GetSignMask: 4092 case MethodRecognizer::kFloat64x2GetSignMask:
4093 __ movmskpd(locs()->out().reg(), left); 4093 __ movmskpd(locs()->out(0).reg(), left);
4094 __ SmiTag(locs()->out().reg()); 4094 __ SmiTag(locs()->out(0).reg());
4095 break; 4095 break;
4096 default: UNREACHABLE(); 4096 default: UNREACHABLE();
4097 } 4097 }
4098 } 4098 }
4099 4099
4100 4100
4101 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const { 4101 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const {
4102 const intptr_t kNumInputs = 2; 4102 const intptr_t kNumInputs = 2;
4103 const intptr_t kNumTemps = 0; 4103 const intptr_t kNumTemps = 0;
4104 LocationSummary* summary = 4104 LocationSummary* summary =
4105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4106 summary->set_in(0, Location::RequiresFpuRegister()); 4106 summary->set_in(0, Location::RequiresFpuRegister());
4107 summary->set_in(1, Location::RequiresFpuRegister()); 4107 summary->set_in(1, Location::RequiresFpuRegister());
4108 summary->set_out(Location::SameAsFirstInput()); 4108 summary->set_out(0, Location::SameAsFirstInput());
4109 return summary; 4109 return summary;
4110 } 4110 }
4111 4111
4112 4112
4113 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4113 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4114 XmmRegister left = locs()->in(0).fpu_reg(); 4114 XmmRegister left = locs()->in(0).fpu_reg();
4115 XmmRegister right = locs()->in(1).fpu_reg(); 4115 XmmRegister right = locs()->in(1).fpu_reg();
4116 ASSERT((locs()->out().fpu_reg() == left)); 4116 ASSERT((locs()->out(0).fpu_reg() == left));
4117 4117
4118 switch (op_kind()) { 4118 switch (op_kind()) {
4119 case MethodRecognizer::kFloat64x2Scale: 4119 case MethodRecognizer::kFloat64x2Scale:
4120 __ shufpd(right, right, Immediate(0x00)); 4120 __ shufpd(right, right, Immediate(0x00));
4121 __ mulpd(left, right); 4121 __ mulpd(left, right);
4122 break; 4122 break;
4123 case MethodRecognizer::kFloat64x2WithX: 4123 case MethodRecognizer::kFloat64x2WithX:
4124 __ subl(ESP, Immediate(16)); 4124 __ subl(ESP, Immediate(16));
4125 // Move value to stack. 4125 // Move value to stack.
4126 __ movups(Address(ESP, 0), left); 4126 __ movups(Address(ESP, 0), left);
(...skipping 27 matching lines...) Expand all
4154 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( 4154 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
4155 bool opt) const { 4155 bool opt) const {
4156 const intptr_t kNumInputs = 4; 4156 const intptr_t kNumInputs = 4;
4157 const intptr_t kNumTemps = 0; 4157 const intptr_t kNumTemps = 0;
4158 LocationSummary* summary = 4158 LocationSummary* summary =
4159 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4159 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4160 summary->set_in(0, Location::RequiresRegister()); 4160 summary->set_in(0, Location::RequiresRegister());
4161 summary->set_in(1, Location::RequiresRegister()); 4161 summary->set_in(1, Location::RequiresRegister());
4162 summary->set_in(2, Location::RequiresRegister()); 4162 summary->set_in(2, Location::RequiresRegister());
4163 summary->set_in(3, Location::RequiresRegister()); 4163 summary->set_in(3, Location::RequiresRegister());
4164 summary->set_out(Location::RequiresFpuRegister()); 4164 summary->set_out(0, Location::RequiresFpuRegister());
4165 return summary; 4165 return summary;
4166 } 4166 }
4167 4167
4168 4168
4169 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4169 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4170 Register v0 = locs()->in(0).reg(); 4170 Register v0 = locs()->in(0).reg();
4171 Register v1 = locs()->in(1).reg(); 4171 Register v1 = locs()->in(1).reg();
4172 Register v2 = locs()->in(2).reg(); 4172 Register v2 = locs()->in(2).reg();
4173 Register v3 = locs()->in(3).reg(); 4173 Register v3 = locs()->in(3).reg();
4174 XmmRegister result = locs()->out().fpu_reg(); 4174 XmmRegister result = locs()->out(0).fpu_reg();
4175 Label x_false, x_done; 4175 Label x_false, x_done;
4176 Label y_false, y_done; 4176 Label y_false, y_done;
4177 Label z_false, z_done; 4177 Label z_false, z_done;
4178 Label w_false, w_done; 4178 Label w_false, w_done;
4179 __ subl(ESP, Immediate(16)); 4179 __ subl(ESP, Immediate(16));
4180 __ CompareObject(v0, Bool::True()); 4180 __ CompareObject(v0, Bool::True());
4181 __ j(NOT_EQUAL, &x_false); 4181 __ j(NOT_EQUAL, &x_false);
4182 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); 4182 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF));
4183 __ jmp(&x_done); 4183 __ jmp(&x_done);
4184 __ Bind(&x_false); 4184 __ Bind(&x_false);
(...skipping 28 matching lines...) Expand all
4213 __ addl(ESP, Immediate(16)); 4213 __ addl(ESP, Immediate(16));
4214 } 4214 }
4215 4215
4216 4216
4217 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { 4217 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const {
4218 const intptr_t kNumInputs = 1; 4218 const intptr_t kNumInputs = 1;
4219 const intptr_t kNumTemps = 0; 4219 const intptr_t kNumTemps = 0;
4220 LocationSummary* summary = 4220 LocationSummary* summary =
4221 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4221 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4222 summary->set_in(0, Location::RequiresFpuRegister()); 4222 summary->set_in(0, Location::RequiresFpuRegister());
4223 summary->set_out(Location::RequiresRegister()); 4223 summary->set_out(0, Location::RequiresRegister());
4224 return summary; 4224 return summary;
4225 } 4225 }
4226 4226
4227 4227
4228 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4228 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4229 XmmRegister value = locs()->in(0).fpu_reg(); 4229 XmmRegister value = locs()->in(0).fpu_reg();
4230 Register result = locs()->out().reg(); 4230 Register result = locs()->out(0).reg();
4231 Label done; 4231 Label done;
4232 Label non_zero; 4232 Label non_zero;
4233 __ subl(ESP, Immediate(16)); 4233 __ subl(ESP, Immediate(16));
4234 // Move value to stack. 4234 // Move value to stack.
4235 __ movups(Address(ESP, 0), value); 4235 __ movups(Address(ESP, 0), value);
4236 switch (op_kind()) { 4236 switch (op_kind()) {
4237 case MethodRecognizer::kInt32x4GetFlagX: 4237 case MethodRecognizer::kInt32x4GetFlagX:
4238 __ movl(result, Address(ESP, 0)); 4238 __ movl(result, Address(ESP, 0));
4239 break; 4239 break;
4240 case MethodRecognizer::kInt32x4GetFlagY: 4240 case MethodRecognizer::kInt32x4GetFlagY:
(...skipping 20 matching lines...) Expand all
4261 4261
4262 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { 4262 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const {
4263 const intptr_t kNumInputs = 3; 4263 const intptr_t kNumInputs = 3;
4264 const intptr_t kNumTemps = 1; 4264 const intptr_t kNumTemps = 1;
4265 LocationSummary* summary = 4265 LocationSummary* summary =
4266 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4266 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4267 summary->set_in(0, Location::RequiresFpuRegister()); 4267 summary->set_in(0, Location::RequiresFpuRegister());
4268 summary->set_in(1, Location::RequiresFpuRegister()); 4268 summary->set_in(1, Location::RequiresFpuRegister());
4269 summary->set_in(2, Location::RequiresFpuRegister()); 4269 summary->set_in(2, Location::RequiresFpuRegister());
4270 summary->set_temp(0, Location::RequiresFpuRegister()); 4270 summary->set_temp(0, Location::RequiresFpuRegister());
4271 summary->set_out(Location::SameAsFirstInput()); 4271 summary->set_out(0, Location::SameAsFirstInput());
4272 return summary; 4272 return summary;
4273 } 4273 }
4274 4274
4275 4275
4276 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4276 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4277 XmmRegister mask = locs()->in(0).fpu_reg(); 4277 XmmRegister mask = locs()->in(0).fpu_reg();
4278 XmmRegister trueValue = locs()->in(1).fpu_reg(); 4278 XmmRegister trueValue = locs()->in(1).fpu_reg();
4279 XmmRegister falseValue = locs()->in(2).fpu_reg(); 4279 XmmRegister falseValue = locs()->in(2).fpu_reg();
4280 XmmRegister out = locs()->out().fpu_reg(); 4280 XmmRegister out = locs()->out(0).fpu_reg();
4281 XmmRegister temp = locs()->temp(0).fpu_reg(); 4281 XmmRegister temp = locs()->temp(0).fpu_reg();
4282 ASSERT(out == mask); 4282 ASSERT(out == mask);
4283 // Copy mask. 4283 // Copy mask.
4284 __ movaps(temp, mask); 4284 __ movaps(temp, mask);
4285 // Invert it. 4285 // Invert it.
4286 __ notps(temp); 4286 __ notps(temp);
4287 // mask = mask & trueValue. 4287 // mask = mask & trueValue.
4288 __ andps(mask, trueValue); 4288 __ andps(mask, trueValue);
4289 // temp = temp & falseValue. 4289 // temp = temp & falseValue.
4290 __ andps(temp, falseValue); 4290 __ andps(temp, falseValue);
4291 // out = mask | temp. 4291 // out = mask | temp.
4292 __ orps(mask, temp); 4292 __ orps(mask, temp);
4293 } 4293 }
4294 4294
4295 4295
4296 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { 4296 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const {
4297 const intptr_t kNumInputs = 2; 4297 const intptr_t kNumInputs = 2;
4298 const intptr_t kNumTemps = 0; 4298 const intptr_t kNumTemps = 0;
4299 LocationSummary* summary = 4299 LocationSummary* summary =
4300 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4300 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4301 summary->set_in(0, Location::RequiresFpuRegister()); 4301 summary->set_in(0, Location::RequiresFpuRegister());
4302 summary->set_in(1, Location::RequiresRegister()); 4302 summary->set_in(1, Location::RequiresRegister());
4303 summary->set_out(Location::SameAsFirstInput()); 4303 summary->set_out(0, Location::SameAsFirstInput());
4304 return summary; 4304 return summary;
4305 } 4305 }
4306 4306
4307 4307
4308 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4308 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4309 XmmRegister mask = locs()->in(0).fpu_reg(); 4309 XmmRegister mask = locs()->in(0).fpu_reg();
4310 Register flag = locs()->in(1).reg(); 4310 Register flag = locs()->in(1).reg();
4311 ASSERT(mask == locs()->out().fpu_reg()); 4311 ASSERT(mask == locs()->out(0).fpu_reg());
4312 __ subl(ESP, Immediate(16)); 4312 __ subl(ESP, Immediate(16));
4313 // Copy mask to stack. 4313 // Copy mask to stack.
4314 __ movups(Address(ESP, 0), mask); 4314 __ movups(Address(ESP, 0), mask);
4315 Label falsePath, exitPath; 4315 Label falsePath, exitPath;
4316 __ CompareObject(flag, Bool::True()); 4316 __ CompareObject(flag, Bool::True());
4317 __ j(NOT_EQUAL, &falsePath); 4317 __ j(NOT_EQUAL, &falsePath);
4318 switch (op_kind()) { 4318 switch (op_kind()) {
4319 case MethodRecognizer::kInt32x4WithFlagX: 4319 case MethodRecognizer::kInt32x4WithFlagX:
4320 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); 4320 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF));
4321 __ jmp(&exitPath); 4321 __ jmp(&exitPath);
(...skipping 26 matching lines...) Expand all
4348 __ addl(ESP, Immediate(16)); 4348 __ addl(ESP, Immediate(16));
4349 } 4349 }
4350 4350
4351 4351
4352 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { 4352 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const {
4353 const intptr_t kNumInputs = 1; 4353 const intptr_t kNumInputs = 1;
4354 const intptr_t kNumTemps = 0; 4354 const intptr_t kNumTemps = 0;
4355 LocationSummary* summary = 4355 LocationSummary* summary =
4356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4357 summary->set_in(0, Location::RequiresFpuRegister()); 4357 summary->set_in(0, Location::RequiresFpuRegister());
4358 summary->set_out(Location::SameAsFirstInput()); 4358 summary->set_out(0, Location::SameAsFirstInput());
4359 return summary; 4359 return summary;
4360 } 4360 }
4361 4361
4362 4362
4363 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4363 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4364 // NOP. 4364 // NOP.
4365 } 4365 }
4366 4366
4367 4367
4368 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { 4368 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const {
4369 const intptr_t kNumInputs = 2; 4369 const intptr_t kNumInputs = 2;
4370 const intptr_t kNumTemps = 0; 4370 const intptr_t kNumTemps = 0;
4371 LocationSummary* summary = 4371 LocationSummary* summary =
4372 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4372 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4373 summary->set_in(0, Location::RequiresFpuRegister()); 4373 summary->set_in(0, Location::RequiresFpuRegister());
4374 summary->set_in(1, Location::RequiresFpuRegister()); 4374 summary->set_in(1, Location::RequiresFpuRegister());
4375 summary->set_out(Location::SameAsFirstInput()); 4375 summary->set_out(0, Location::SameAsFirstInput());
4376 return summary; 4376 return summary;
4377 } 4377 }
4378 4378
4379 4379
4380 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4380 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4381 XmmRegister left = locs()->in(0).fpu_reg(); 4381 XmmRegister left = locs()->in(0).fpu_reg();
4382 XmmRegister right = locs()->in(1).fpu_reg(); 4382 XmmRegister right = locs()->in(1).fpu_reg();
4383 ASSERT(left == locs()->out().fpu_reg()); 4383 ASSERT(left == locs()->out(0).fpu_reg());
4384 switch (op_kind()) { 4384 switch (op_kind()) {
4385 case Token::kBIT_AND: { 4385 case Token::kBIT_AND: {
4386 __ andps(left, right); 4386 __ andps(left, right);
4387 break; 4387 break;
4388 } 4388 }
4389 case Token::kBIT_OR: { 4389 case Token::kBIT_OR: {
4390 __ orps(left, right); 4390 __ orps(left, right);
4391 break; 4391 break;
4392 } 4392 }
4393 case Token::kBIT_XOR: { 4393 case Token::kBIT_XOR: {
(...skipping 15 matching lines...) Expand all
4409 if ((kind() == MethodRecognizer::kMathSin) || 4409 if ((kind() == MethodRecognizer::kMathSin) ||
4410 (kind() == MethodRecognizer::kMathCos)) { 4410 (kind() == MethodRecognizer::kMathCos)) {
4411 const intptr_t kNumInputs = 1; 4411 const intptr_t kNumInputs = 1;
4412 const intptr_t kNumTemps = 1; 4412 const intptr_t kNumTemps = 1;
4413 LocationSummary* summary = 4413 LocationSummary* summary =
4414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4415 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4415 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4416 // EDI is chosen because it is callee saved so we do not need to back it 4416 // EDI is chosen because it is callee saved so we do not need to back it
4417 // up before calling into the runtime. 4417 // up before calling into the runtime.
4418 summary->set_temp(0, Location::RegisterLocation(EDI)); 4418 summary->set_temp(0, Location::RegisterLocation(EDI));
4419 summary->set_out(Location::FpuRegisterLocation(XMM1)); 4419 summary->set_out(0, Location::FpuRegisterLocation(XMM1));
4420 return summary; 4420 return summary;
4421 } 4421 }
4422 ASSERT(kind() == MethodRecognizer::kMathSqrt); 4422 ASSERT(kind() == MethodRecognizer::kMathSqrt);
4423 const intptr_t kNumInputs = 1; 4423 const intptr_t kNumInputs = 1;
4424 const intptr_t kNumTemps = 0; 4424 const intptr_t kNumTemps = 0;
4425 LocationSummary* summary = 4425 LocationSummary* summary =
4426 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4426 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4427 summary->set_in(0, Location::RequiresFpuRegister()); 4427 summary->set_in(0, Location::RequiresFpuRegister());
4428 summary->set_out(Location::RequiresFpuRegister()); 4428 summary->set_out(0, Location::RequiresFpuRegister());
4429 return summary; 4429 return summary;
4430 } 4430 }
4431 4431
4432 4432
4433 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4433 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4434 if (kind() == MethodRecognizer::kMathSqrt) { 4434 if (kind() == MethodRecognizer::kMathSqrt) {
4435 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4435 __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4436 } else { 4436 } else {
4437 ASSERT((kind() == MethodRecognizer::kMathSin) || 4437 ASSERT((kind() == MethodRecognizer::kMathSin) ||
4438 (kind() == MethodRecognizer::kMathCos)); 4438 (kind() == MethodRecognizer::kMathCos));
4439 // Save ESP. 4439 // Save ESP.
4440 __ movl(locs()->temp(0).reg(), ESP); 4440 __ movl(locs()->temp(0).reg(), ESP);
4441 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 4441 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
4442 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 4442 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
4443 __ CallRuntime(TargetFunction(), InputCount()); 4443 __ CallRuntime(TargetFunction(), InputCount());
4444 __ fstpl(Address(ESP, 0)); 4444 __ fstpl(Address(ESP, 0));
4445 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); 4445 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4446 // Restore ESP. 4446 // Restore ESP.
4447 __ movl(ESP, locs()->temp(0).reg()); 4447 __ movl(ESP, locs()->temp(0).reg());
4448 } 4448 }
4449 } 4449 }
4450 4450
4451 4451
4452 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { 4452 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
4453 if (result_cid() == kDoubleCid) { 4453 if (result_cid() == kDoubleCid) {
4454 const intptr_t kNumInputs = 2; 4454 const intptr_t kNumInputs = 2;
4455 const intptr_t kNumTemps = 1; 4455 const intptr_t kNumTemps = 1;
4456 LocationSummary* summary = 4456 LocationSummary* summary =
4457 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4457 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4458 summary->set_in(0, Location::RequiresFpuRegister()); 4458 summary->set_in(0, Location::RequiresFpuRegister());
4459 summary->set_in(1, Location::RequiresFpuRegister()); 4459 summary->set_in(1, Location::RequiresFpuRegister());
4460 // Reuse the left register so that code can be made shorter. 4460 // Reuse the left register so that code can be made shorter.
4461 summary->set_out(Location::SameAsFirstInput()); 4461 summary->set_out(0, Location::SameAsFirstInput());
4462 summary->set_temp(0, Location::RequiresRegister()); 4462 summary->set_temp(0, Location::RequiresRegister());
4463 return summary; 4463 return summary;
4464 } 4464 }
4465 4465
4466 ASSERT(result_cid() == kSmiCid); 4466 ASSERT(result_cid() == kSmiCid);
4467 const intptr_t kNumInputs = 2; 4467 const intptr_t kNumInputs = 2;
4468 const intptr_t kNumTemps = 0; 4468 const intptr_t kNumTemps = 0;
4469 LocationSummary* summary = 4469 LocationSummary* summary =
4470 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4470 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4471 summary->set_in(0, Location::RequiresRegister()); 4471 summary->set_in(0, Location::RequiresRegister());
4472 summary->set_in(1, Location::RequiresRegister()); 4472 summary->set_in(1, Location::RequiresRegister());
4473 // Reuse the left register so that code can be made shorter. 4473 // Reuse the left register so that code can be made shorter.
4474 summary->set_out(Location::SameAsFirstInput()); 4474 summary->set_out(0, Location::SameAsFirstInput());
4475 return summary; 4475 return summary;
4476 } 4476 }
4477 4477
4478 4478
4479 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4479 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4480 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 4480 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
4481 (op_kind() == MethodRecognizer::kMathMax)); 4481 (op_kind() == MethodRecognizer::kMathMax));
4482 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); 4482 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
4483 if (result_cid() == kDoubleCid) { 4483 if (result_cid() == kDoubleCid) {
4484 Label done, returns_nan, are_equal; 4484 Label done, returns_nan, are_equal;
4485 XmmRegister left = locs()->in(0).fpu_reg(); 4485 XmmRegister left = locs()->in(0).fpu_reg();
4486 XmmRegister right = locs()->in(1).fpu_reg(); 4486 XmmRegister right = locs()->in(1).fpu_reg();
4487 XmmRegister result = locs()->out().fpu_reg(); 4487 XmmRegister result = locs()->out(0).fpu_reg();
4488 Register temp = locs()->temp(0).reg(); 4488 Register temp = locs()->temp(0).reg();
4489 __ comisd(left, right); 4489 __ comisd(left, right);
4490 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); 4490 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump);
4491 __ j(EQUAL, &are_equal, Assembler::kNearJump); 4491 __ j(EQUAL, &are_equal, Assembler::kNearJump);
4492 const Condition double_condition = 4492 const Condition double_condition =
4493 is_min ? TokenKindToDoubleCondition(Token::kLT) 4493 is_min ? TokenKindToDoubleCondition(Token::kLT)
4494 : TokenKindToDoubleCondition(Token::kGT); 4494 : TokenKindToDoubleCondition(Token::kGT);
4495 ASSERT(left == result); 4495 ASSERT(left == result);
4496 __ j(double_condition, &done, Assembler::kNearJump); 4496 __ j(double_condition, &done, Assembler::kNearJump);
4497 __ movsd(result, right); 4497 __ movsd(result, right);
(...skipping 21 matching lines...) Expand all
4519 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left. 4519 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left.
4520 } 4520 }
4521 __ movsd(result, right); 4521 __ movsd(result, right);
4522 __ Bind(&done); 4522 __ Bind(&done);
4523 return; 4523 return;
4524 } 4524 }
4525 4525
4526 ASSERT(result_cid() == kSmiCid); 4526 ASSERT(result_cid() == kSmiCid);
4527 Register left = locs()->in(0).reg(); 4527 Register left = locs()->in(0).reg();
4528 Register right = locs()->in(1).reg(); 4528 Register right = locs()->in(1).reg();
4529 Register result = locs()->out().reg(); 4529 Register result = locs()->out(0).reg();
4530 __ cmpl(left, right); 4530 __ cmpl(left, right);
4531 ASSERT(result == left); 4531 ASSERT(result == left);
4532 if (is_min) { 4532 if (is_min) {
4533 __ cmovgel(result, right); 4533 __ cmovgel(result, right);
4534 } else { 4534 } else {
4535 __ cmovlessl(result, right); 4535 __ cmovlessl(result, right);
4536 } 4536 }
4537 } 4537 }
4538 4538
4539 4539
4540 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 4540 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
4541 const intptr_t kNumInputs = 1; 4541 const intptr_t kNumInputs = 1;
4542 return LocationSummary::Make(kNumInputs, 4542 return LocationSummary::Make(kNumInputs,
4543 Location::SameAsFirstInput(), 4543 Location::SameAsFirstInput(),
4544 LocationSummary::kNoCall); 4544 LocationSummary::kNoCall);
4545 } 4545 }
4546 4546
4547 4547
4548 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4548 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4549 Register value = locs()->in(0).reg(); 4549 Register value = locs()->in(0).reg();
4550 ASSERT(value == locs()->out().reg()); 4550 ASSERT(value == locs()->out(0).reg());
4551 switch (op_kind()) { 4551 switch (op_kind()) {
4552 case Token::kNEGATE: { 4552 case Token::kNEGATE: {
4553 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4553 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4554 kDeoptUnaryOp); 4554 kDeoptUnaryOp);
4555 __ negl(value); 4555 __ negl(value);
4556 __ j(OVERFLOW, deopt); 4556 __ j(OVERFLOW, deopt);
4557 break; 4557 break;
4558 } 4558 }
4559 case Token::kBIT_NOT: 4559 case Token::kBIT_NOT:
4560 __ notl(value); 4560 __ notl(value);
4561 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 4561 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
4562 break; 4562 break;
4563 default: 4563 default:
4564 UNREACHABLE(); 4564 UNREACHABLE();
4565 } 4565 }
4566 } 4566 }
4567 4567
4568 4568
4569 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 4569 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
4570 const intptr_t kNumInputs = 1; 4570 const intptr_t kNumInputs = 1;
4571 const intptr_t kNumTemps = 0; 4571 const intptr_t kNumTemps = 0;
4572 LocationSummary* summary = 4572 LocationSummary* summary =
4573 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4573 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4574 summary->set_in(0, Location::RequiresFpuRegister()); 4574 summary->set_in(0, Location::RequiresFpuRegister());
4575 summary->set_out(Location::SameAsFirstInput()); 4575 summary->set_out(0, Location::SameAsFirstInput());
4576 return summary; 4576 return summary;
4577 } 4577 }
4578 4578
4579 4579
4580 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4580 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4581 XmmRegister value = locs()->in(0).fpu_reg(); 4581 XmmRegister value = locs()->in(0).fpu_reg();
4582 ASSERT(locs()->out().fpu_reg() == value); 4582 ASSERT(locs()->out(0).fpu_reg() == value);
4583 __ DoubleNegate(value); 4583 __ DoubleNegate(value);
4584 } 4584 }
4585 4585
4586 4586
4587 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { 4587 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
4588 const intptr_t kNumInputs = 1; 4588 const intptr_t kNumInputs = 1;
4589 const intptr_t kNumTemps = 0; 4589 const intptr_t kNumTemps = 0;
4590 LocationSummary* result = 4590 LocationSummary* result =
4591 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4591 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4592 result->set_in(0, Location::WritableRegister()); 4592 result->set_in(0, Location::WritableRegister());
4593 result->set_out(Location::RequiresFpuRegister()); 4593 result->set_out(0, Location::RequiresFpuRegister());
4594 return result; 4594 return result;
4595 } 4595 }
4596 4596
4597 4597
4598 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4598 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4599 Register value = locs()->in(0).reg(); 4599 Register value = locs()->in(0).reg();
4600 FpuRegister result = locs()->out().fpu_reg(); 4600 FpuRegister result = locs()->out(0).fpu_reg();
4601 __ SmiUntag(value); 4601 __ SmiUntag(value);
4602 __ cvtsi2sd(result, value); 4602 __ cvtsi2sd(result, value);
4603 } 4603 }
4604 4604
4605 4605
4606 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { 4606 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
4607 const intptr_t kNumInputs = 1; 4607 const intptr_t kNumInputs = 1;
4608 const intptr_t kNumTemps = 0; 4608 const intptr_t kNumTemps = 0;
4609 LocationSummary* result = 4609 LocationSummary* result =
4610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4610 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4611 result->set_in(0, Location::RegisterLocation(ECX)); 4611 result->set_in(0, Location::RegisterLocation(ECX));
4612 result->set_out(Location::RegisterLocation(EAX)); 4612 result->set_out(0, Location::RegisterLocation(EAX));
4613 return result; 4613 return result;
4614 } 4614 }
4615 4615
4616 4616
4617 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4617 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4618 Register result = locs()->out().reg(); 4618 Register result = locs()->out(0).reg();
4619 Register value_obj = locs()->in(0).reg(); 4619 Register value_obj = locs()->in(0).reg();
4620 XmmRegister value_double = XMM0; 4620 XmmRegister value_double = XMM0;
4621 ASSERT(result == EAX); 4621 ASSERT(result == EAX);
4622 ASSERT(result != value_obj); 4622 ASSERT(result != value_obj);
4623 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset())); 4623 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset()));
4624 __ cvttsd2si(result, value_double); 4624 __ cvttsd2si(result, value_double);
4625 // Overflow is signalled with minint. 4625 // Overflow is signalled with minint.
4626 Label do_call, done; 4626 Label do_call, done;
4627 // Check for overflow and that it fits into Smi. 4627 // Check for overflow and that it fits into Smi.
4628 __ cmpl(result, Immediate(0xC0000000)); 4628 __ cmpl(result, Immediate(0xC0000000));
(...skipping 17 matching lines...) Expand all
4646 __ Bind(&done); 4646 __ Bind(&done);
4647 } 4647 }
4648 4648
4649 4649
4650 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { 4650 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
4651 const intptr_t kNumInputs = 1; 4651 const intptr_t kNumInputs = 1;
4652 const intptr_t kNumTemps = 0; 4652 const intptr_t kNumTemps = 0;
4653 LocationSummary* result = new LocationSummary( 4653 LocationSummary* result = new LocationSummary(
4654 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4654 kNumInputs, kNumTemps, LocationSummary::kNoCall);
4655 result->set_in(0, Location::RequiresFpuRegister()); 4655 result->set_in(0, Location::RequiresFpuRegister());
4656 result->set_out(Location::RequiresRegister()); 4656 result->set_out(0, Location::RequiresRegister());
4657 return result; 4657 return result;
4658 } 4658 }
4659 4659
4660 4660
4661 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4661 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4662 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 4662 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
4663 Register result = locs()->out().reg(); 4663 Register result = locs()->out(0).reg();
4664 XmmRegister value = locs()->in(0).fpu_reg(); 4664 XmmRegister value = locs()->in(0).fpu_reg();
4665 __ cvttsd2si(result, value); 4665 __ cvttsd2si(result, value);
4666 // Check for overflow and that it fits into Smi. 4666 // Check for overflow and that it fits into Smi.
4667 __ cmpl(result, Immediate(0xC0000000)); 4667 __ cmpl(result, Immediate(0xC0000000));
4668 __ j(NEGATIVE, deopt); 4668 __ j(NEGATIVE, deopt);
4669 __ SmiTag(result); 4669 __ SmiTag(result);
4670 } 4670 }
4671 4671
4672 4672
4673 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { 4673 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
4674 const intptr_t kNumInputs = 1; 4674 const intptr_t kNumInputs = 1;
4675 const intptr_t kNumTemps = 0; 4675 const intptr_t kNumTemps = 0;
4676 LocationSummary* result = 4676 LocationSummary* result =
4677 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4677 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4678 result->set_in(0, Location::RequiresFpuRegister()); 4678 result->set_in(0, Location::RequiresFpuRegister());
4679 result->set_out(Location::RequiresFpuRegister()); 4679 result->set_out(0, Location::RequiresFpuRegister());
4680 return result; 4680 return result;
4681 } 4681 }
4682 4682
4683 4683
4684 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4684 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4685 XmmRegister value = locs()->in(0).fpu_reg(); 4685 XmmRegister value = locs()->in(0).fpu_reg();
4686 XmmRegister result = locs()->out().fpu_reg(); 4686 XmmRegister result = locs()->out(0).fpu_reg();
4687 switch (recognized_kind()) { 4687 switch (recognized_kind()) {
4688 case MethodRecognizer::kDoubleTruncate: 4688 case MethodRecognizer::kDoubleTruncate:
4689 __ roundsd(result, value, Assembler::kRoundToZero); 4689 __ roundsd(result, value, Assembler::kRoundToZero);
4690 break; 4690 break;
4691 case MethodRecognizer::kDoubleFloor: 4691 case MethodRecognizer::kDoubleFloor:
4692 __ roundsd(result, value, Assembler::kRoundDown); 4692 __ roundsd(result, value, Assembler::kRoundDown);
4693 break; 4693 break;
4694 case MethodRecognizer::kDoubleCeil: 4694 case MethodRecognizer::kDoubleCeil:
4695 __ roundsd(result, value, Assembler::kRoundUp); 4695 __ roundsd(result, value, Assembler::kRoundUp);
4696 break; 4696 break;
4697 default: 4697 default:
4698 UNREACHABLE(); 4698 UNREACHABLE();
4699 } 4699 }
4700 } 4700 }
4701 4701
4702 4702
4703 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { 4703 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
4704 const intptr_t kNumInputs = 1; 4704 const intptr_t kNumInputs = 1;
4705 const intptr_t kNumTemps = 0; 4705 const intptr_t kNumTemps = 0;
4706 LocationSummary* result = 4706 LocationSummary* result =
4707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4708 result->set_in(0, Location::RequiresFpuRegister()); 4708 result->set_in(0, Location::RequiresFpuRegister());
4709 result->set_out(Location::SameAsFirstInput()); 4709 result->set_out(0, Location::SameAsFirstInput());
4710 return result; 4710 return result;
4711 } 4711 }
4712 4712
4713 4713
4714 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4714 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4715 __ cvtsd2ss(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4715 __ cvtsd2ss(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4716 } 4716 }
4717 4717
4718 4718
4719 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { 4719 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
4720 const intptr_t kNumInputs = 1; 4720 const intptr_t kNumInputs = 1;
4721 const intptr_t kNumTemps = 0; 4721 const intptr_t kNumTemps = 0;
4722 LocationSummary* result = 4722 LocationSummary* result =
4723 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4723 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4724 result->set_in(0, Location::RequiresFpuRegister()); 4724 result->set_in(0, Location::RequiresFpuRegister());
4725 result->set_out(Location::SameAsFirstInput()); 4725 result->set_out(0, Location::SameAsFirstInput());
4726 return result; 4726 return result;
4727 } 4727 }
4728 4728
4729 4729
4730 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4730 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4731 __ cvtss2sd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4731 __ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4732 } 4732 }
4733 4733
4734 4734
4735 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 4735 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
4736 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4736 ASSERT((InputCount() == 1) || (InputCount() == 2));
4737 const intptr_t kNumTemps = 1; 4737 const intptr_t kNumTemps = 1;
4738 LocationSummary* result = 4738 LocationSummary* result =
4739 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4739 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4740 // EDI is chosen because it is callee saved so we do not need to back it 4740 // EDI is chosen because it is callee saved so we do not need to back it
4741 // up before calling into the runtime. 4741 // up before calling into the runtime.
4742 result->set_temp(0, Location::RegisterLocation(EDI)); 4742 result->set_temp(0, Location::RegisterLocation(EDI));
4743 result->set_in(0, Location::FpuRegisterLocation(XMM1)); 4743 result->set_in(0, Location::FpuRegisterLocation(XMM1));
4744 if (InputCount() == 2) { 4744 if (InputCount() == 2) {
4745 result->set_in(1, Location::FpuRegisterLocation(XMM2)); 4745 result->set_in(1, Location::FpuRegisterLocation(XMM2));
4746 } 4746 }
4747 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4747 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4748 // Temp index 1. 4748 // Temp index 1.
4749 result->AddTemp(Location::RegisterLocation(EAX)); 4749 result->AddTemp(Location::RegisterLocation(EAX));
4750 // Temp index 2. 4750 // Temp index 2.
4751 result->AddTemp(Location::FpuRegisterLocation(XMM4)); 4751 result->AddTemp(Location::FpuRegisterLocation(XMM4));
4752 } 4752 }
4753 result->set_out(Location::FpuRegisterLocation(XMM3)); 4753 result->set_out(0, Location::FpuRegisterLocation(XMM3));
4754 return result; 4754 return result;
4755 } 4755 }
4756 4756
4757 4757
4758 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4758 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4759 // Save ESP. 4759 // Save ESP.
4760 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP); 4760 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP);
4761 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 4761 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
4762 for (intptr_t i = 0; i < InputCount(); i++) { 4762 for (intptr_t i = 0; i < InputCount(); i++) {
4763 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg()); 4763 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
4764 } 4764 }
4765 Label do_call, skip_call; 4765 Label do_call, skip_call;
4766 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4766 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4767 // Pseudo code: 4767 // Pseudo code:
4768 // if (exponent == 0.0) return 1.0; 4768 // if (exponent == 0.0) return 1.0;
4769 // if (base == 1.0) return 1.0; 4769 // if (base == 1.0) return 1.0;
4770 // if (base.isNaN || exponent.isNaN) { 4770 // if (base.isNaN || exponent.isNaN) {
4771 // return double.NAN; 4771 // return double.NAN;
4772 // } 4772 // }
4773 XmmRegister base = locs()->in(0).fpu_reg(); 4773 XmmRegister base = locs()->in(0).fpu_reg();
4774 XmmRegister exp = locs()->in(1).fpu_reg(); 4774 XmmRegister exp = locs()->in(1).fpu_reg();
4775 XmmRegister result = locs()->out().fpu_reg(); 4775 XmmRegister result = locs()->out(0).fpu_reg();
4776 Register temp = locs()->temp(kObjectTempIndex).reg(); 4776 Register temp = locs()->temp(kObjectTempIndex).reg();
4777 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg(); 4777 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg();
4778 4778
4779 Label check_base_is_one; 4779 Label check_base_is_one;
4780 // Check if exponent is 0.0 -> return 1.0; 4780 // Check if exponent is 0.0 -> return 1.0;
4781 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); 4781 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
4782 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4782 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4783 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); 4783 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
4784 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4784 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4785 // 'result' contains 1.0. 4785 // 'result' contains 1.0.
(...skipping 10 matching lines...) Expand all
4796 4796
4797 __ Bind(&base_is_nan); 4797 __ Bind(&base_is_nan);
4798 // Returns NaN. 4798 // Returns NaN.
4799 __ movsd(result, base); 4799 __ movsd(result, base);
4800 __ jmp(&skip_call, Assembler::kNearJump); 4800 __ jmp(&skip_call, Assembler::kNearJump);
4801 // exp is Nan case is handled correctly in the C-library. 4801 // exp is Nan case is handled correctly in the C-library.
4802 } 4802 }
4803 __ Bind(&do_call); 4803 __ Bind(&do_call);
4804 __ CallRuntime(TargetFunction(), InputCount()); 4804 __ CallRuntime(TargetFunction(), InputCount());
4805 __ fstpl(Address(ESP, 0)); 4805 __ fstpl(Address(ESP, 0));
4806 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); 4806 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4807 __ Bind(&skip_call); 4807 __ Bind(&skip_call);
4808 // Restore ESP. 4808 // Restore ESP.
4809 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg()); 4809 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg());
4810 } 4810 }
4811 4811
4812 4812
4813 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4813 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4814 if (kind() == MergedMathInstr::kTruncDivMod) { 4814 if (kind() == MergedMathInstr::kTruncDivMod) {
4815 const intptr_t kNumInputs = 2; 4815 const intptr_t kNumInputs = 2;
4816 const intptr_t kNumTemps = 1; 4816 const intptr_t kNumTemps = 1;
4817 LocationSummary* summary = 4817 LocationSummary* summary =
4818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4819 // Both inputs must be writable because they will be untagged. 4819 // Both inputs must be writable because they will be untagged.
4820 summary->set_in(0, Location::RegisterLocation(EAX)); 4820 summary->set_in(0, Location::RegisterLocation(EAX));
4821 summary->set_in(1, Location::WritableRegister()); 4821 summary->set_in(1, Location::WritableRegister());
4822 summary->set_out(Location::RequiresRegister()); 4822 summary->set_out(0, Location::RequiresRegister());
4823 // Will be used for sign extension and division. 4823 // Will be used for sign extension and division.
4824 summary->set_temp(0, Location::RegisterLocation(EDX)); 4824 summary->set_temp(0, Location::RegisterLocation(EDX));
4825 return summary; 4825 return summary;
4826 } 4826 }
4827 if (kind() == MergedMathInstr::kSinCos) { 4827 if (kind() == MergedMathInstr::kSinCos) {
4828 const intptr_t kNumInputs = 1; 4828 const intptr_t kNumInputs = 1;
4829 const intptr_t kNumTemps = 0; 4829 const intptr_t kNumTemps = 0;
4830 LocationSummary* summary = 4830 LocationSummary* summary =
4831 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4831 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4832 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4832 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4833 summary->set_out(Location::RegisterLocation(EAX)); 4833 summary->set_out(0, Location::RegisterLocation(EAX));
4834 return summary; 4834 return summary;
4835 } 4835 }
4836 UNIMPLEMENTED(); 4836 UNIMPLEMENTED();
4837 return NULL; 4837 return NULL;
4838 } 4838 }
4839 4839
4840 4840
4841 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4841 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
4842 4842
4843 extern const RuntimeEntry kSinCosRuntimeEntry( 4843 extern const RuntimeEntry kSinCosRuntimeEntry(
4844 "libc_sincos", reinterpret_cast<RuntimeFunction>( 4844 "libc_sincos", reinterpret_cast<RuntimeFunction>(
4845 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 4845 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
4846 4846
4847 4847
4848 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4848 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4849 Label* deopt = NULL; 4849 Label* deopt = NULL;
4850 if (CanDeoptimize()) { 4850 if (CanDeoptimize()) {
4851 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4851 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4852 } 4852 }
4853 4853
4854 if (kind() == MergedMathInstr::kTruncDivMod) { 4854 if (kind() == MergedMathInstr::kTruncDivMod) {
4855 Register left = locs()->in(0).reg(); 4855 Register left = locs()->in(0).reg();
4856 Register right = locs()->in(1).reg(); 4856 Register right = locs()->in(1).reg();
4857 Register result = locs()->out().reg(); 4857 Register result = locs()->out(0).reg();
4858 Range* right_range = InputAt(1)->definition()->range(); 4858 Range* right_range = InputAt(1)->definition()->range();
4859 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4859 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4860 // Handle divide by zero in runtime. 4860 // Handle divide by zero in runtime.
4861 __ testl(right, right); 4861 __ testl(right, right);
4862 __ j(ZERO, deopt); 4862 __ j(ZERO, deopt);
4863 } 4863 }
4864 ASSERT(left == EAX); 4864 ASSERT(left == EAX);
4865 ASSERT((right != EDX) && (right != EAX)); 4865 ASSERT((right != EDX) && (right != EAX));
4866 ASSERT(locs()->temp(0).reg() == EDX); 4866 ASSERT(locs()->temp(0).reg() == EDX);
4867 ASSERT((result != EDX) && (result != EAX)); 4867 ASSERT((result != EDX) && (result != EAX));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4930 __ pushl(EAX); 4930 __ pushl(EAX);
4931 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 4931 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
4932 __ fldl(Address(ESP, 0)); 4932 __ fldl(Address(ESP, 0));
4933 __ fsincos(); 4933 __ fsincos();
4934 __ fstpl(Address(ESP, 0)); 4934 __ fstpl(Address(ESP, 0));
4935 __ movsd(XMM1, Address(ESP, 0)); 4935 __ movsd(XMM1, Address(ESP, 0));
4936 __ fstpl(Address(ESP, 0)); 4936 __ fstpl(Address(ESP, 0));
4937 __ movsd(XMM0, Address(ESP, 0)); 4937 __ movsd(XMM0, Address(ESP, 0));
4938 __ addl(ESP, Immediate(2 * kWordSize)); 4938 __ addl(ESP, Immediate(2 * kWordSize));
4939 4939
4940 Register result = locs()->out().reg(); 4940 Register result = locs()->out(0).reg();
4941 const TypedData& res_array = TypedData::ZoneHandle( 4941 const TypedData& res_array = TypedData::ZoneHandle(
4942 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); 4942 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4943 __ LoadObject(result, res_array); 4943 __ LoadObject(result, res_array);
4944 const intptr_t index_scale = 4944 const intptr_t index_scale =
4945 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid); 4945 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4946 Address sin_address( 4946 Address sin_address(
4947 FlowGraphCompiler::ElementAddressForIntIndex( 4947 FlowGraphCompiler::ElementAddressForIntIndex(
4948 kTypedDataFloat64ArrayCid, index_scale, result, 4948 kTypedDataFloat64ArrayCid, index_scale, result,
4949 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin))); 4949 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin)));
4950 Address cos_address( 4950 Address cos_address(
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5000 deopt, 5000 deopt,
5001 deopt_id(), 5001 deopt_id(),
5002 instance_call()->token_pos(), 5002 instance_call()->token_pos(),
5003 locs()); 5003 locs());
5004 } 5004 }
5005 5005
5006 5006
5007 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { 5007 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
5008 comparison()->InitializeLocationSummary(opt); 5008 comparison()->InitializeLocationSummary(opt);
5009 // Branches don't produce a result. 5009 // Branches don't produce a result.
5010 comparison()->locs()->set_out(Location::NoLocation()); 5010 comparison()->locs()->set_out(0, Location::NoLocation());
5011 return comparison()->locs(); 5011 return comparison()->locs();
5012 } 5012 }
5013 5013
5014 5014
5015 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5015 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5016 comparison()->EmitBranchCode(compiler, this); 5016 comparison()->EmitBranchCode(compiler, this);
5017 } 5017 }
5018 5018
5019 5019
5020 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { 5020 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
5171 const intptr_t value_cid = value()->Type()->ToCid(); 5171 const intptr_t value_cid = value()->Type()->ToCid();
5172 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); 5172 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid));
5173 const bool needs_writable_input = (value_cid == kSmiCid); 5173 const bool needs_writable_input = (value_cid == kSmiCid);
5174 const intptr_t kNumTemps = needs_temp ? 1 : 0; 5174 const intptr_t kNumTemps = needs_temp ? 1 : 0;
5175 LocationSummary* summary = 5175 LocationSummary* summary =
5176 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5176 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5177 summary->set_in(0, needs_writable_input 5177 summary->set_in(0, needs_writable_input
5178 ? Location::WritableRegister() 5178 ? Location::WritableRegister()
5179 : Location::RequiresRegister()); 5179 : Location::RequiresRegister());
5180 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); 5180 if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
5181 summary->set_out(Location::RequiresFpuRegister()); 5181 summary->set_out(0, Location::RequiresFpuRegister());
5182 return summary; 5182 return summary;
5183 } 5183 }
5184 5184
5185 5185
5186 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5186 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5187 const intptr_t value_cid = value()->Type()->ToCid(); 5187 const intptr_t value_cid = value()->Type()->ToCid();
5188 const Register value = locs()->in(0).reg(); 5188 const Register value = locs()->in(0).reg();
5189 const XmmRegister result = locs()->out().fpu_reg(); 5189 const XmmRegister result = locs()->out(0).fpu_reg();
5190 5190
5191 if (value_cid == kMintCid) { 5191 if (value_cid == kMintCid) {
5192 __ movsd(result, FieldAddress(value, Mint::value_offset())); 5192 __ movsd(result, FieldAddress(value, Mint::value_offset()));
5193 } else if (value_cid == kSmiCid) { 5193 } else if (value_cid == kSmiCid) {
5194 __ SmiUntag(value); // Untag input before conversion. 5194 __ SmiUntag(value); // Untag input before conversion.
5195 __ movd(result, value); 5195 __ movd(result, value);
5196 __ pmovsxdq(result, result); 5196 __ pmovsxdq(result, result);
5197 } else { 5197 } else {
5198 Register temp = locs()->temp(0).reg(); 5198 Register temp = locs()->temp(0).reg();
5199 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); 5199 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger);
(...skipping 18 matching lines...) Expand all
5218 const intptr_t kNumInputs = 1; 5218 const intptr_t kNumInputs = 1;
5219 const intptr_t kNumTemps = 2; 5219 const intptr_t kNumTemps = 2;
5220 LocationSummary* summary = 5220 LocationSummary* summary =
5221 new LocationSummary(kNumInputs, 5221 new LocationSummary(kNumInputs,
5222 kNumTemps, 5222 kNumTemps,
5223 LocationSummary::kCallOnSlowPath); 5223 LocationSummary::kCallOnSlowPath);
5224 summary->set_in(0, Location::RequiresFpuRegister()); 5224 summary->set_in(0, Location::RequiresFpuRegister());
5225 summary->set_temp(0, Location::RegisterLocation(EAX)); 5225 summary->set_temp(0, Location::RegisterLocation(EAX));
5226 summary->set_temp(1, Location::RegisterLocation(EDX)); 5226 summary->set_temp(1, Location::RegisterLocation(EDX));
5227 // TODO(fschneider): Save one temp by using result register as a temp. 5227 // TODO(fschneider): Save one temp by using result register as a temp.
5228 summary->set_out(Location::RequiresRegister()); 5228 summary->set_out(0, Location::RequiresRegister());
5229 return summary; 5229 return summary;
5230 } 5230 }
5231 5231
5232 5232
5233 class BoxIntegerSlowPath : public SlowPathCode { 5233 class BoxIntegerSlowPath : public SlowPathCode {
5234 public: 5234 public:
5235 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5235 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction)
5236 : instruction_(instruction) { } 5236 : instruction_(instruction) { }
5237 5237
5238 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5238 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5239 __ Comment("BoxIntegerSlowPath"); 5239 __ Comment("BoxIntegerSlowPath");
5240 __ Bind(entry_label()); 5240 __ Bind(entry_label());
5241 const Class& mint_class = 5241 const Class& mint_class =
5242 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); 5242 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class());
5243 const Code& stub = 5243 const Code& stub =
5244 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); 5244 Code::Handle(StubCode::GetAllocationStubForClass(mint_class));
5245 const ExternalLabel label(mint_class.ToCString(), stub.EntryPoint()); 5245 const ExternalLabel label(mint_class.ToCString(), stub.EntryPoint());
5246 5246
5247 LocationSummary* locs = instruction_->locs(); 5247 LocationSummary* locs = instruction_->locs();
5248 locs->live_registers()->Remove(locs->out()); 5248 locs->live_registers()->Remove(locs->out(0));
5249 5249
5250 compiler->SaveLiveRegisters(locs); 5250 compiler->SaveLiveRegisters(locs);
5251 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5251 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5252 &label, 5252 &label,
5253 PcDescriptors::kOther, 5253 PcDescriptors::kOther,
5254 locs); 5254 locs);
5255 __ MoveRegister(locs->out().reg(), EAX); 5255 __ MoveRegister(locs->out(0).reg(), EAX);
5256 compiler->RestoreLiveRegisters(locs); 5256 compiler->RestoreLiveRegisters(locs);
5257 5257
5258 __ jmp(exit_label()); 5258 __ jmp(exit_label());
5259 } 5259 }
5260 5260
5261 private: 5261 private:
5262 BoxIntegerInstr* instruction_; 5262 BoxIntegerInstr* instruction_;
5263 }; 5263 };
5264 5264
5265 5265
5266 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5266 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5267 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); 5267 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
5268 compiler->AddSlowPathCode(slow_path); 5268 compiler->AddSlowPathCode(slow_path);
5269 5269
5270 Register out_reg = locs()->out().reg(); 5270 Register out_reg = locs()->out(0).reg();
5271 XmmRegister value = locs()->in(0).fpu_reg(); 5271 XmmRegister value = locs()->in(0).fpu_reg();
5272 5272
5273 // Unboxed operations produce smis or mint-sized values. 5273 // Unboxed operations produce smis or mint-sized values.
5274 // Check if value fits into a smi. 5274 // Check if value fits into a smi.
5275 Label not_smi, done; 5275 Label not_smi, done;
5276 __ pextrd(EDX, value, Immediate(1)); // Upper half. 5276 __ pextrd(EDX, value, Immediate(1)); // Upper half.
5277 __ pextrd(EAX, value, Immediate(0)); // Lower half. 5277 __ pextrd(EAX, value, Immediate(0)); // Lower half.
5278 // 1. Compute (x + -kMinSmi) which has to be in the range 5278 // 1. Compute (x + -kMinSmi) which has to be in the range
5279 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. 5279 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi.
5280 __ addl(EAX, Immediate(0x40000000)); 5280 __ addl(EAX, Immediate(0x40000000));
(...skipping 30 matching lines...) Expand all
5311 case Token::kBIT_XOR: { 5311 case Token::kBIT_XOR: {
5312 const intptr_t kNumTemps = 5312 const intptr_t kNumTemps =
5313 FLAG_throw_on_javascript_int_overflow ? 1 : 0; 5313 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
5314 LocationSummary* summary = 5314 LocationSummary* summary =
5315 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5315 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5316 summary->set_in(0, Location::RequiresFpuRegister()); 5316 summary->set_in(0, Location::RequiresFpuRegister());
5317 summary->set_in(1, Location::RequiresFpuRegister()); 5317 summary->set_in(1, Location::RequiresFpuRegister());
5318 if (FLAG_throw_on_javascript_int_overflow) { 5318 if (FLAG_throw_on_javascript_int_overflow) {
5319 summary->set_temp(0, Location::RequiresRegister()); 5319 summary->set_temp(0, Location::RequiresRegister());
5320 } 5320 }
5321 summary->set_out(Location::SameAsFirstInput()); 5321 summary->set_out(0, Location::SameAsFirstInput());
5322 return summary; 5322 return summary;
5323 } 5323 }
5324 case Token::kADD: 5324 case Token::kADD:
5325 case Token::kSUB: { 5325 case Token::kSUB: {
5326 const intptr_t kNumTemps = 2; 5326 const intptr_t kNumTemps = 2;
5327 LocationSummary* summary = 5327 LocationSummary* summary =
5328 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5328 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5329 summary->set_in(0, Location::RequiresFpuRegister()); 5329 summary->set_in(0, Location::RequiresFpuRegister());
5330 summary->set_in(1, Location::RequiresFpuRegister()); 5330 summary->set_in(1, Location::RequiresFpuRegister());
5331 summary->set_temp(0, Location::RequiresRegister()); 5331 summary->set_temp(0, Location::RequiresRegister());
5332 summary->set_temp(1, Location::RequiresRegister()); 5332 summary->set_temp(1, Location::RequiresRegister());
5333 summary->set_out(Location::SameAsFirstInput()); 5333 summary->set_out(0, Location::SameAsFirstInput());
5334 return summary; 5334 return summary;
5335 } 5335 }
5336 default: 5336 default:
5337 UNREACHABLE(); 5337 UNREACHABLE();
5338 return NULL; 5338 return NULL;
5339 } 5339 }
5340 } 5340 }
5341 5341
5342 5342
5343 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5343 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5344 XmmRegister left = locs()->in(0).fpu_reg(); 5344 XmmRegister left = locs()->in(0).fpu_reg();
5345 XmmRegister right = locs()->in(1).fpu_reg(); 5345 XmmRegister right = locs()->in(1).fpu_reg();
5346 5346
5347 ASSERT(locs()->out().fpu_reg() == left); 5347 ASSERT(locs()->out(0).fpu_reg() == left);
5348 5348
5349 Label* deopt = NULL; 5349 Label* deopt = NULL;
5350 if (FLAG_throw_on_javascript_int_overflow) { 5350 if (FLAG_throw_on_javascript_int_overflow) {
5351 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); 5351 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
5352 } 5352 }
5353 switch (op_kind()) { 5353 switch (op_kind()) {
5354 case Token::kBIT_AND: __ andpd(left, right); break; 5354 case Token::kBIT_AND: __ andpd(left, right); break;
5355 case Token::kBIT_OR: __ orpd(left, right); break; 5355 case Token::kBIT_OR: __ orpd(left, right); break;
5356 case Token::kBIT_XOR: __ xorpd(left, right); break; 5356 case Token::kBIT_XOR: __ xorpd(left, right); break;
5357 case Token::kADD: 5357 case Token::kADD:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5397 const intptr_t kNumInputs = 2; 5397 const intptr_t kNumInputs = 2;
5398 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; 5398 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
5399 LocationSummary* summary = 5399 LocationSummary* summary =
5400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5400 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5401 summary->set_in(0, Location::RequiresFpuRegister()); 5401 summary->set_in(0, Location::RequiresFpuRegister());
5402 summary->set_in(1, Location::RegisterLocation(ECX)); 5402 summary->set_in(1, Location::RegisterLocation(ECX));
5403 summary->set_temp(0, Location::RequiresRegister()); 5403 summary->set_temp(0, Location::RequiresRegister());
5404 if (op_kind() == Token::kSHL) { 5404 if (op_kind() == Token::kSHL) {
5405 summary->set_temp(1, Location::RequiresRegister()); 5405 summary->set_temp(1, Location::RequiresRegister());
5406 } 5406 }
5407 summary->set_out(Location::SameAsFirstInput()); 5407 summary->set_out(0, Location::SameAsFirstInput());
5408 return summary; 5408 return summary;
5409 } 5409 }
5410 5410
5411 5411
5412 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5412 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5413 XmmRegister left = locs()->in(0).fpu_reg(); 5413 XmmRegister left = locs()->in(0).fpu_reg();
5414 ASSERT(locs()->in(1).reg() == ECX); 5414 ASSERT(locs()->in(1).reg() == ECX);
5415 ASSERT(locs()->out().fpu_reg() == left); 5415 ASSERT(locs()->out(0).fpu_reg() == left);
5416 5416
5417 Label* deopt = compiler->AddDeoptStub(deopt_id(), 5417 Label* deopt = compiler->AddDeoptStub(deopt_id(),
5418 kDeoptShiftMintOp); 5418 kDeoptShiftMintOp);
5419 Label done; 5419 Label done;
5420 __ testl(ECX, ECX); 5420 __ testl(ECX, ECX);
5421 __ j(ZERO, &done); // Shift by 0 is a nop. 5421 __ j(ZERO, &done); // Shift by 0 is a nop.
5422 __ subl(ESP, Immediate(2 * kWordSize)); 5422 __ subl(ESP, Immediate(2 * kWordSize));
5423 __ movq(Address(ESP, 0), left); 5423 __ movq(Address(ESP, 0), left);
5424 // Deoptimize if shift count is > 31. 5424 // Deoptimize if shift count is > 31.
5425 // sarl operation masks the count to 5 bits and 5425 // sarl operation masks the count to 5 bits and
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5467 } 5467 }
5468 5468
5469 5469
5470 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { 5470 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const {
5471 const intptr_t kNumInputs = 1; 5471 const intptr_t kNumInputs = 1;
5472 const intptr_t kNumTemps = 5472 const intptr_t kNumTemps =
5473 FLAG_throw_on_javascript_int_overflow ? 1 : 0; 5473 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
5474 LocationSummary* summary = 5474 LocationSummary* summary =
5475 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5475 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5476 summary->set_in(0, Location::RequiresFpuRegister()); 5476 summary->set_in(0, Location::RequiresFpuRegister());
5477 summary->set_out(Location::SameAsFirstInput()); 5477 summary->set_out(0, Location::SameAsFirstInput());
5478 if (FLAG_throw_on_javascript_int_overflow) { 5478 if (FLAG_throw_on_javascript_int_overflow) {
5479 summary->set_temp(0, Location::RequiresRegister()); 5479 summary->set_temp(0, Location::RequiresRegister());
5480 } 5480 }
5481 return summary; 5481 return summary;
5482 } 5482 }
5483 5483
5484 5484
5485 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5485 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5486 ASSERT(op_kind() == Token::kBIT_NOT); 5486 ASSERT(op_kind() == Token::kBIT_NOT);
5487 XmmRegister value = locs()->in(0).fpu_reg(); 5487 XmmRegister value = locs()->in(0).fpu_reg();
5488 ASSERT(value == locs()->out().fpu_reg()); 5488 ASSERT(value == locs()->out(0).fpu_reg());
5489 Label* deopt = NULL; 5489 Label* deopt = NULL;
5490 if (FLAG_throw_on_javascript_int_overflow) { 5490 if (FLAG_throw_on_javascript_int_overflow) {
5491 deopt = compiler->AddDeoptStub(deopt_id(), 5491 deopt = compiler->AddDeoptStub(deopt_id(),
5492 kDeoptUnaryMintOp); 5492 kDeoptUnaryMintOp);
5493 } 5493 }
5494 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 5494 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
5495 __ pxor(value, XMM0); 5495 __ pxor(value, XMM0);
5496 if (FLAG_throw_on_javascript_int_overflow) { 5496 if (FLAG_throw_on_javascript_int_overflow) {
5497 Register tmp = locs()->temp(0).reg(); 5497 Register tmp = locs()->temp(0).reg();
5498 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); 5498 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 5586
5587 5587
5588 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { 5588 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
5589 return LocationSummary::Make(0, 5589 return LocationSummary::Make(0,
5590 Location::RequiresRegister(), 5590 Location::RequiresRegister(),
5591 LocationSummary::kNoCall); 5591 LocationSummary::kNoCall);
5592 } 5592 }
5593 5593
5594 5594
5595 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5595 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5596 __ MoveRegister(locs()->out().reg(), CTX); 5596 __ MoveRegister(locs()->out(0).reg(), CTX);
5597 } 5597 }
5598 5598
5599 5599
5600 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { 5600 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
5601 const intptr_t kNumInputs = 2; 5601 const intptr_t kNumInputs = 2;
5602 const intptr_t kNumTemps = 0; 5602 const intptr_t kNumTemps = 0;
5603 if (needs_number_check()) { 5603 if (needs_number_check()) {
5604 LocationSummary* locs = 5604 LocationSummary* locs =
5605 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5605 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
5606 locs->set_in(0, Location::RegisterLocation(EAX)); 5606 locs->set_in(0, Location::RegisterLocation(EAX));
5607 locs->set_in(1, Location::RegisterLocation(ECX)); 5607 locs->set_in(1, Location::RegisterLocation(ECX));
5608 locs->set_out(Location::RegisterLocation(EAX)); 5608 locs->set_out(0, Location::RegisterLocation(EAX));
5609 return locs; 5609 return locs;
5610 } 5610 }
5611 LocationSummary* locs = 5611 LocationSummary* locs =
5612 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5612 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5613 locs->set_in(0, Location::RegisterOrConstant(left())); 5613 locs->set_in(0, Location::RegisterOrConstant(left()));
5614 // Only one of the inputs can be a constant. Choose register if the first one 5614 // Only one of the inputs can be a constant. Choose register if the first one
5615 // is a constant. 5615 // is a constant.
5616 locs->set_in(1, locs->in(0).IsConstant() 5616 locs->set_in(1, locs->in(0).IsConstant()
5617 ? Location::RequiresRegister() 5617 ? Location::RequiresRegister()
5618 : Location::RegisterOrConstant(right())); 5618 : Location::RegisterOrConstant(right()));
5619 locs->set_out(Location::RequiresRegister()); 5619 locs->set_out(0, Location::RequiresRegister());
5620 return locs; 5620 return locs;
5621 } 5621 }
5622 5622
5623 5623
5624 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 5624 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
5625 BranchLabels labels) { 5625 BranchLabels labels) {
5626 Location left = locs()->in(0); 5626 Location left = locs()->in(0);
5627 Location right = locs()->in(1); 5627 Location right = locs()->in(1);
5628 ASSERT(!left.IsConstant() || !right.IsConstant()); 5628 ASSERT(!left.IsConstant() || !right.IsConstant());
5629 if (left.IsConstant()) { 5629 if (left.IsConstant()) {
(...skipping 18 matching lines...) Expand all
5648 5648
5649 5649
5650 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5650 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5651 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5651 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5652 5652
5653 Label is_true, is_false; 5653 Label is_true, is_false;
5654 BranchLabels labels = { &is_true, &is_false, &is_false }; 5654 BranchLabels labels = { &is_true, &is_false, &is_false };
5655 Condition true_condition = EmitComparisonCode(compiler, labels); 5655 Condition true_condition = EmitComparisonCode(compiler, labels);
5656 EmitBranchOnCondition(compiler, true_condition, labels); 5656 EmitBranchOnCondition(compiler, true_condition, labels);
5657 5657
5658 Register result = locs()->out().reg(); 5658 Register result = locs()->out(0).reg();
5659 Label done; 5659 Label done;
5660 __ Bind(&is_false); 5660 __ Bind(&is_false);
5661 __ LoadObject(result, Bool::False()); 5661 __ LoadObject(result, Bool::False());
5662 __ jmp(&done, Assembler::kNearJump); 5662 __ jmp(&done, Assembler::kNearJump);
5663 __ Bind(&is_true); 5663 __ Bind(&is_true);
5664 __ LoadObject(result, Bool::True()); 5664 __ LoadObject(result, Bool::True());
5665 __ Bind(&done); 5665 __ Bind(&done);
5666 } 5666 }
5667 5667
5668 5668
(...skipping 10 matching lines...) Expand all
5679 // Detect pattern when one value is zero and another is a power of 2. 5679 // Detect pattern when one value is zero and another is a power of 2.
5680 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 5680 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
5681 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 5681 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
5682 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 5682 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
5683 } 5683 }
5684 5684
5685 5685
5686 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { 5686 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
5687 comparison()->InitializeLocationSummary(opt); 5687 comparison()->InitializeLocationSummary(opt);
5688 // TODO(vegorov): support byte register constraints in the register allocator. 5688 // TODO(vegorov): support byte register constraints in the register allocator.
5689 comparison()->locs()->set_out(Location::RegisterLocation(EDX)); 5689 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX));
5690 return comparison()->locs(); 5690 return comparison()->locs();
5691 } 5691 }
5692 5692
5693 5693
5694 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5694 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5695 ASSERT(locs()->out().reg() == EDX); 5695 ASSERT(locs()->out(0).reg() == EDX);
5696 5696
5697 // Clear upper part of the out register. We are going to use setcc on it 5697 // Clear upper part of the out register. We are going to use setcc on it
5698 // which is a byte move. 5698 // which is a byte move.
5699 __ xorl(EDX, EDX); 5699 __ xorl(EDX, EDX);
5700 5700
5701 // Emit comparison code. This must not overwrite the result register. 5701 // Emit comparison code. This must not overwrite the result register.
5702 BranchLabels labels = { NULL, NULL, NULL }; 5702 BranchLabels labels = { NULL, NULL, NULL };
5703 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 5703 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
5704 5704
5705 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 5705 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5738 } 5738 }
5739 } 5739 }
5740 } 5740 }
5741 5741
5742 5742
5743 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { 5743 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
5744 const intptr_t kNumInputs = 0; 5744 const intptr_t kNumInputs = 0;
5745 const intptr_t kNumTemps = 1; 5745 const intptr_t kNumTemps = 1;
5746 LocationSummary* result = 5746 LocationSummary* result =
5747 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5747 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
5748 result->set_out(Location::RegisterLocation(EAX)); 5748 result->set_out(0, Location::RegisterLocation(EAX));
5749 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 5749 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
5750 return result; 5750 return result;
5751 } 5751 }
5752 5752
5753 5753
5754 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5754 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5755 // The arguments to the stub include the closure, as does the arguments 5755 // The arguments to the stub include the closure, as does the arguments
5756 // descriptor. 5756 // descriptor.
5757 Register temp_reg = locs()->temp(0).reg(); 5757 Register temp_reg = locs()->temp(0).reg();
5758 int argument_count = ArgumentCount(); 5758 int argument_count = ArgumentCount();
(...skipping 13 matching lines...) Expand all
5772 5772
5773 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { 5773 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
5774 return LocationSummary::Make(1, 5774 return LocationSummary::Make(1,
5775 Location::RequiresRegister(), 5775 Location::RequiresRegister(),
5776 LocationSummary::kNoCall); 5776 LocationSummary::kNoCall);
5777 } 5777 }
5778 5778
5779 5779
5780 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5780 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5781 Register value = locs()->in(0).reg(); 5781 Register value = locs()->in(0).reg();
5782 Register result = locs()->out().reg(); 5782 Register result = locs()->out(0).reg();
5783 5783
5784 Label done; 5784 Label done;
5785 __ LoadObject(result, Bool::True()); 5785 __ LoadObject(result, Bool::True());
5786 __ CompareRegisters(result, value); 5786 __ CompareRegisters(result, value);
5787 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 5787 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
5788 __ LoadObject(result, Bool::False()); 5788 __ LoadObject(result, Bool::False());
5789 __ Bind(&done); 5789 __ Bind(&done);
5790 } 5790 }
5791 5791
5792 5792
(...skipping 10 matching lines...) Expand all
5803 PcDescriptors::kOther, 5803 PcDescriptors::kOther,
5804 locs()); 5804 locs());
5805 __ Drop(ArgumentCount()); // Discard arguments. 5805 __ Drop(ArgumentCount()); // Discard arguments.
5806 } 5806 }
5807 5807
5808 } // namespace dart 5808 } // namespace dart
5809 5809
5810 #undef __ 5810 #undef __
5811 5811
5812 #endif // defined TARGET_ARCH_IA32 5812 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698